我教会 Claude Code 先思考再写代码。这是我的提示词。

Claude Code 是我用过最快的编程助手。它能在几分钟内搭建一个功能、编写测试并发起 PR。但我一直遇到同一个问题:代码运行正常了,然后又出问题了

状态转换中的竞态条件。本该用常量却硬编码的字符串。回滚了本应保留的审计记录的事务。断言 true 而不是断言正确值的测试。

修复总是也很快。但每次修复都伴随着一场支线任务:故障事故、回滚、“为什么没发现这个”的复盘。速度很快,但扣除 Bug 后的净速度并没有那么快。

即使有了一份不错的 CLAUDE.md,我仍然需要时刻盯着每一次会话。请别忘了这次用 TDD。嘿,你忘记检查 Bug Bot 了。你能在发起 PR 前实际运行测试吗?每次提示都感觉像是在和一个极具天赋但短期记忆力只有金鱼水平的人对话。问题不在于 Claude 的能力,而在于写在 markdown 某处的好习惯不会自动变成实践的习惯。我就是流程本身。这意味着流程不一致、健忘,而且对自己越来越恼火。

于是我尝试了不同的方法。与其修复 Claude 的输出,我改变了 Claude 思考的方式


问题不是智力,而是流程

看看初级开发者的工作方式:他们读工单,打开文件,开始敲代码。他们很快。他们也是那些忘记检查调用的方法是否存在、或者引用的数据库列是否在三周前被重命名的人。(就是在三周前重命名的。总是在三周前。)

现在看看高级开发者:他们读工单,读周围的代码,读测试,检查 git 历史,然后才开始敲代码。他们启动较慢但完成更快,因为他们不需要回头修复他们破坏的东西。

Claude Code 默认是初级模式。不是因为它缺乏知识,而是因为它缺乏流程。它没有内部清单告诉它去验证假设、先写测试,或者思考当两个请求同时命中同一个端点时会发生什么。它充满热情。它交付代码。事实证明,热情无法捕获可空的 datetime 崩溃。

我建立了那个清单。


/wizard

/wizard 是一个 Claude Code 技能,一个放在项目中的 markdown 文件,当你在 CLI 中输入 /wizard 时激活。它将 Claude 从快速编码器转变为严谨软件架构师。把它想象成一个站在 Claude 肩上的高级工程师,除了这个从不问你”试过关机再开机吗”。

它是一个 8 阶段方法论,最好配合以下几点使用:一个定义项目规范的 CLAUDE.md、开始前创建的 GitHub issue(/wizard 可以帮你写)、对 TDD 的真正承诺,以及每个任务的干净功能分支。对于 CI,我使用 GitHub Actions,但这个技能不关心这个。它只是需要能在第 8 阶段响应的东西。稍后详述。

以下是 8 个阶段的工作方式。

阶段 1:动代码前先规划

Claude 读取你的 CLAUDE.md,找到关联的 GitHub issue,在写下一行代码之前就构建结构化的待办清单。它评估复杂度:可能影响的文件数量、是否有架构影响、可能出错的程度。然后相应地评估工作量。

这听起来很明显。确实很明显。这也是当你赶时间时最常跳过的步骤,而这时恰恰是最需要它的时候。有趣吧。

阶段 2:假设前先探索

有了计划,Claude 探索实际的代码库。它对每一个打算使用的模型、方法、关系和常量进行 grep 搜索,在代码中引用它们之前验证它们存在。

没有这个阶段,Claude 可能会自信地调用 user.clientProfile.accounts,一个它完全确信存在但实际上是幻觉的关系链。阶段 2 的存在就是为了防止这种情况。仅此一项改变就消除了我项目中整整一类 Bug。事实证明,“这东西真的存在吗”是在它上面构建之前一个相当好的问题。

阶段 3:先写测试

阶段 3 强制执行 TDD。Claude 先写失败的测试,运行它们(必须失败),实现让测试通过的最小代码,然后验证。按这个顺序,每次都这样,不走捷径。

但关键是:它使用变异测试思维。不写 assert($result),而是写 assertEquals('completed', $result->status)。不是检查函数是否运行无错,而是检查每一个副作用是否真的发生了:时间戳设置了、通知发送了、计数器增加了。

差别很重要。assert(true) 在代码什么都不做时也能通过。抗变异的断言能捕获真正的 Bug。你的测试套件应该是怀疑者,而不是那个没看就告诉你 PR 很棒的朋友。

阶段 4:实现最小化

有了失败的测试,Claude 编写实现。不是完整的愿景,不是它脑海中已经有的巧妙抽象,只是让测试通过所需的最小代码。范围蔓延也是一种 Bug,而且是最昂贵的那种,因为它看起来像是进展。

阶段 5:验证无回归

阶段 5 运行更广泛的测试套件,不只是新测试。目标是零回归。如果有不相关的东西坏了,现在发现总比在 PR 评审评论里看到”呃,为什么计费模块挂了”要好。

阶段 6:趁热写文档

内联注释、更新日志条目,任何需要更新的东西。小步骤,容易跳过,但总是在上下文消失前值得做。读这段代码的下一个人可能是三个月后的你自己,盯着它却完全不记得为什么做了那个决定。

阶段 7:对抗性评审

这是 /wizard 真正发挥价值的地方。在每次提交前,Claude 以攻击者的身份而非作者评审自己的工作。检查清单:

  • 如果这个并发运行两次会发生什么?
  • 如果输入是 null 呢?空值?负数?
  • 我做错了什么假设?
  • 如果这个在生产环境崩了我会尴尬吗?

这不是理论。在我的代码库中,这个阶段捕获了:

  • 一个缺少数据库锁定的状态转换服务。两个并发 API 调用可能应用冲突的转换。一个竞态条件,静静地坐在那里,等着一个糟糕的日子。
  • 一个 Blade 模板在可空的 datetime 上调用 ->format()。在任何该字段为 null 的页面加载时崩溃。完全无声,直到它突然发生。
  • 通知载荷使用硬编码的分类字符串,而不是就在同一个 PR 中创建的枚举。真是令人叹为观止。

这些都不会被单独的测试捕获。它们需要以不同的模式思考代码:作为攻击者,而非作者。

阶段 8:质量门禁循环

阶段 8 处理 PR 生命周期。/wizard 不只是发起 PR 就认为工作完成了。它监控自动化评审机器人的状态(Bug Bot、CodeRabbit,无论你有什么),读取每一个发现,修复有效问题,回复误报,然后重复直到状态干净。

这是我以前手动做但经常忘记的阶段,让 PR 带着未解决的机器人发现闲置数天。现在它是流程的一部分,而这正是它一直应该在的地方。


真实案例

以下是在真实任务中所有 8 个阶段的样子:实现 ACAT 转账状态跟踪与通知。

阶段 1:Claude 读取 CLAUDE.md,找到 GitHub issue,评估任务为”复杂”(7+ 文件,架构影响),构建待办清单。

阶段 2:Claude grep 搜索 AcatTransfer 模型,验证 VALID_TRANSITIONS 常量存在,检查 ClientProfile 有正确的关系,确认 NotificationCategory 枚举。没有幻觉的方法链。没有意外。

阶段 3:Claude 编写 23 个失败的测试,覆盖状态转换、通知、命令行为和仪表板渲染。运行它们。全部失败。很好。这就是重点。

阶段 4:Claude 实现服务、命令、5 个通知类、控制器变更和 Blade 模板。运行测试。全部通过。

阶段 5:运行完整的相关测试套件(49 个测试)。零回归。

阶段 6:更新更新日志并给转换服务添加内联注释。

阶段 7:对抗性评审发现 initiated_at->format() 如果字段为 null 可能 NPE。在变成凌晨 2 点事故前修复它。

阶段 8:发起 PR。Bug Bot 发现 4 个问题:

  1. 硬编码的分类字符串(应该用枚举):已修复
  2. 状态转换缺少数据库锁定:用 lockForUpdate() 修复
  3. Blade 模板中可空的 initiated_at:用空安全操作符修复
  4. 完成事件的通知音调错误:已修复

经过 3 轮修复循环,Bug Bot 返回 success。PR 就绪。

总计:49 个测试,108 个断言,4 个 Bug 在发布前被捕获。对于一个清单来说不错。


如何安装

一个命令:

curl -sL https://raw.githubusercontent.com/vlad-ko/claude-wizard/main/install.sh | bash

这会将三个文件放入 .claude/skills/wizard/

  • SKILL.md:核心 8 阶段方法论
  • CHECKLISTS.md:快速参考检查清单
  • PATTERNS.md:常见模式和反模式

然后在 Claude Code 中输入 /wizard 激活它。


定制属于你自己的版本

该技能设计上与框架无关。它不知道你在写 Laravel、Rails、Next.js 还是 Rust。规划、探索、测试、实现、验证、文档、评审、交付的方法论,在任何地方都适用。

但当你定制它时,它会变得强大。在我的项目中,我添加了:

  • Laravel 特定的测试命令(./vendor/bin/sail test
  • 我们的日志服务模式(LoggingService::logPortfolioEvent()
  • 我们 ORM 的数据库锁定约定
  • Bug Bot 线程解析命令(GraphQL 突变)
  • UI 组件的 Alpine.js 要求

你添加的项目特定上下文越多,Claude 需要猜测的就越少。而 Claude 猜测得越少,漏过的 Bug 就越少。事实证明这两者是相关的。


它不是什么

/wizard 不是代码评审的替代品。它不是测试框架。它不是 CI 管道。

它是一个流程提示词:一种将高级工程师习惯编码到 Claude 工作流中的方式,让这些习惯在每次任务、甚至在凌晨 2 点你累了只想让功能发布时都能一致地发生。

提示词大约 500 行 markdown。没有魔法。这是一个优秀的技术负责人会运行的相同清单,只是被明确化和可重复化。唯一令人惊讶的是没有人更早把它写下来。


源码

完整的技能在 github.com/vlad-ko/claude-wizard 开源。MIT 许可证。Fork 它,定制它,让它更好。


原文:I Made Claude Code Think Before It Codes. Here’s the Prompt. 作者:Vladimir J. K.