Skip to content

🐛 fix(docs): 文档里那份提示词照抄就崩 —— 与常量对齐,并用测试钉死 - #38

Merged
MrXnneHang merged 1 commit into
mainfrom
docs/sync-diary-prompt
Aug 2, 2026
Merged

🐛 fix(docs): 文档里那份提示词照抄就崩 —— 与常量对齐,并用测试钉死#38
MrXnneHang merged 1 commit into
mainfrom
docs/sync-diary-prompt

Conversation

@xnne-bot

Copy link
Copy Markdown
Collaborator

动机

#36 里我报过一条:docs/guide/writing-diary.md 声称它印的那份提示词「ships as wikimem.DIARY_PROMPT」,但两者已经漂移(933 vs 1049 字符)。你说另开 PR 修,就是这个。

真去查的时候,发现问题比"文案不一致"严重得多:文档给出的提示词,按文档自己说的用法用,会直接崩。

memorize(diary, turn, llm=..., prompt=<文档里印的那份>)
EN 文档块    -> KeyError: 'conversation_turn'
zh 文档块    -> KeyError: 'conversation_turn'
DIARY_PROMPT -> 正常

两页都写着「replace it wholesale with prompt=」/「用 prompt= 整份替换」—— 照做就是这个结果。读者复制一份提示词,拿到的不是日记,是一个崩溃。

两个各自独立的原因

任何一个单独存在都足以让它崩:

# 原因 报错
1 {conversation_turn} 占位符memorize().format(character=...),从不填这个键 —— 那一轮对话是作为独立的 user 消息发出的,根本不进提示词 KeyError: 'conversation_turn'
2 JSON 示例花括号没转义[ { "content": … } ].format 当成字段名 KeyError: ' "content"'

常量里第 2 点写的是 [{{"content": …}}] —— 转义过。文档块把它"美化"成了单花括号,正好踩中。

逐条验证过(不是推断):

>>> "The turn:\n{conversation_turn}".format(character="Elaina")
KeyError: 'conversation_turn'
>>> '[ { "content": "x" } ]'.format(character="Elaina")
KeyError: ' "content"'
>>> '[{{"content": "…"}}]'.format(character="E")      # 常量的写法
'[{"content": "…"}]'

解决方案

EN 页:文档块换成 DIARY_PROMPT 逐字原文,并补上说明 —— {character}{{ }}.format 的产物(后者渲染成 { }),以及对话本身不会被插进提示词(system 一条、user 一条)。原来那段错误的 The turn: / {conversation_turn} 由此自然消失。

zh 页:那份中文提示词是改写版,不是随包那份的副本 —— 所以保留中文(它本来就是给你 prompt= 传进去用的),但修掉同样的两个毛病,并把规则与常量逐条对齐(6 条对 6 条)。措辞也改准了:以前写「英文版同一份文案随包提供」,实际是「随包的是它的英文原版」。

测试:4 条新增,全部验证过会在修复前失败

我把修复前的两份文档 checkout 回来跑了一遍:

FAILED test_english_guide_prints_the_shipped_prompt_verbatim
FAILED test_documented_prompts_survive_being_used_as_documented[guide/writing-diary.md-...]
FAILED test_documented_prompts_survive_being_used_as_documented[zh/guide/writing-diary.md-...]
FAILED test_zh_prompt_carries_the_same_rules_as_the_shipped_one
4 failed

换回修好的文档 → 4 passed

三条的分工:

  1. EN 文档块与 DIARY_PROMPT 逐字节相等。 散文管不住这种漂移,只有等号能 —— 这次漂移正是因为 📝 docs: 《Writing the diary》—— 指导 LLM 写日记的参考提示词 #22 写文档、✨ feat: memorize —— 注入式 LLM 一次调用写日记(ADR-0005 模式 A) #24 改常量,中间没有任何东西拦着。
  2. 两份文档提示词都真的执行一遍 memorize(prompt=...)这条才是能抓到本次这类 bug 的那条 —— 等号只能保证 EN 那份不漂,保证不了它"能用";zh 那份是改写版没法比等号,但照样能跑。
  3. zh 与常量的规则条数一致 —— 翻译版能做到的最强约束,防的是「往一边加了条规则、另一边忘了」。

(提取文档块时会去掉恰好一个结尾换行:fenced block 不可能没有它,那是 markdown 的标点,不是提示词的一部分。helper 的 docstring 里写了。)

验证

uv run pytest -q                   → 220 passed, 1 skipped   (原 216 + 4)
uvx ruff format --check .          → 27 files already formatted
uvx ruff check .                   → All checks passed!
uv run ty check --error-on-warning → All checks passed!
docs: pnpm i --frozen-lockfile && pnpm build → build complete in 5.13s

类型

  • 🐛 fix: 修复 bug
  • ✅ test: 测试用例添加及修改

起因是 #36 里报的「文档块与 `DIARY_PROMPT` 常量不一致(933 vs 1049 字符)」。
真去查的时候发现不止是文案漂移 —— **文档给出的提示词,按文档自己说的用法用,
会直接抛异常**:

    memorize(diary, turn, llm=..., prompt=<文档里那份>)
    EN 文档块 -> KeyError: 'conversation_turn'
    zh 文档块 -> KeyError: 'conversation_turn'
    DIARY_PROMPT -> 正常

两个各自独立的原因,任何一个单独出现都足以让它崩:

1. **`{conversation_turn}` 占位符** —— `memorize()` 只 `.format(character=...)`,
   从不填这个键;那一轮对话是作为**独立的 user 消息**发出的,根本不进提示词。
2. **JSON 示例的花括号没转义** —— `[ { "content": … } ]` 被 `.format` 当成字段
   名,报 `KeyError: ' "content"'`。常量里写的是 `[{{"content": …}}]`。

也就是说:照文档复制一份提示词的读者,拿到的不是日记,是一个崩溃。

改动:

- **EN 页**:文档块换成 `DIARY_PROMPT` 逐字原文,并补两段说明 —— `{character}`
  与 `{{ }}` 是 `.format` 的产物(后者渲染成 `{ }`),以及**对话本身不会被插进
  提示词**(system + user 两条消息)。原来那段错误的 `The turn:` 由此消失。
- **zh 页**:那份中文提示词是**改写版**、不是随包那份的副本,所以保留中文,但
  修掉同样的两个毛病,并把规则与常量逐条对齐(6 条对 6 条)。措辞也改准:以前
  说"英文版同一份文案随包提供",实际是"随包的是它的英文原版"。

测试(4 条新增,均已验证会在修复前的文档上失败):

- EN 文档块与 `DIARY_PROMPT` **逐字节相等**。散文管不住这种漂移,只有等号能。
- **两份文档提示词都真的跑一遍** `memorize(prompt=...)` —— 这条才是能抓到本次
  这类 bug 的那条。zh 是改写版没法比等号,但照样能执行。
- zh 与常量的规则条数一致(翻译版能做到的最强约束)。

四道闸门:220 passed, 1 skipped(原 216 + 4);文档站 `pnpm build` 通过。

Co-Authored-By: Claude <noreply@anthropic.com>

@xnne-bot xnne-bot left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The documented prompts now format safely and the test coverage pins everything down robustly to prevent future drift. This looks great and is ready to merge.

@MrXnneHang
MrXnneHang merged commit 3a630da into main Aug 2, 2026
6 checks passed
@MrXnneHang
MrXnneHang deleted the docs/sync-diary-prompt branch August 2, 2026 13:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants