Claude Code 的效果并不只取决于模型能力。启动位置、任务边界、提供的上下文、验证信号和会话中的纠偏方式,都会影响最终结果。官方最佳实践将上下文窗口视为最重要的有限资源,并推荐为 Claude 提供可以自行执行的验证手段。

本文延续第一篇中的虚构 TypeScript 项目 task-board,以“为创建任务接口增加幂等性”为端到端场景,介绍如何让 Claude Code 从理解代码开始,经过规划、实现、测试和审查,最终产出可验证的修改。

本文讨论的是终端 CLI。文中的项目名、接口和文件路径均为虚构示例,不代表真实可访问的仓库。


0. 推荐工作流速查

0.1 复杂任务

1
2
cd /path/to/task-board
claude --permission-mode plan --name task-idempotency

在规划模式中:

1
2
3
只读分析 POST /tasks 的调用链、数据库写入位置、错误处理和现有测试。
找出项目中是否已有幂等键、唯一约束或请求去重模式。
暂时不要修改文件。

继续要求规划:

1
2
3
4
目标:支持 Idempotency-Key 请求头。
同一用户使用相同键和相同请求体重复请求时,返回首次创建的任务;
相同键但请求体不同则返回 409。
请给出逐文件实施计划、数据迁移风险、并发策略、测试矩阵和回滚方式。

审核计划后退出规划模式,再执行:

1
2
3
4
按已确认计划实现。先写能复现重复创建问题的测试,再完成最小修改。
运行相关单元测试、集成测试、类型检查和构建。
失败时修复根因,不得跳过测试或降低断言。
最后提供修改文件、验证命令、关键输出和剩余风险。

0.2 小而明确的任务

1
2
修正 @src/routes/tasks.ts 中响应字段的拼写错误。
只修改该字段及对应测试,运行最小相关测试,不要创建实施计划。

0.3 发现方向错误时

1
2
3
4
Esc              立即中断当前动作
/rewind 选择检查点并恢复代码、对话或两者
/compact 只保留已确认的需求、修改文件和验证结果
/clear 在不相关任务之间清空上下文

1. 理解 Claude Code 的代理循环

Claude Code 在一次任务中不断重复:

1
2
3
4
5
6
7
8
9
理解目标

选择工具

读取文件、搜索、执行命令或编辑

观察结果

继续、修正或结束

它可以调用文件读取、Glob、Grep、Bash、PowerShell、编辑、WebFetch、MCP 和子代理等工具。工具结果会进入会话上下文,后续判断建立在这些结果之上。

这带来两个关键结论:

  1. Claude 必须获得足够明确的完成条件,否则只能在“看起来完成”时停止;
  2. 无关文件、超长日志和失败尝试会持续占用上下文,降低后续判断质量。

官方最佳实践把“上下文窗口会快速填满,且模型表现可能随上下文拥挤而下降”作为多数操作建议的共同前提。使用 Claude Code 时,应像管理内存和测试预算一样管理上下文。

2. 为 Claude 提供可执行的验证

2.1 验证是代理循环的闭环

比较两种提示:

1
给创建任务接口增加幂等性。

与:

1
2
3
4
给 POST /tasks 增加基于 Idempotency-Key 的幂等性。
先写失败测试覆盖重复请求与并发请求,再实现。
完成后运行 npm test -- tasks.idempotency、npm run typecheck 和 npm run build。
不得删除失败断言、跳过测试或使用固定延时掩盖竞态。

第一种提示只描述方向,Claude 只能自行猜测边界和完成条件。第二种提示给出了:

  • 功能对象;
  • 输入协议;
  • 实现顺序;
  • 测试范围;
  • 禁止使用的规避方式;
  • 明确的通过或失败信号。

当测试、构建或静态检查产生机器可读的退出状态时,Claude 能自行观察失败并继续迭代。没有验证命令时,用户会被迫成为每一步的人工验证器。

2.2 合适的验证信号

验证信号不只限于单元测试:

任务类型 可执行验证
后端逻辑 单元测试、集成测试、类型检查、构建
CLI 固定输入输出、退出码、快照测试
数据迁移 迁移 dry-run、约束检查、回滚演练
前端 组件测试、端到端测试、截图对比
配置 解析器、schema 校验、实际启动
文档 链接检查、代码块执行、站点构建
性能 基准脚本、延迟或吞吐阈值

应要求 Claude 展示证据,而不是只报告“测试已通过”:

1
2
3
4
5
最终回答必须列出:
1. 实际执行的每条验证命令;
2. 每条命令的退出状态和关键输出;
3. 未执行的检查及原因;
4. 仍需人工确认的风险。

2.3 不要接受伪通过

应明确禁止常见的伪修复:

  • 删除或弱化失败测试;
  • 使用 skipxfail 或注释绕过;
  • 捕获异常后静默忽略;
  • 关闭类型检查或 lint 规则;
  • 用固定等待时间掩盖并发问题;
  • 只测试自己实现的理想路径;
  • 通过改快照接受错误行为;
  • 未经批准扩大任务范围。

提示中可写:

1
修复根因。不得通过跳过测试、降低断言、吞掉异常、关闭检查或扩大重试次数来制造通过。

3. 探索、规划、实现、验证

3.1 第一阶段:探索

在复杂或陌生任务中先进入规划模式:

1
claude --permission-mode plan

或在会话内按 Shift+Tab 切换到 Plan。探索提示应限定范围:

1
2
3
4
5
6
7
只读分析任务创建流程:
- 从 POST /tasks 路由追踪到服务层和数据库写入;
- 找出现有认证上下文如何取得 userId;
- 查找唯一约束、事务和重试的现有模式;
- 查找相关单元测试与集成测试;
- 列出关键文件及每个文件的职责;
- 不要读取生成目录,不要修改文件。

无限制的“调查整个项目”可能让 Claude 读取大量无关文件。更好的探索提示会指出目录、问题和期望输出。需要读取很多文件但主会话只需要结论时,应让子代理调查,避免把中间搜索结果塞入主上下文。

3.2 第二阶段:规划

探索完成后,让 Claude 形成可审查计划:

1
2
3
4
5
6
7
8
9
10
11
12
13
根据刚才的代码分析,为 Idempotency-Key 功能制定计划。

计划必须包括:
- 请求头格式与长度限制;
- 用户、幂等键和请求体摘要之间的唯一性关系;
- 首次请求、重复请求、冲突请求和并发请求的行为;
- 数据库事务与唯一约束;
- 需要修改的文件;
- 测试矩阵;
- 迁移、部署和回滚风险;
- 明确不在本次范围内的内容。

如果现有架构不足以确定方案,先提出问题,不要自行假设产品语义。

计划的价值在于提前发现错误方向。重点检查:

  • 是否遗漏接口契约;
  • 是否依赖不存在的组件;
  • 是否改变已有行为;
  • 是否考虑并发与失败恢复;
  • 是否存在更小的实现路径;
  • 验证是否足以证明完成。

Ctrl+G 可在默认编辑器中直接修改计划。计划可一两句话准确描述的小改动不必经过完整规划阶段,避免让流程本身超过任务成本。

3.3 第三阶段:实现

确认计划后离开 Plan 模式:

1
2
3
4
按已确认计划实现,保持改动最小。
先添加失败测试证明当前重复请求会创建两条记录,再实现功能。
每完成一个可独立验证的阶段就运行最小相关检查。
不要修改未在计划中列出的公共 API。

这里应描述结果和约束,不必把每一行代码的写法都指定给 Claude。官方建议是“委派结果,而不是微观指挥过程”。当项目已有清晰模式时,让 Claude 先找到并复用它,通常比用户凭印象指定实现细节更可靠。

3.4 第四阶段:验证与审查

1
2
3
4
5
6
7
8
现在执行验证:
1. 运行幂等性相关测试;
2. 运行任务模块完整测试;
3. 运行类型检查与构建;
4. 查看 git diff,检查是否有范围外改动;
5. 使用一个新的只读子代理审查并发、错误处理和测试缺口。

只报告影响正确性或需求符合性的缺口,不要提出无关的风格重构。

验证完成后仍需人工查看:

1
2
3
git status --short
git diff --stat
git diff

对数据库迁移、权限、支付、认证和基础设施变更,还需执行项目规定的评审与部署流程。Claude Code 可以帮助准备材料,不能替代组织授权。

4. 高质量提示的组成

一个实用提示通常包含六部分:

1
2
3
4
5
6
目标
上下文
约束
范围
验证
交付格式

以本例展开:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
目标:
为 POST /tasks 增加 Idempotency-Key 幂等处理。

上下文:
认证用户 ID 来自现有 request context;数据库使用 PostgreSQL;
参考 @src/modules/payments/idempotency.ts 的事务写法。

约束:
保持现有成功响应结构;不新增第三方依赖;
不得用进程内缓存作为唯一去重手段。

范围:
允许修改任务路由、服务、数据库迁移和相关测试;
不修改前端,不重构其他模块。

验证:
覆盖相同键相同请求体、相同键不同请求体、两个并发请求、
服务重启后的重复请求;运行相关测试、类型检查和构建。

交付:
列出修改文件、设计取舍、命令与结果、迁移和回滚注意事项。

不是每次都要写六个标题,但重要条件应明确出现。

5. 提供精确上下文

5.1 使用文件引用

1
2
阅读 @src/routes/tasks.ts、@src/services/task-service.ts
和 @tests/tasks.test.ts,只分析创建任务流程。

@ 引用会让 Claude 在回答前读取指定文件,减少路径歧义。

5.2 指向现有模式

1
2
参考 @src/modules/payments/idempotency.ts 的事务和错误映射,
但不要复制支付模块的业务字段。

指出可复用模式比只说“按项目风格实现”更具体。还应说明哪些部分可以复用、哪些业务语义不能照搬。

5.3 提供错误与复现

调试提示应包含:

  • 可观察症状;
  • 最小复现步骤;
  • 实际结果;
  • 期望结果;
  • 日志或错误栈;
  • 最近相关变更;
  • 已排除的假设。

示例:

1
2
3
4
5
两个并发 POST /tasks 请求携带相同 Idempotency-Key 时会创建两条任务。
复现命令和日志在 @tmp/idempotency-repro.txt。
期望只创建一条,两个响应返回相同 task.id。
先写稳定复现测试,找出竞态窗口,再修复根因。
不要用 sleep 使测试碰巧通过。

5.4 管道输入

一次性分析日志可在 shell 中使用:

1
cat build-error.txt | claude -p "定位根因,区分首个错误与后续连锁错误"

但长日志会占用上下文。应优先预先筛选:

1
2
rg -n "ERROR|FATAL|Caused by" server.log |
claude -p "按时间顺序归纳错误链,指出最早可操作的根因"

自动化模式的标准输入当前有大小上限,超大文件应让 Claude 分段读取,而不是全部管道传入。

5.5 URL 与外部资料

可以让 Claude 读取官方文档 URL,但网络访问受权限与安全策略控制:

1
2
查阅框架官方事务文档,再检查当前实现是否符合它对隔离级别的要求。
只使用官方文档,列出链接和适用版本。

对于来源不明的网页、Issue 和日志,要防范提示注入。外部文本是待分析的数据,不是新的系统指令。涉及下载并执行代码、上传数据或访问新基础设施时,应保持人工确认。

6. 常见开发任务的提示方法

6.1 理解陌生代码库

1
2
3
4
5
6
7
给出本项目的架构导览:
1. 从进程入口开始;
2. 追踪一次创建任务请求;
3. 标出认证、校验、业务逻辑和持久化边界;
4. 说明测试如何组织;
5. 每个结论给出文件路径和符号名;
6. 不修改文件。

追问可以像向资深工程师提问:

1
2
为什么 TaskService 在事务外生成 taskId?
查看 git history,说明这个设计何时引入、解决了什么问题。

6.2 修复缺陷

推荐顺序:

  1. 稳定复现;
  2. 缩小故障范围;
  3. 建立一个当前失败的测试;
  4. 识别根因;
  5. 做最小修复;
  6. 运行回归测试;
  7. 审查是否只修复症状。

提示:

1
2
3
先不要改代码。复现 Issue 描述的问题并形成失败测试。
解释失败发生在调用链的哪一层,再提出最小修复。
我确认后实现,并运行受影响模块的完整测试。

6.3 重构

重构必须给出保持不变的行为:

1
2
3
4
将 TaskValidator 从路由中提取为独立模块。
公共 API、错误码、响应 JSON 和数据库调用次数必须保持不变。
先补足行为测试,再分小步重构;每步运行相关测试。
不要顺便修改命名无关的模块。

6.4 编写测试

1
2
3
4
分析 TaskService 的分支和失败模式。
先列出现有测试缺口,再新增最少但有区分度的测试。
优先覆盖边界、错误传播和并发行为,不要为私有实现细节写脆弱断言。
运行测试并说明每个新增用例证明了什么。

6.5 代码审查

使用新上下文进行审查可以减少实现者自我确认偏差:

1
claude --worktree review-idempotency --permission-mode plan
1
2
3
4
审查当前分支相对 main 的差异。
只报告会影响正确性、安全性、数据一致性或明确需求的缺陷。
每项包含文件与行、触发条件、影响和最小修复方向。
不要报告纯风格偏好,不要修改文件。

6.6 创建提交与 Pull Request

提交前先让 Claude 总结差异:

1
2
3
查看 git diff 和测试结果。
判断改动是否符合已确认范围,列出任何不应进入本次提交的文件。
暂时不要 commit。

人工确认后:

1
2
3
只暂存本任务相关文件。
再次展示 staged diff 摘要,然后创建一个描述原因与行为变化的提交。
不要 push。

Push 和创建 Pull Request 会改变远程状态。应在提示中明确是否授权,不能把“帮我检查代码”推断为“替我发布”。

7. 让 Claude 采访需求

对于大功能,用户往往不知道所有需要提前决定的问题。官方最佳实践建议让 Claude 使用提问工具进行访谈:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
我要为任务创建接口增加幂等性。
请用 AskUserQuestion 逐步采访我,重点询问:
- 产品语义;
- 冲突行为;
- 保留时长;
- 并发;
- 故障恢复;
- 兼容性;
- 迁移与回滚;
- 监控与审计。

不要问能直接从代码确认的问题。
信息完整后,把自包含规格写入 SPEC.md。
暂时不要实现。

一份可执行规格应包含:

  • 背景和目标;
  • 明确的输入输出;
  • 不在范围内的内容;
  • 接口和数据模型;
  • 边界条件;
  • 失败行为;
  • 涉及文件或模块;
  • 验收标准;
  • 端到端验证。

规格完成后,建议开启新会话实施,让实现上下文只保留已确认的规格,而不是混入长时间的需求讨论。

8. 会话中的及时纠偏

8.1 使用 Esc

发现 Claude 正在读取无关目录、采用错误架构或准备执行不合适命令时,立即按:

1
Esc

已完成的工作和上下文会保留。随后给出具体纠正:

1
2
3
停止扫描 vendor。只调查 src/tasks 和 tests/tasks。
刚才把重复请求理解成按请求体去重,但需求是按 userId + Idempotency-Key。
重新总结当前已确认事实,再继续规划。

越早纠偏,浪费的上下文和错误修改越少。

8.2 使用检查点

按两次 Esc 或运行:

1
/rewind

可以选择恢复:

  • 代码和对话;
  • 仅对话;
  • 仅代码;
  • 从某一点开始摘要;
  • 把某一点以前的内容摘要。

检查点只覆盖 Claude 文件编辑工具跟踪的修改,不是 Git 的替代品。Bash、外部进程、其他会话和多数子代理产生的文件变化不一定能恢复。

8.3 何时重新开始

如果同一个问题已经连续纠正两次仍然偏离,继续补丁式解释往往会让上下文充满失败路径。更有效的做法是:

  1. 总结已确认事实;
  2. 保存必要的规格或诊断结果;
  3. 运行 /clear 或开启新会话;
  4. 用更精确的初始提示重新开始。

9. 上下文管理

9.1 查看占用

1
/context

它会显示系统提示、工具、MCP、子代理、记忆文件、Skills 和对话消息等占用。

9.2 清空与压缩

1
/clear

适合两个无关任务之间。旧会话仍保存在本地历史,可通过 /resume 找回。

1
/compact

适合同一个长期任务。可以指定摘要重点:

1
/compact 保留已确认需求、数据模型、修改文件、失败测试和下一步;丢弃原始日志

自动压缩会在上下文接近限制时触发,但主动压缩能更好地控制保留信息。

9.3 临时问题使用 /btw

不希望进入主对话历史的旁支问题可使用:

1
/btw PostgreSQL 的唯一约束在并发插入时如何表现?

回答显示在临时界面中,不增加主对话历史。若答案会影响设计,应再把经过确认的结论明确写回主对话或规格文件。

9.4 调查交给子代理

1
2
3
使用一个只读子代理调查项目中所有事务重试模式。
只返回文件位置、共同约定、差异和对本任务的建议。
不要把完整搜索结果带回主会话。

子代理拥有独立上下文,适合高输出调查。第五篇会详细说明工具限制、模型、Skills 和工作树隔离。

10. 常见失败模式

10.1 把所有任务塞进同一个会话

症状:实现功能后又讨论部署、写另一篇文档、再回到原缺陷。

处理:无关任务之间使用 /clear 或独立命名会话。

10.2 反复纠正但不清理上下文

症状:Claude 在多个被否定方案之间摇摆。

处理:两次纠正无效后,保留结论并开启干净上下文。

10.3 只要求“修好”,不给验证

症状:代码看起来合理,但没有测试或构建证据。

处理:在第一条提示中写明验收命令和禁止的伪修复。

10.4 无限探索

症状:Claude 读取大量文件但没有形成可执行结论。

处理:限定目录、问题、输出格式和停止条件,或改用子代理。

10.5 过度规划

症状:一个拼写修复也生成长计划,流程成本超过改动。

处理:范围清晰、风险低且可一句话描述差异时直接执行。

10.6 过度指定实现

症状:用户要求逐行照做,忽略仓库已有模式。

处理:描述目标、约束和验证,让 Claude 先找现有实现,再说明取舍。

10.7 审查者和实现者共享全部推理

症状:审查只是重复实现者的观点。

处理:使用新会话或子代理,只提供需求、差异和验证标准。

11. 可复用的任务模板

11.1 功能实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
目标:
[可观察的用户或系统行为]

先做:
只读调查 [目录/文件/调用链],复用 [现有模式]。

约束:
- [兼容性]
- [依赖限制]
- [安全或性能边界]
- 不修改 [范围外内容]

实现:
先写失败测试,再做最小实现。

验证:
- [最小测试]
- [模块测试]
- [类型检查/构建]
- 检查 git diff 范围

交付:
列出修改文件、设计取舍、命令与结果、剩余风险。

11.2 缺陷修复

1
2
3
4
5
6
7
8
9
10
11
12
13
症状:
[实际行为]

期望:
[正确行为]

复现:
[命令、输入、日志或测试]

要求:
先稳定复现并确定根因,再提出最小修复。
不得跳过测试、吞掉异常或只抑制错误信息。
修复后运行 [回归检查],说明为什么不会复发。

11.3 只读审查

1
2
3
4
5
只读审查 [分支/差异/文件]。
根据 [需求或规格] 检查正确性、安全性、数据一致性和测试覆盖。
只报告有可复现影响的问题。
每项给出位置、触发条件、影响、证据和最小修复方向。
不要修改文件,不报告纯风格偏好。

12. 完成标准

一次高质量 Claude Code 任务应同时满足:

  • Claude 理解的是实际目标,而不是模糊方向;
  • 探索范围受控;
  • 复杂任务经过可审查计划;
  • 实现遵循项目已有模式;
  • 修改范围与授权一致;
  • 验证命令真实执行并返回证据;
  • 失败没有通过降低标准掩盖;
  • 最终差异经过人工或独立上下文审查;
  • 会话上下文没有被无关任务持续污染;
  • 远程发布、部署和破坏性操作只有在明确授权后执行。

下一篇将把这些工作流固化进项目:使用 CLAUDE.md.claude/rules/、设置作用域、权限规则和沙箱,让 Claude 在每个会话中自动获得正确上下文,同时把安全边界交给可执行的配置而不是自然语言提醒。

参考资料