Inside ClaudeKit ClaudeKit Engineer
更新于 2026-05-21 Planning, Deep, TDD Home

选择 plan mode 时的备忘

什么时候用 /ck:plan --deep --tdd

不是每个任务都需要重量级模式。本文厘清什么时候需要 --deep,什么时候加 --tdd,什么时候走短路径就够了。

贯穿示例

billing 模块从单体应用里拆出来

API routes DB models 后台任务 Webhooks Admin UI

Billing 逻辑散落在 API routes、database models、后台任务、retry 逻辑、invoice status、webhook handler 和 Admin UI 里。任务听起来简单:"把 billing 拆成独立模块,保留旧行为"。但 agent 一开始跑,新问题就暴露出来了:

  • 哪些文件真正属于 scope:API、jobs、DB、UI 还是 webhook?
  • 哪些行为必须保留:retry、幂等性、invoice status、payment failure?
  • 现有测试覆盖了多少?
  • 这个阶段是否隐式依赖某个 migration 或后台任务?
  • 新代码构建通过但边界条件偏差了,谁来发现?

对于小任务,/ck:plan --fast 或默认的 /ck:plan 通常够用。对于复杂但还不到大规模重构的任务,--hard 往往更合适。对于大任务,前期缺乏 context 会在后期产生代价:cook 要重新猜测 scope,phase 文件模糊,test 写在代码之后,回归问题只有重构完才暴露。

核心

--deep 帮助 plan 看清受影响的范围:文件清单、test 缺口、各阶段之间的依赖。--tdd 强制在重构前记录当前行为,再用这些测试作为回归验证门。

这两个选项不是"更强的模式"——不是打开就更好。它们各自解决一个具体风险:不清楚 scope无法保护旧行为

Section 01

Mode 与 Flag,两个不同的概念

在继续之前,需要先厘清一个容易混淆的地方。/ck:plan 接受两类参数:

类型示例作用
Mode--fast, --hard, --deep, --parallel, --two选择 pipeline。每条命令只用一个 mode。
Composable flag--tdd, --no-tasks附加选项,可以搭配任意 mode 使用。

关键点:--deepmode,会改变 planning pipeline。--tddflag,保持已选的 mode 不变,只在 phase 文件和 cook 流程里加入 tests-first 的部分。

argument hint
argument-hint: "[task] [--fast|--hard|--deep|--parallel|--two] [--tdd|--no-tasks]"

各 mode 之间的 | 表示选其一。--tdd 在独立的 block 里,所以可以组合。因此 --deep --tdd 合法,而 --deep --hard 不合法。

Section 02

--deep,当 plan 需要按阶段绘制地图

--deep 解决什么问题

大型任务通常会同时影响多个代码区域。以 billing 模块为例,scope 可能横跨:

  • API routes:创建 invoice、重试支付、退款、webhook callback
  • Database:invoice 表、payment attempt 表、status 历史
  • 后台任务:重试调度器、对账任务、webhook replay
  • Admin UI:invoice 详情、手动重试、退款操作
  • 共享契约:前端 API 响应、webhook payload、事件名称

这类任务不只需要一份步骤清单,它们需要一张地图:

问题billing 示例中的对应
哪些文件需要 create/modify/delete?Route、service、job、migration、UI action
哪些测试在覆盖旧行为?Retry、幂等性、退款、webhook replay
哪个阶段依赖哪个阶段?Migration 必须先于 service,service 先于 UI
哪些接口需要测试保护?API 响应、webhook payload、job 输入
哪条依赖边风险最高?Job 读取旧 status 时 service 已改了枚举值

--deep 适合在"plan 出错的代价大于细致 plan 的成本"时使用。

mode rule
Major refactor, 5+ areas, architectural debt -> use --deep

如果只改少量文件,--fast 或默认 /ck:plan 通常够用。如果 scope 复杂但架构还清晰,--hard 往往更合适。--deep 值得用的场景是:plan 出错会导致数小时返工——重写 phase、重写测试、重新分配所有权。

--deep 的 pipeline

先建立宽泛 context,再逐步聚焦到具体 phase。

Researcher pass2-3 轮审视架构与受影响区域。
Scout 全局文档、主模块、现有测试、主要依赖。
按 phase Scout每个 phase 有文件清单、test 缺口、需保护的接口。
Phase 文件Planner 将 scout 数据写入各 phase。
Red-team发现 scope 泄漏、phase 顺序错误、实现风险。
Validation检查 plan 是否包含足够的 command、依赖和成功标准。
Tasks生成 task 列表,除非使用了 --no-tasks
Cook handoff输出 /ck:cook {path}/plan.md

--hard(通常对整个 plan 只 scout 一轮)相比,--deep 会对每个 phase 额外做一轮检查。成本更高,但换来的是更具体的 phase 文件:涉及哪些文件、缺少哪些测试、哪条依赖有风险。

--deep 时 phase 文件需要额外包含什么

  • 文件清单表:操作类型 create/modify/delete、预估大小、测试影响
  • 测试场景矩阵:critical/high/medium 路径
  • 依赖图:当前 phase 链接到哪些其他 phase
  • 函数/接口检查清单:哪些函数或接口需要测试保护

这是核心差异所在。一个 phase 不能只说"重构 billing service",它必须说清楚涉及哪些文件、测试、边界条件,以及依赖哪个 phase。

Section 03

--tdd,当你担心重构破坏正在运行的行为

--tdd 解决什么问题

cook 的默认流程很熟悉:读取 plan、逐步实现每个 task、每个文件后做 type check,之后再单独跑测试。对于 greenfield 项目这没问题。对于正在运行的代码的重构,这还不够安全。

在 billing 示例中,旧行为可能包括:

  • Retry 最多跑 3 次,之后把 invoice 改为 failed
  • 相同 event_id 的 webhook 只能 apply 一次
  • invoice 已经 voided 时不能发起退款
  • Admin UI 在 service 拆分后仍需正确显示 status 历史

Happy path 可能仍然通过。Bug 往往藏在边界条件里。--tdd 在改代码之前建立回归验证门。这里的"TDD"不是为新功能写测试,而是在重构前先记录当前行为

--tdd 最有价值的场景

场景是否适合用?billing 中的对应
全新的 greenfield 代码通常不需要没有 invoice/retry 行为可以记录
重构正在被用户使用的模块适合需要保留 retry、幂等性、status 转换
更换支付提供商但保留旧契约适合API 响应或 webhook 行为容易出现偏差
改动 1-2 行且原因明确通常不需要比如修改 Admin UI 里的 label 拼写
临时原型不需要测试验证门的成本不值得

--tdd 在具有异步模式、有状态工作流、数据库事务或公共 API 契约的模块中价值最大。Billing 恰好包含所有这些:后台任务、status 转换、事务边界、webhook payload、admin 操作。

在 plan 阶段

phase 文件中的部分作用
重构前的测试在改代码前先写回归覆盖,记录当前行为。
重构描述要改的代码,受上面的测试保护。
补充测试为本阶段新增行为补充测试(如果有)。
阶段末验证门具体的 compile + test 命令,重构后必须全部通过。
phase shape
使用 --tdd 的 phase 通常按以下顺序执行:
1. 写测试保护当前行为
2. 如果旧代码难以测试,先拆解一个小依赖点
3. 重构代码
4. 重新跑 compile + tests

让旧代码可测试这一步经常被跳过。有时候旧代码根本无法直接测试:一个长函数内部直接调用数据库,无法注入依赖,无法隔离输出。这时需要先拆出一个小依赖点——保持行为不变,但让代码可测——然后再做真正的重构。

cook 运行时

使用 --tdd 时 cook 的执行流程

先写测试在改代码前记录当前行为。
重构调整结构、拆分模块,必要时让旧代码可测。
跑验证门保护旧行为的测试仍需与 compile 门一起通过。

简单理解:先写的测试是旧行为的基准。重构后如果基准失败,cook 应该暂停修复行为偏差,再继续往下走。

版本说明

本文对照 Engineer Kit engineer@v2.19.1-beta.10 撰写,可通过 ck -V 确认。此说明仅用于在 ck:planck:cook 工作流日后变更时避免混淆。

Section 04

为什么 --deep--tdd 经常一起用

--deep--tdd 解决的是两个不同层次的风险。

如果任务同时存在两种风险,两个选项都打开。

不清楚 scope需要按 phase scout、文件清单、依赖图。
担心旧行为偏移需要重构前先写测试,cook 时有回归验证门。
结论--deep 提供地图,--tdd 提供验证层。大型重构通常两者都需要。
风险需要什么选项
不清楚 scope按 phase scout、文件清单、依赖图--deep
重构导致旧行为偏移重构前先写测试,cook 时有 Regression Gate--tdd

大型重构通常同时存在两种风险。例如:

task shape
把 billing 模块从单体应用里拆出来。
保留前端现有的 API 契约。
保留 retry、幂等性、invoice status 的旧行为。
涉及:database schema、后台任务、API routes、Admin UI。

这个 billing 任务需要 --deep,因为 scope 广、依赖多。它也需要 --tdd,因为 retry、幂等性、退款和 webhook 都是需要保留的旧行为。

只开 --deep,plan 可能很清晰,但重构仍然缺少回归验证门。只开 --tdd,测试流程可能正确,但 phase 文件仍然模糊:测什么、在哪里、哪个模块受影响、哪条依赖需要先跑。

速记

任务范围宽就用 --deep。有旧行为需要保留就加 --tdd。两个风险都有才同时打开。

Section 05

什么时候先用 /ck:brainstorm/ck:scout

一个常见错误:在思路还模糊时就用 --deep --tdd。plan mode 不解决 ambiguity。它只是把已经选定的方案转化为更具体的步骤。

例如,如果还没有决定:

  • 真正拆成独立 service,还是只在单体内模块化?
  • 引入新队列,还是保留现有后台任务?
  • 保留现有 invoice status 枚举,还是改用更清晰的状态机?
  • 重写 Admin UI 流程,还是逐步重构?

这种情况应该先用 /ck:brainstorm 确定方案,再去 plan。

另一层是 /ck:scout。把它看作收集 context 的步骤,而不是做决策的步骤。当你不确定代码在哪里、哪些模块相关、哪些测试覆盖了当前行为时,scout 很有价值。

brief 还模糊时,不要直接跳到 plan。

1 · Scout找到真实代码、真实测试、真实依赖。
2 · Brainstorm在锁定 plan 前先选定方案和权衡。
3 · Plan方案已足够清晰时再用 --deep --tdd
context-first flow
/ck:scout "billing retry flow, invoice status, background jobs, admin UI"
/ck:brainstorm "把 billing 模块拆出来但保留现有 API 契约"
/ck:plan --deep --tdd "按已确定的方案重构 billing 模块..."

当你已经熟悉相关代码区域和主要权衡时,可以跳过单独的 /ck:scout 步骤。/ck:plan --deep 的 pipeline 里本身就包含 scout 步骤。但当 brief 还太笼统时,提前 scout 能避免一个隐性错误:agent 的推理听起来合理,却是基于一份错误的项目地图。

场景从哪里开始
不熟悉项目 context / 不知道代码在哪里/ck:scout -> /ck:brainstorm
清楚做什么怎么做直接用 /ck:plan
清楚做什么,不确定怎么做/ck:brainstorm -> /ck:plan
还不确定要不要做/ck:brainstorm -> 决定 -> plan 或放弃
Section 06

决策矩阵

Scope unclear先用 /ck:scout
Approach unclear先用 /ck:brainstorm
Major refactor/ck:plan --deep --tdd
场景命令
不熟悉项目 context先用 /ck:scout,再 brainstorm/plan
不确定方案先用 /ck:brainstorm
小修改 1-2 个文件/ck:plan --fast
中等规模新功能/ck:plan 自动
复杂功能、陌生领域/ck:plan --hard
3+ 个独立模块、可并行/ck:plan --parallel
纠结于 2 个具体方案/ck:plan --two
重构 5+ 个区域、有架构债/ck:plan --deep
重构正在运行/dogfood 的代码,担心回归任意 mode + --tdd
大型重构且代码库有需要保留的行为/ck:plan --deep --tdd

--deep --tdd 不是一个单一机制,而是两件不同的事放在一起。--deep 提供地图--tdd 提供验证层。planning 成本增加了,但 cook 不用猜测 scope,回归验证门也更清晰。

Section 07

内部机制

本节深入介绍 --deep--tdd 在 plan 阶段、cook 阶段的具体影响,以及运行成本。

7.1 --deep 更贵:researcher + 按阶段 scout

ModeResearcherRed TeamValidation按 phase Scout
--fast000No
--hard2YesOptionalNo
--deep2-3YesYesYes
--parallel2YesOptionalNo
--two2+选定后选定后No

--deep 的成本主要来自:2-3 个 researcher 做高层架构分析、red-team review、validation 步骤,以及按每个 phase 重新过一遍。

简单说,每个 phase 在 plan 最终确定前都会被单独审视:这个 phase 涉及哪些文件、依赖哪个 phase、还缺哪些测试、有没有容易遗漏的边界条件。

需要避免的误解:这里说的"scout"指的是按 phase 读取和复查的过程,不是承诺每次运行都会启动一个独立 agent。重要的是 --deep 强制 plan 经过更多轮次的小检查,而不是只在总览层面看一次 scope。

7.2 --tdd 不会启动新的 agent

容易误解的地方:--tdd 不会改变已选的 mode。它是一个附加 flag:你仍然照常跑 --fast--hard--deep,只是加了 tests-first 的结构。

这个 flag 只改变 2 件事

  • plan 阶段的 phase 文件。 普通 phase 有 overview、要求、架构、相关文件、实现步骤、成功标准、风险评估。打开 --tdd 后,phase 会额外包含:重构前的测试、重构后的测试和阶段末验证门。
  • cook 阶段的执行顺序。 先写保护旧行为的测试,再重构,然后重跑 compile/test 验证门。

--tdd 的成本远低于 --deep。它主要是在 phase 文件里加结构,并改变 cook 的执行顺序。

7.3 Regression Gate 需要具体的 command

cook spec 要求 Regression Gate 是具体的 compile/test 命令。以 Go 项目为例:

regression gate
Regression Gate: go test ./... && go vet ./...

如果 phase 文件写得模糊,比如"run tests to verify",验证步骤就会变弱,因为 cook 没有精确命令可以执行。--tdd flag 不能保证在每个 repo 里都猜对工具。如果项目使用特殊命令,应该在 task description 或 plan 文件里明确写出。

tooling hint
Project 用 go test ./...,前端用 npm test,E2E 用 Playwright。

task 中明确了 tooling,plan 才有依据为每个 phase 写出正确的 Regression Gate。

Section 08

怎么跑和通用模板

以下模板基于 ck:planck:cook 的 source skill:plan 接受 task + mode/flag,cook 接受 plan path,如果 plan 已开启 --tdd,cook 也需要保留该 flag。

通用模板

general template
/ck:plan [mode] [--tdd] "[要做的事情].
范围:[涉及的 module/file/stack].
保持不变:[API 契约、旧行为、兼容性].
涉及:[database、job、route、UI、shared type].
Tooling:[具体的 compile/test 命令].
已知 bug / 不在 scope 内:[如有]."

注意:如果 plan 用了 --tdd,运行 cook 时也需要加 --tdd

cook command
/ck:cook /absolute/path/to/plan.md --tdd

将模板套用到几种常见场景:

--deep 用于 planning/inventory 阶段

deep only
/ck:plan --deep "制作 inventory plan,为把 billing 模块拆成独立包做准备。
Scope:API routes、invoice service、payment jobs、Admin UI、database schema。
需要输出:文件清单、依赖图、phase 所有权、风险列表。
本轮不重构正在运行的行为。"

--hard --tdd 用于重构正在运行/dogfood 的代码

hard + tdd
/ck:plan --hard --tdd "重构 invoiceStatusService:将 transition rules
拆到单独文件,保留 retry、failed、refunded、voided 的精确行为。"

--deep --tdd 用于有需要保留行为的大型重构

deep + tdd
/ck:plan --deep --tdd "把 billing 模块从单体应用里拆出来。
保留前端 API 契约,保留 retry/幂等性/退款/webhook 行为。
涉及:database schema、payment jobs、API routes、Admin UI。
Project 用 go test ./...,前端用 npm test。"

好的 task description 通常包含:

  • 范围:涉及哪些 file/module/stack
  • 约束:不能破坏什么、需要保持哪些兼容性
  • Tooling:test 命令、compile 命令,对 --tdd 尤其重要
  • 期望结果:简洁但具体

过于模糊的输入,比如 "refactor billing",只会产出模糊的 plan。scout 没有具体锚点,输出很容易流于泛泛。

Section 09

最佳实践与常见陷阱

cook 之前应该做的

Scope

plan 之前清理 worktree

如果工作目录有其他任务的未提交改动,scout 容易把当前代码和进行中的代码混淆。大型 plan 之前:commit 或 stash。更好的办法是通过 /ck:worktree 创建独立的 worktree。

Review

cook 之前先 review phase 文件

--deep --tdd plan 跑起来比较耗时,所以在没有读完 plan.md 和各 phase 文件之前,不要直接跑 cook。

Phase review checklist

用以下 5 个问题读完 plan.md 和各 phase 文件,然后再让 cook 跑:

文件清单有没有不想让 agent 改动的文件?
测试场景矩阵有没有遗漏 race condition 或边界条件,比如重复 webhook?
Phase 顺序各阶段真的独立吗,还是 migration 必须先于 job?
Regression Gate工具和测试子集是否正确?
已知 bug需要修复,还是需要保留旧行为?
Tooling

在 task 里声明 test 命令

使用 --tdd 时,如果 repo 用了特殊工具,比如 bun 替代 npmmise 替代 asdftask 替代 make,请直接声明。

tooling hint
Project 用 go test ./...,前端用 npm test,E2E 用 Playwright。

不声明的话 agent 会猜。猜错命令会让 Regression Gate 变弱。

Context

plan 和 cook 之间用 /clear

大型任务的 plan context 通常很重:research 输出、scout 数据、red-team 反馈。推荐流程:plan 完成 -> /clear -> 重新打开 -> /ck:cook {absolute-path}/plan.md --tdd。cook 会从 plan 文件重新读取,不需要旧的 planning context。

需要避免的

Cook flag

/ck:cook 漏写 --tdd

plan 有 --tdd,cook 没有 -> cook 仍然能读到"重构前测试"的部分,但不会强制执行"先写测试再重构"的顺序。测试可能仍然被写,只是写在代码之后。应该使用 plan 输出里建议的 cook 命令。

Overkill

小任务用 --deep

涉及文件不超过约 5 个时通常不需要。用 --hard--fast 更简洁。

Greenfield

greenfield 代码用 --tdd

新代码没有现有行为可以记录。"重构前测试"部分几乎为空,agent 容易写出形式化的测试而不是真正的 TDD。Greenfield 用 --hard,让测试按正常流程写。

Blind spot

过度信任 phase 文件

--deep scout 更仔细,但仍然可能遗漏隐式依赖。cook 之前应该自问:后续 phase 是否隐式依赖前面 phase 还没创建的东西?

Known bug

--tdd 把已有 bug 记录成"行为"

旧 billing 代码有潜在 bug,比如重复 webhook 偶尔会创建 2 条 payment attempt。如果重构前的测试把 bug 也记录成"当前行为",重构时意外修复了 bug 就会导致验证门失败,agent 可能反而把代码改回有 bug 的状态。解决方案:在 task 里声明已知 bug,或者拆成两个 plan:plan 1 修 bug,plan 2 重构。

Mode mix

强行把 --deep--parallel 组合

--deep--parallel 都是 mode,不能互相组合。如果需要多个 agent 并行跑,用 --parallel --tdd,并把 ownership 和 test scope 划分清楚。如果不确定 ownership 和 test isolation,放弃 --parallel,保留 --deep --tdd

Section 10

总结

--deep --tdd 不适合所有任务。

它适合同时具备以下两个特征的任务:

  1. scope 足够大,普通 plan 容易缺少地图
  2. 现有代码有需要在重构后保留的行为

--deep 让 planning 变慢,但换来更具体的 phase 文件:文件清单、test 缺口、依赖图、函数/接口检查清单。

--tdd 让 cook 变慢,但换来重构有回归验证门:先写测试、再重构、再验证。

如果你是 PM/founder/产品,只需要知道这两个选项的存在。当团队准备重构大模块(比如 billing)时,问一下 plan 里有没有按阶段 scout 和回归验证门。

如果你是开发者,在下一个大任务里试试。第一次可能会觉得多花了时间。但只要有一次"重构前测试"发现了隐性回归,这点成本就很容易接受。