---
title: "AI 编程困扰逆向索引（症状 → 该怎么做）"
author: garplab
publisher: TypingTube
license: CC BY 4.0
license_url: https://creativecommons.org/licenses/by/4.0/
license_scope: 本文档的全部正文（不含此 frontmatter）
language: zh
canonical: https://typing-tube.net/articles/zh/lookup
---

# AI 编程困扰逆向索引（症状 → 该怎么做）

这是一张按症状而非标题查找的表格。点击“详情”可以前往写有实测数据和具体做法的文章章节。

本表以 Claude Code（Anthropic 的编程智能体）为前提。hook、CLAUDE.md、subagent、auto memory 都是它的功能名称。

| 正在发生什么 | 该怎么做 | Claude Code 功能 | 详情 |
|---|---|---|---|
| AI 每次运行测试，数万行输出都会涌入上下文 | 把测试执行统一收进一个包装脚本（wrapper script），把全部输出写入日志文件，只把失败的摘要返回给 AI。 | `context window` / `wrapper script` / `fixed-prefix count line ([observed])` | [読まない技術 第1回：テスト結果を読まない技術](https://typing-tube.net/articles/cd93e0c5cac832#cd93e0c5cac832-4eea2df8) |
| AI 保存的知识笔记越多，之后每次会话要读的量就越大 | 在写入 memory 前触发的 PreToolUse hook 中让它读取一份检查清单，指示文件（CLAUDE.md）里只留“写之前先读”这一行。 | `MEMORY.md` / `loaded at session start` / `context rot` | [読まない技術 第2回：メモリを読まない技術](https://typing-tube.net/articles/384477896fec22#384477896fec22-4eea2df8) |
| 测试都通过了，但不知道它们是否真的在保护什么 | 把 mutation testing（故意破坏代码看测试是否会失败的方法）的方针写成一份文档，请求检查测试时让 AI 读取它。 | `mutation testing` / `positive control` / `vacuous truth` | [読まない技術 第3回：単体テストを読まない技術](https://typing-tube.net/articles/e4ad91d2fd6c67#e4ad91d2fd6c67-4eea2df8) |
| 注册好的 skill，AI 有时用、有时不用 | 命令仍以普通脚本的形式保留，用 PreToolUse hook 拦截错误的调用方式，并引导它去读应该读的文档。 | `PreToolUse hook (Bash matcher)` / `hook stderr + exit 2` / `mission` | [読まない技術 第4回：スキルを使わない技術](https://typing-tube.net/articles/8f9ae8791b448d#8f9ae8791b448d-4eea2df8) |
| 交给 sub-agent 的工作，在完成之前看不到里面发生了什么 | 用 YAML 定义可以委托给 sub-agent 的任务、以及启动前必须准备好的输入文件，并用 hook 在启动前检查。 | `subagent (Agent tool)` / `subagent (no parent context)` / `contract (inputs / outputs / acceptance)` | [読まない技術 第5回：サブエージェントの出力だけは読め](https://typing-tube.net/articles/62f714d7c2b599#62f714d7c2b599-7e6cc5ce) |
| 指示文件里规则加得越多，之前加的规则就越不被遵守 | 把每一条“不要做某事”的规则，逐条改写成能检测出违规的自动化测试（Minitest）。 | `CLAUDE.md` / `Claude Code hooks (PreToolUse / PostToolUse / Stop / SubagentStop)` / `hook contract (proof of reading)` | [読まない技術 第6回：ルールを読まない技術](https://typing-tube.net/articles/569d598941c00f#569d598941c00f-4eea2df8) |
| 并行运行的多个会话共享的 memory 变得混乱，让它读方针文件也没用 | 把同一份方针文件挪到 PostToolUse hook 里，和保存后的 diff 一起展示。读的内容不变，只改变出现的时机。 | `MEMORY.md` / `concurrent test runs` / `hooks / automated tests` | [読まない技術 第7回：共有メモリを整理しない技術](https://typing-tube.net/articles/83c46d1e6b2591#83c46d1e6b2591-4eea2df8) |
| 即使写好了同类失败的应对方法，AI 下次还是会犯同样的错误 | 把重试时的方针整理成几行的文件，由检测到失败的 hook 自动插入。 | `auto memory (feedback_*)` | [読まない技術 第8回：修正履歴を読まない技術](https://typing-tube.net/articles/f7c9c30f567aee#f7c9c30f567aee-4eea2df8) |
| 读了交接说明和完成报告，但对自己不利的部分被省略了 | 在完成报告旁边，每次都并排列出用 git diff --stat 等命令机械获取的数值。 | `handoff` / `test summary line (full log in a file)` | [読まない技術 第9回：引き継ぎを読まない技術](https://typing-tube.net/articles/a43b57a94d2216#a43b57a94d2216-4eea2df8) |
| 机器统计出的数字，传到报告里时已经变成了另一个数字 | 给数值所在的行加上固定前缀，并用 hook 检查它是否被逐字复制过来。 | `machine-counted numbers ([observed] / git diff --stat)` / `test summary line (full log in a file)` / `self-report (bias toward completion)` | [読まない技術 第10回：AIに要約しろと言わない技術](https://typing-tube.net/articles/yomanai-10-no-summary#yomanai-10-no-summary-4eea2df8) |
| 在 AI 工作过程中插话，之后的动作就会乱掉 | 不要在工作中途由人插话，而是让保存后立即返回方针的 PostToolUse hook，以及检测到失败就打回的 hook 来介入。人等到一个段落结束再说。 | `user message during a task` / `recency` / `context window` | [読まない技術 第11回：口を挟まない技術](https://typing-tube.net/articles/6c6d2e4f80a649#6c6d2e4f80a649-e4cb60ea) |
| 会话结束时，该读什么、不该读什么并没有定下来 | 不去读产出物也不去读 transcript，只看测试和 linter 的 exit code 判定通过还是失败。 | `self-report (bias toward completion)` / `machine-counted numbers ([observed] / git diff --stat)` / `exit code (pass / fail)` | [読まない技術 第12回：作業結果を読まない技術](https://typing-tube.net/articles/1769779c2f1b4b#1769779c2f1b4b-4eea2df8) |
| 一次驳回的提案，在下一个会话里又被提出来 | 把驳回过的判断，用固定的格式整理进同一份文档里。 |  | [AIの意見を聞かない技術 第1回：提案を検討しない技術](https://typing-tube.net/articles/kikanai-01-no-review#kikanai-01-no-review-9e2b31e8) |
| 明明写了一行禁止事项，却被过度解读或过度缩小解读 | 在汇总驳回判断的那一份文档（例如 non_goals.md）里，为每条禁止事项设一个“理由”小标题，和结论并列写出。 |  | [AIの意見を聞かない技術 第2回：禁止を書かない技術](https://typing-tube.net/articles/kikanai-02-reason#kikanai-02-reason-2973ce11) |
| 禁止事项明明写对了却没被遵守，每次都要来问一遍 | 在驳回文档里为每条禁止事项设一个“适用范围”小标题，把容易判断不清的边界情况逐行列出。 | `gap between goal pressure and spec` / `rule-to-test mapping` | [AIの意見を聞かない技術 第3回：禁止ルールを作らない技術](https://typing-tube.net/articles/kikanai-03-scope#kikanai-03-scope-1db3e01a) |
| 把同一条指示分给多个 sub-agent，返回的格式却各不相同 | 在可以交给 sub-agent 的任务清单里，明确写出启动前应该准备好的输入文件。 | `subagent mission catalog + launch hook` / `contract (inputs / outputs / acceptance)` / `required input files` | [AIの意見を聞かない技術 第4回：サブエージェントの入力だけは、確かめろ](https://typing-tube.net/articles/kikanai-04-subagent-input#kikanai-04-subagent-input-0b96e6a8) |
| 没有自动化测试的禁止事项，只是写在那里不断堆积 | 在驳回文档的清单里加一个“机器验证”小标题，逐项标明是否有对应的自动化测试（Minitest）。 | `probabilistic compliance (p^n)` | [AIの意見を聞かない技術 第5回：自動テストを書かない技術](https://typing-tube.net/articles/kikanai-05-machine-check#kikanai-05-machine-check-0f82d02b) |
| AI 的工作每次都以“请打开页面确认一下”收尾 | 用 Playwright 准备一个 smoke test，判定通过与否看的是数据库里留下的记录，而不是页面的外观。 | `automatic error report from users` | [AIの意見を聞かない技術 第6回：AIの確認依頼を断る技術](https://typing-tube.net/articles/kikanai-06-production#kikanai-06-production-6c41de4e) |
| AI 每次说得稍微有点偏，都要自己解释再纠正 | 不要由人来解释并纠正偏差，而是把指正写进 hook 的 stderr（exit 2）和自动化测试的失败信息里，让它通过这条路径到达 AI。 | `SendMessage (retry)` | [AIの意見を聞かない技術 第7回：AIの話を聞かない技術](https://typing-tube.net/articles/kikanai-07-no-listening#kikanai-07-no-listening-f900b392) |
| 驳回过的判断清单不断变长，眼看就要没人再读了 | 在驳回文档的末尾设一个“未采纳的方案”小节，把驳回的提案记录在那里。 | `MEMORY.md` / `context rot` | [AIの意見を聞かない技術 第8回：ルールを整理しない技術](https://typing-tube.net/articles/kikanai-08-no-inventory#kikanai-08-no-inventory-d72023ae) |
| 指示文件里“请务必执行”的要求一直堆在那里，没有减少 | 用一个自动化测试去核对：指示文件里写着“务必执行”的命令，是否也存在于 pre-commit hook 中。 | `CLAUDE.md` / `Minitest` / `hooks / automated tests` | [言わない技術 第1回：検証を指示しない技術](https://typing-tube.net/articles/iwanai-01-no-verification#iwanai-01-no-verification-f9f3539e) |
| 连具体做法都写清楚交出去了，结果改回来的还是不一样 | 不去指示具体步骤，而是按用途定义 sub-agent 启动前必须存在的输入文件。 | `per-mission guide document` / `presupposition` / `launch without a contract` | [言わない技術 第2回：具体的な指示を出さない技術](https://typing-tube.net/articles/iwanai-02-no-procedure#iwanai-02-no-procedure-e45dd403) |
| 每次反馈 bug，都要自己把复现步骤和症状重新写一遍 | 设置一个 bug 反馈表单，人只需要填一句症状描述，URL、操作历史、浏览器信息由 JavaScript 自动收集。 | `bug report form (JS collects URL / actions / browser)` | [言わない技術 第3回：不具合詳細を書かない技術](https://typing-tube.net/articles/iwanai-03-no-bug-details#iwanai-03-no-bug-details-e45dd403) |
| 每次都要花力气打一句“先出个计划” | 不需要新的实现。放一份设计文档，AI 就会读取现有文档并沿用同样的格式。 |  | [言わない技術 第4回：計画を書けと言わない技術](https://typing-tube.net/articles/iwanai-04-no-plan-request#iwanai-04-no-plan-request-be44c158) |
| 越是希望被遵守的行写得越强调，却不知道有没有效果 | 不再去测量效果，而是统计指示文件里带强调表达的行数，超过基准值就判定失败的自动化测试（ratchet）。 | `emphasis count in CLAUDE.md` / `sycophancy` / `Dir.glob scan` | [言わない技術 第5回：念を押さない技術](https://typing-tube.net/articles/iwanai-05-no-emphasis#iwanai-05-no-emphasis-abb803f1) |
| sub-agent 交回来的成果，格式和自己预想的不一样 | 按 sub-agent 的每种用途，把成果物的验收条件（文件名、格式、必填项）定义在一份文档里。 | `subagent (Agent tool)` / `contract (inputs / outputs / acceptance)` / `self-report (bias toward completion)` | [言わない技術 第6回：サブエージェントの出力だけは、細かく指示しろ](https://typing-tube.net/articles/iwanai-06-subagent-output#iwanai-06-subagent-output-633e9bd9) |
| 发现错误时，忍不住想追问“你真的读过了吗” | 不去追问，而是把每次请求的第二句话固定为“……不是吗？”这样的疑问句模板。 | `sycophancy` | [言わない技術 第7回：AI を問い詰めない技術](https://typing-tube.net/articles/iwanai-07-no-interrogation#iwanai-07-no-interrogation-293fc181) |
| 对返回的答案回一句“不是这个意思”，情况也不会变好 | 不去指出问题，而是把没有替代方案的禁止事项，通过 PostToolUse hook 和保存后的 diff 一起展示出来。 | `SendMessage (retry)` / `guarded_by + marker` / `over-triggering` | [言わない技術 第8回：AI にダメ出ししない技術](https://typing-tube.net/articles/iwanai-08-no-criticism#iwanai-08-no-criticism-e4cb60ea) |
| AI 会像打开过某个文件一样，谈论它其实没打开过的文件内容 | 让 AI 在被引用的文档和代码两边都写上相互对应的标记（marker），再用自动化测试验证标记是否真的存在。 | `hallucination` / `escape hatch (SKIP_*= / --no-verify)` / `marker` | [言わない技術 第9回：AI に考えさせない技術](https://typing-tube.net/articles/iwanai-09-no-guessing#iwanai-09-no-guessing-61ef1df2) |
| AI 不断问“A 和 B 选哪个”，手上的工作就停下来了 | 不再当场回答，而是让选项的判定交给自动化测试或 hook 那一侧来决定。 |  | [言わない技術 第10回：質問に答えない技術](https://typing-tube.net/articles/iwanai-10-no-answering#iwanai-10-no-answering-0efdc39b) |
| 让 AI 做 review，但不知道它到底漏看了什么 | 用一个从外部计数的自动化测试，检测出那些遍历了文件却没有设下限（assert_operator ... :>=）的自动化测试。 | `Minitest` / `vacuous truth` / `Dir.glob scan` | [言わない技術 第11回：AI にレビューをさせない技術](https://typing-tube.net/articles/iwanai-11-no-review#iwanai-11-no-review-659e23ad) |
| 截图越积越多，却分不清哪一张验证了什么 | 在做画面确认之前，先回答“要验证什么”“为什么更廉价的手段不够用”这两个问题，并放一份按单元测试 → 集成测试 → E2E 顺序、从廉价手段开始尝试的方针文档。 | `Playwright screenshot` / `verification ladder (unit → integration → E2E)` / `verification declaration file + PreToolUse hook` | [確かめない技術 第1回：スクリーンショットを撮らない技術](https://typing-tube.net/articles/tashikamenai-01-no-screenshots#tashikamenai-01-no-screenshots-d3d345e4) |
| 设置了要求先写声明的环节，却数不出有多少次执行是跳过声明直接跑的 | 在截图或 E2E 之前先写一个声明文件（例如 tmp/visual_verification.md），说明“要验证什么”，把它是否存在作为 PreToolUse hook 的执行条件，没有声明文件就不启动截图或 E2E。 | `verification declaration file + PreToolUse hook` / `Claude Code hooks (PreToolUse / PostToolUse / Stop / SubagentStop)` / `PreToolUse hook (Bash matcher)` | [確かめない技術 第2回：宣言を信じない技術](https://typing-tube.net/articles/tashikamenai-02-declaration-guard#tashikamenai-02-declaration-guard-4eea2df8) |
| 代码明明没有改动，同一批测试却又跑了一遍，白白等待 | 给测试的包装脚本加上 --last 选项，重新显示上一次的日志，省去再次执行的需要。 | `--last (replay the previous result)` / `mtime check` / `expensive entry point (screenshot / E2E / production)` | [確かめない技術 第3回：テストを再実行しない技術](https://typing-tube.net/articles/tashikamenai-03-no-rerun#tashikamenai-03-no-rerun-ffaed55c) |
| 什么都没弄坏，却冒出一大串没见过的错误 | 在测试的包装脚本里获取互斥锁（利用 mkdir 的原子性），拿不到锁就不执行。 | `flaky failure` / `mkdir lock` / `concurrent test runs` | [確かめない技術 第4回：偽の失敗を読まない技術](https://typing-tube.net/articles/tashikamenai-04-false-failures#tashikamenai-04-false-failures-a29d752a) |
| “测试都通过了”的报告里，没写清楚哪些部分根本没跑 | 给耗时的 E2E 打上区域名标签、默认 skip，并每次都输出没有执行的区域清单。 | `E2E area (E2E=<area>)` / `skipped-area count line` / `pass / fail by DB record` | [確かめない技術 第5回：全部走らせない技術](https://typing-tube.net/articles/tashikamenai-05-selective-e2e#tashikamenai-05-selective-e2e-bb037847) |
| 指定了做事顺序的指示，事后没法判断有没有被遵守 | 想让它遵守步骤时，不要加强指示的措辞，而是改成让走过该步骤的痕迹留在成果物里（例如每打开一个文件就输出一行）。 | `sycophancy` / `file existence check` / `tool_use count` | [動かさない技術 第1回：手順を守らせない技術](https://typing-tube.net/articles/ugokasanai-01-no-procedure-enforcement#ugokasanai-01-no-procedure-enforcement-129e096a) |
| 设置好的 wrapper，用着用着又被换回了原始命令 | 想让它使用 wrapper 时，不要加强指示，而要检查是否还残留着不得不用原始命令的理由（也就是 wrapper 的功能是否有欠缺）。 | `wrapper script` / `the raw command the model defaults to` / `workaround after exit 2` | [動かさない技術 第2回：ラッパーを使わせない技術](https://typing-tube.net/articles/ugokasanai-02-no-wrapper-enforcement#ugokasanai-02-no-wrapper-enforcement-129e096a) |
| 同一个问题问了好几次，每次答案都不一样，一汇总又有东西消失了 | 在把多个回答汇总成一个之前，先按问题类型输出出现次数（多少次里有多少次提到）。 | `one subagent run` / `answer key` | [動かさない技術 第3回：集めない技術](https://typing-tube.net/articles/ugokasanai-03-no-aggregation#ugokasanai-03-no-aggregation-f7af24f4) |
| 写了“如有需要请执行……”这样的条件语句，却不知道有没有触发 | 不写“如有需要请执行……”这类条件性指示，改用不经过这道工序就无法继续的 hook 来强制执行。 | `rule-to-test mapping` / `Claude Code hooks (PreToolUse / PostToolUse / Stop / SubagentStop)` / `file existence check` | [動かさない技術 第4回：役に立たない技術](https://typing-tube.net/articles/ugokasanai-04-no-conditional-instruction#ugokasanai-04-no-conditional-instruction-e45dd403) |
| 回一句“再想一下”答案就会变，但不知道它是不是真的想通了 | 不要用“请再想一下”打回去，而是具体指出是哪个前提错了。 | `sycophancy` / `SendMessage (retry)` / `guarded_by + marker` | [動かさない技術 第5回：選び直させない技術](https://typing-tube.net/articles/ugokasanai-05-no-reselection#ugokasanai-05-no-reselection-88f30148) |
| 写了“不要靠猜测”之后，AI 变成什么都不产出就交回来了 | 不要只给出禁止项，还要一并写明替代的输出方式，比如“不适用时请输出‘无’”。 | `escape hatch (SKIP_*= / --no-verify)` / `hooks + automated tests + ratchet` / `hallucination` | [動かさない技術 第6回：逃げ道を塞がない技術](https://typing-tube.net/articles/ugokasanai-06-no-blocking-exits#ugokasanai-06-no-blocking-exits-420ce5bc) |
| 顺利的对话继续下去，需要核对的工作量却越积越多 | 在任务的分界点结束会话，下一个任务用新的会话开始。 | `context window` / `input / output / cache read tokens` / `sycophancy` | [動かさない技術 第7回：セッションを続けない技術](https://typing-tube.net/articles/ugokasanai-07-no-long-sessions#ugokasanai-07-no-long-sessions-a59368ec) |
| 产出物全都正确，但不会留在产出物里的浪费却在不断累积 | 在产出物齐备的那一刻，用脚本对 transcript 那一侧做一次统计。 | `file existence check` / `machine-counted numbers ([observed] / git diff --stat)` / `Dir.glob scan` | [動かさない技術 第8回：成果物で判断しない技術](https://typing-tube.net/articles/ugokasanai-08-no-artifact-judgment#ugokasanai-08-no-artifact-judgment-588e1e37) |
| 为后来者留下的知识笔记，会和实际情况脱节、变得过时 | 不把知识写进文档里保存，而是嵌入到自动化测试的失败信息或 hook 的中止信息里，在需要的那一刻才输出。 | `handoff` / `MEMORY.md` / `mtime check` | [動かさない技術 第9回：知見を残さない技術](https://typing-tube.net/articles/ugokasanai-09-no-knowledge-notes#ugokasanai-09-no-knowledge-notes-cb7946f3) |
| 刨根问底地追查原因，答案出来之后还在继续读 | 从 transcript 里统计“什么都没改动就连续进行的读取”，并在开始深挖之前用一行写清楚结束条件。 | `machine-counted numbers ([observed] / git diff --stat)` / `input / output / cache read tokens` / `Dir.glob scan` | [追わない技術 第1回：深追いしない技術](https://typing-tube.net/articles/owanai-01-no-deep-dive#owanai-01-no-deep-dive-36119a54) |
| 没有衡量用途，就把单价最便宜的模型定为默认选择 | 把同一个任务分别交给便宜的模型和贵的模型，数清楚完成所需的往返次数，以及新读取量、复用量（cache read）、写入量之后再决定。 | `rule-to-test mapping` / `Minitest` / `machine-counted numbers ([observed] / git diff --stat)` | [追わない技術 第2回：一番安いモデルを使わない技術](https://typing-tube.net/articles/owanai-02-no-cheapest-model#owanai-02-no-cheapest-model-15eb5702) |
| 一旦不顺利，想到的不是改进机制，而是换更高级的模型 | 把同一个任务同时交给贵的和便宜的模型，把只有便宜的一方失败的地方做成检查项留下来。 | `rule-to-test mapping` / `Minitest` / `machine-counted numbers ([observed] / git diff --stat)` | [追わない技術 第3回：最新モデルを使わない技術](https://typing-tube.net/articles/owanai-03-no-latest-model#owanai-03-no-latest-model-eec0ed05) |
| 本可以由主体自己完成的调查，出于保险起见交给了 sub-agent | 交出去之前先看“父 agent 是不是已经掌握了这个前提”。如果已经掌握就在父 agent 里继续，只把父 agent 尚未掌握、需要大量读取的部分交给 sub-agent。 | `subagent (Agent tool)` / `context window` / `input / output / cache read tokens` | [追わない技術 第4回：サブエージェントを使わない技術](https://typing-tube.net/articles/owanai-04-no-subagent#owanai-04-no-subagent-efc681e6) |
| 不假思索地分成 4 份，同时并行跑 | 交给一个 sub-agent 的任务量，控制在一次回复就能返回的规模。决定成本的不是数量，而是拆分后的每一个要和父 agent 往返多少次。 | `subagent (Agent tool)` / `input / output / cache read tokens` / `machine-counted numbers ([observed] / git diff --stat)` | [追わない技術 第5回：エージェントチームを使わない技術](https://typing-tube.net/articles/owanai-05-no-agent-team#owanai-05-no-agent-team-037074af) |
| 在作业进行到一半时，从外部插入“这里也看一下”的要求 | 等到一个工作段落结束后，再缩小范围提出追加请求。向 AI 本身询问不足之处时，一定要附上“如果已经足够，请注明已经足够”。这是为了给它留一条退路（escape hatch），不必硬凑出一个不足之处。 | `subagent (Agent tool)` / `instruction priority (position / recency / system vs user)` / `over-triggering` | [追わない技術 第6回：途中でレビューさせない技術](https://typing-tube.net/articles/owanai-06-no-midway-review#owanai-06-no-midway-review-542ab968) |
| 想通过比较来决定该用哪个模型 | 开始比较模型之前，先数清楚这次比较相当于多少个 hook 或自动化测试的工作量。如果能写出来的机制比这个数字还多，就先把机制建好再比较。 | `input / output / cache read tokens` / `rule-to-test mapping` | [追わない技術 第7回：モデルを選ばない技術](https://typing-tube.net/articles/owanai-07-no-model-choice#owanai-07-no-model-choice-41136ab2) |
| 以一句“没有差异”草草收场，想结束验证 | 用“没有差异”收场之前先数两件事：如果有结果被排除在统计之外（比如失败的 sub-agent），就放回去重新计数；如果一半以上的项目在所有条件下都是 0，就换一种课题的说法重新测量。 | `machine-counted numbers ([observed] / git diff --stat)` / `vacuous truth` | [追わない技術 第8回：諦めさせない技術](https://typing-tube.net/articles/owanai-08-no-giving-up#owanai-08-no-giving-up-82156f07) |

---

出处：《AI 编程困扰逆向索引（症状 → 该怎么做）》garplab（TypingTube） https://typing-tube.net/articles/zh/lookup / CC BY 4.0（https://creativecommons.org/licenses/by/4.0/）
只要注明出处，本表格即可复制、转载、翻译、用于商业用途。最新版本和各篇文章全文见上方 URL。
