Rokcso's Blog

译> 我如何使用 Claude Code

我目前使用 Claude Code 的方式基本遵循「规划 –> 实施」的工作流,但是每一个环节的具体执行上其实还不够到位,我用过 Claude Code 内置的规划模式,也用过 OpenSpec 这种比较「重」的规划模式,感觉 Boris Tane 所分享的这种工作流是介于二者之间的恰到好处,值得尝试。

除了在规划阶段投入精力,及时止损也很重要,不要在投入太多精力让 Claude Code 修复它之前产出的错误结果,直接撤销从头再来通常更为高效。


本文翻译自 How I Use Claude Code,作者 Boris Tane

译文由 AI 翻译,rokcso 修正

我使用 Claude Code 作为主力开发工具已有大约 9 个月了,最终形成的工作流与大多数人使用 AI 编程工具的方式截然不同。多数开发者习惯于输入提示词、偶尔启用规划模式、修补错误、循环往复。更极端的用户则热衷于缝合各种技术黑话 —— 拉尔夫循环、MCP 协议、Gas Town(还记得这些吗?)等等。但无论是哪种方式,一旦涉及复杂场景便会土崩瓦解,产出的结果往往杂乱无章且难以维系。

我将要介绍的工作流有一个核心原则:在审查并批准书面方案之前,绝不允许 Claude 编写代码。这种规划与执行相分离的原则是我实践中最关键的突破。它不仅避免了无效劳动,让我始终掌控架构决策主导权,更重要的是,相比直接生成代码,这种模式能用更少的 token 消耗产出质量显著提升的成果。

graph LR
    A["研究"] --> B["规划"]
    B --> C["注释"]
    C --> | 重复 1-6x | C
    C --> D["任务清单"]
    D --> E["实施"]
    E --> F["反馈与迭代"]

第一阶段:研究

每个有价值的任务都始于一条深入研究指令。我会要求 Claude 在开展任何实际操作前,彻底理解代码库的相关部分。关键在于:所有研究发现必须写入可持续维护的 Markdown 文档,而绝不仅仅是聊天窗口中的临时性文字摘要。

深入阅读这个文件夹,彻底理解其工作原理,了解其功能以及所有具体细节。完成之后,将你的学习成果和发现详细记录在 research.md 文档中


深入研究通知系统,彻底理解其工作原理,并撰写一份详细的 research.md 文档,包含关于通知工作原理的所有信息


深入研究任务调度流程,彻底理解其工作原理,寻找潜在的错误。系统中确实存在错误,因为它有时会运行本应取消的任务。继续研究流程,直到找到所有错误,不要停止,直到所有错误被发现。完成后,在 research.md 中详细记录你的发现

注意这些措辞:「深度地」「详细地」「关注细节」「全面地」。这不是无关紧要的。如果没有这些词,Claude 只会浅尝辄止。它可扫读文件,仅在函数签名层面了解其功能,然后跳过。你必须明确表示不能只做表面阅读。

书面文档(research.md)至关重要。这并非为了让 Claude 完成作业般的形式主义,而是我进行审查的基准界面。通过阅读这份文档,我能验证 Claude 是否真正理解了系统架构,并在制定规划前及时纠偏。若前期研究有误,后续规划必将出错,最终实现自然也会失败。输入的是垃圾,输出自然也是垃圾。

这正是 AI 辅助编程中最需要警惕的失败模式,问题并非出在语法错误或逻辑缺陷,而在于那些孤立运行正常却破坏系统整体性的实现。比如某个函数忽略了现有的缓存层,一次数据迁移未遵循 ORM 的规范,或是新增 API 端点重复实现了既有逻辑。而前期研究阶段正是杜绝此类问题的关键防线。

第二阶段:规划

在我审阅完研究报告后,会要求在一个独立的 Markdown 文件中提供详细的实施方案。

我想构建一个新功能(名称和描述),该功能扩展系统以执行(业务成果)。编写一个详细的 plan.md 文档,概述如何实现此功能。包含代码片段


列表接口应支持基于游标的分页,而非偏移量。请编写一份详细的 plan.md,阐述如何实现此功能。在提出修改建议前,务必阅读源文件,并依据实际代码库制定计划

生成的方案始终包含以下要素:详细的方法说明、展示具体修改的代码片段、涉及变更的文件路径,以及相关的考量因素与利弊分析。

我习惯使用自己的 .md 规划文档,而非 Claude Code 内置的规划模式。内置的规划模式实在难用。我的 Markdown 文件能让我完全掌控,既能在编辑器中自由修改,又可添加行内注释,更重要的是它能作为实际成果永久存储在项目里。

我有个常用的技巧:当需要开发独立功能时,如果曾在开源项目中见过优秀实现,我会将参考代码与需求说明一并提交。比如要实现可排序 ID 功能,就直接粘贴某个项目的 ID 生成代码,附上说明「这是别人实现可排序 ID 的方案,请据此撰写 plan.md 说明如何采用类似方案」。实践表明,当 Claude 拥有具体参考实现而非从零设计时,工作效果会显著提升。

不过,规划文档本身其实不是重点。真正的精髓在于后续的展开。

注释循环

这是我工作流中最具特色的环节,也是我个人价值贡献最集中的部分。

graph TD
    A[Claude 编写 plan.md] --> B[我在编辑器中审阅]
    B --> C[我添加行内注释]
    C --> D[将文档重新发给 Claude]
    D --> E[Claude 更新 plan.md]
    E --> F{满意?}
    F -->|No| B
    F -->|Yes| G[请求任务清单]

当 Claude 输出规划方案后,我会在编辑器中打开文档,直接添加行内注释。用来修正不合理的假设、否决某些实现路径、增加技术约束条件,或是补充 Claude 所欠缺的领域知识。

注释的篇幅差异极大。有时仅需两三个字,比如在 Claude 标记为「可选」的参数旁写上「必填」;有时则需一大段话,阐释某个业务逻辑的来龙去脉,或是直接粘贴代码片段示范预期的数据结构。

以下是我实际添加注释的几个真实样例:

然后我将文档重新发给 Claude:

我在文档中添加了几条注释,请处理所有注释并相应更新文档。暂不实现

这个循环重复 1 到 6 次。显式的「暂不实现」是必不可少的。没有它,Claude 会立刻跳到编写代码,只要它认为规划足够好。只要在我确认它足够好之前,它都还不够好。

为什么效果如此出色

这个 Markdown 文件在我和 Claude 之间是共享可变状态。我可以按自己的节奏思考,精确标注错误之处,重新参与讨论而不丢失上下文。我并非试图在聊天消息中解释所有内容,而是在文档中直接指出问题所在并写出更正。

这本质上与试图通过聊天消息来指导实施是不同的。这个规划是一个结构化、完整的规范,我可以全面地审查。聊天对话是我需要滚动查看才能重建决策的内容。规划每次都更好。

经过三轮「我添加注释,更新计划」可以将一个通用的实施规划转变为与现有系统完美契合的规划。Claude 在理解代码、提出解决方案和编写实现方面非常出色。但它不了解我的产品优先级,不了解我的用户的痛点,也不了解我愿意做出的工程权衡。注释循环是我注入这种判断的方式。

任务清单

在实施开始前,我总会先要求将任务分解得尽可能详细:

在规划中添加一份详尽的任务清单,涵盖所有阶段及完成规划所需的各项具体任务,暂不执行

这会创建一个清单,用作实施过程中的进度跟踪器。Claude 会随着进展自动标记项目为已完成,因此我随时可以查看规划,准确了解当前进度。这对于进行数小时会话的场景尤其有用。

第三阶段:实施

当规划准备就绪后,我会下达实施指令。我已经将其精炼成一个标准提示词,并在各个会话中重复使用:

全面实施。当任务或阶段完成后,请在规划文档中将其标记为已完成。不要停止,直到所有任务和阶段都完成。不要添加不必要的注释或 jsdocs,不要使用任何或未知的类型。持续运行类型检查,确保不会引入新的问题。

这个提示词包含了所有关键内容:

我几乎在每次实施过程中都使用这个措辞(略有变化)。当我说「全面实施」时,所有决策都已做出并验证。实施变得机械而非创造性,这是有意为之。我想让实施过程变得枯燥乏味,创造性的工作发生在注释循环。一旦规划正确,实施就应该是直截了当的。

如果没有规划阶段,Claude 通常会过早地做出一个看似合理但实际上错误的假设,并在此基础上进行大约 15 分钟的构建,然后我不得不逐一撤销这些更改。「不要立即实现」的防护措施可以完全避免这种情况。

实施过程中的意见反馈

一旦 Claude 开始实施规划,我的角色就从架构师转变为监督者。我的提示变得非常简洁。

graph LR
    A[Claude 实施] --> B[我审查/测试]
    B --> C{正确?}
    C -->|No| D[简洁的纠正]
    D --> A
    C -->|Yes| E{更多任务?}
    E -->|Yes| A
    E -->|No| F[完成]

规划注释可能是一个段落,但实施更正通常只是一句话:

Claude 对整个规划和当前会话都有全面的了解,因此只需简洁的更正即可。

前端开发是最需要不断迭代的部分。我通常在浏览器中测试,并迅速做出调整:

遇到视觉问题时,我有时会附上截图。一张表格错位截图比文字描述更能快速传达问题。

我也经常参考已有代码:

这种方法比从零开始描述一个设计要精确得多。成熟代码库中的大多数功能都是基于现有模式的变体。因此,新的设置页面应该与现有的设置页面保持一致。通过参考现有页面,可以传达所有隐含的要求,无需详细说明。Claude 通常会在进行更正之前读取参考文件。

当事情出现偏差时,我不会尝试去修补。我会回滚并重新规划,通过舍弃 Git 的更改:

进行回滚后缩小工作范围,通常比试图逐步修正错误的方法效果更好。

保持在掌控之中

虽然我把实施任务委托给 Claude,但我从不给它完全的自主权去决定构建什么。我在 plan.md 文档中负责绝大部分的主动指导。

这很重要,因为 Claude 有时会提出技术上正确但对项目不合适的解决方案。或许这个方法过于复杂,或者它改变了其他系统部分依赖的公共 API 签名,或者它选择了一个更复杂的选项,而一个简单的选项就足够了。Claude 没有关于整个系统、产品方向和工程文化的背景信息。

graph TD
    A[Claude 提出提案] --> B[我评估每一项]
    B --> C[原样接受]
    B --> D[修改提案]
    B --> E[跳过/移除]
    B --> F[覆盖技术选择]
    C --> G[精炼的实施范围]
    D --> G
    E --> G
    F --> G

在提案中进行挑选:当 Claude 提出多个问题时,我会逐一处理:「第一个问题直接用 Promise.all 就行,别搞太复杂;第三个问题单独提取成函数,提升可读性;第四个和第五个忽略掉,不值得为此增加复杂度。」。我正基于当前最紧要的知识点,逐项做出决策。

范围裁剪:当规划包含锦上添花的功能时,我会果断削减。「将下载功能从计划中移除,我现在不想实现这个。」。这能有效防止范围无限制扩大。

保护现有接口:当我明确某些内容不应更改时,我会设置硬性约束:「这三个函数的签名不应更改,调用方必须适配,而非修改库本身。」

覆盖技术选择:有时我有特定的偏好(这是 Claude 无法知晓的),比如*「使用这个模型而非那个」「使用这个库的内置方法而非编写自定义方法」*。快速、直接的覆盖操作。

Claude 负责具体实施,而我负责关键决策。规划预先就明确方向,选择性指导则处理实施过程中出现的小细节。

单个长时间会话

我倾向于在单个长时间会话中完成研究、规划和实施,而非拆分为多个独立会话。一次会话可能从深度阅读某个文件夹开始,经过三轮规划注释,然后执行完整实施方案,全程在连续对话中一气呵成。

实际上我并未遇到像大家说的那样上下文窗口占用超 50% 后的性能衰减。因为当我说「全面实施」时,Claude 早已在整个会话中持续构建认知:在研究阶段阅读文件,在注释循环完善思维模型,并吸收我提供的领域知识修正。

当上下文窗口满载时,Claude 的自动压缩机制会保留足够上下文以保持进程连贯。而作为持久性产物的规划文档,能在压缩过程中完整保留全部信息精度。我可以在任意时间点指引 Cluade 查阅该文档。

一句话概括

深度阅读,制定规划,反复注释直至计划完善,然后放手让 Claude 连续全面实施,过程中进行类型检查。

仅此而已。无需魔法提示词,无需复杂的系统指令,无需奇技淫巧。只需要一套将思考与执行分离的规范流程。前置研究能防止 Claude 做出无知的改动,详细规划能避免其错误修改,注释循环则注入我的判断力。而在所有决策敲定后,一条实施指令即可让它心无旁骛地持续运转。

试试这套工作流,你会惊讶于从前没有注释规划文档作为缓冲时,自己究竟是如何用编程 Agent 完成任何项目。

#Translation