按自己的理解做了,不是你要的那个
Built what it understood, not what you meant
智能体交付了一个自洽的功能,但回答的是需求的另一种读法。所有检查都通过了,因为检查测的也是它自己的理解。
适用于: Claude Code · Cursor · Codex · Copilot agent
症状
打开结果一看:合理、有测试,但就是不对。你能在需求里找到那句允许两种理解的话。
为什么会这样
需求本身信息不足,智能体会默默消化歧义而不是提问。测试通常也是同一个智能体按同一种理解写的,所以只会证实误读,而不是发现误读。developertoolkit.ai 把这类问题称为 "spec misread",最早的控制点在写代码之前的需求阶段。
示例
示意,基于 developertoolkit.ai 的例子:需求写的是“总价四舍五入到分”。
ts// Intended: round the order total once
const total = round2(items.reduce((s, i) => s + i.price * i.qty, 0));
// Agent's reading: round every line item, then sum (totals now drift by cents)
const total = items.reduce((s, i) => s + round2(i.price * i.qty), 0);
复制即用的修复
按你用的智能体挑选文件。规则片段用英文写,放进任何仓库都能用。
规则
Claude Code:加入 CLAUDE.md
CLAUDE.md## Before writing code: confirm the spec
- Restate the request in one sentence and list every assumption you are making.
- If any sentence in the request allows two readings, ask which one before coding. Do not pick silently.
- Write the acceptance checks first (in SPEC.md or as failing tests), including one example that
distinguishes the intended reading from the most plausible wrong one. Wait for approval on non-trivial work.
- When done, map each acceptance check to the command output that proves it.
规则
Codex、Copilot 编码智能体等:加入 AGENTS.md
AGENTS.md## Before writing code: confirm the spec
- Restate the request in one sentence and list every assumption you are making.
- If any sentence in the request allows two readings, ask which one before coding. Do not pick silently.
- Write the acceptance checks first (in SPEC.md or as failing tests), including one example that
distinguishes the intended reading from the most plausible wrong one. Wait for approval on non-trivial work.
- When done, map each acceptance check to the command output that proves it.
Cursor 规则
Cursor:项目规则
.cursor/rules/spec-misread.mdc---
description: "AgentFails: Built what it understood, not what you meant"
alwaysApply: true
---
## Before writing code: confirm the spec
- Restate the request in one sentence and list every assumption you are making.
- If any sentence in the request allows two readings, ask which one before coding. Do not pick silently.
- Write the acceptance checks first (in SPEC.md or as failing tests), including one example that
distinguishes the intended reading from the most plausible wrong one. Wait for approval on non-trivial work.
- When done, map each acceptance check to the command output that proves it.
模板
SPEC.md 验收标准(先写、先确认,再写代码)
队友直接在这个文件(或设计稿/产物)上批注,而不是事后审一个大 PR。每条验收标准都要能区分“你要的理解”和“你不要的理解”。
SPEC.md# Spec: <feature name>
## Goal (one sentence, in the user's words)
## Out of scope
- <things a reasonable agent might also do, but must not>
## Acceptance checks (each one runnable)
- [ ] Given <input>, when <action>, then <exact observable result>
- [ ] Example that rules out the wrong reading: <input> -> <expected>, NOT <plausible wrong output>
- [ ] Command that proves it: `<test or curl command>`
## Open questions (agent must ask, not assume)
- <question>
## Approved by: <name> on <date>
技能
团队共享的 /verify 技能(Claude Code)
把它提交进仓库,让整个团队(以及每个智能体会话)跑同一套检查。把命令换成你项目里真实的命令。
.claude/skills/verify/SKILL.md---
name: verify
description: Verify the current change before calling it done. Use before every commit, PR, or "done" message.
---
# Verify
Run every step and paste the real output. Never summarize a step you did not run.
1. **Scope**: run `git diff --stat` and `git status --short`. For every changed file, say which part
of the request needs it. Any file you cannot justify gets reverted, or listed under
"Unrequested changes" for the user to decide.
2. **Build and types**: `npm run build` (or the project's build command).
3. **Tests**: `npm test`. Report pass/fail counts. If a test was edited, skipped or deleted,
say so explicitly with the reason.
4. **Behavior**: exercise the changed behavior once for real (a curl, a CLI run, a screenshot)
and show what happened.
5. **Report** in this format:
- Requested: <one line>
- Changed files: <list, each with its reason>
- Checks run: <command -> result>
- Not done / unsure: <list, or "none">