需求阶段交出来的是一份 spec、一份决定记录和一个固定的代码基线。设计阶段拿着这三样东西做两件事:写出技术方案,再把方案拆成一组开发任务。
开发阶段由多个子 agent 并行执行这些任务。每个子 agent 只看得到派给它的那个任务,看不到设计阶段的对话,也看不到别的任务。所以设计阶段的目标就一条:开发时不需要猜。
本篇讲六件事:
- 设计阶段读什么、交出什么;
- 架构问题怎么问,Agent 想多做的东西怎么拦住;
- 技术方案文档怎么写,为什么只生成一次、由人来审;
- 任务怎么拆,每个任务要写清什么,以及 Claude Code 和 Codex 的子 agent 启动时能看到什么;
- 任务说明怎么编译成任务图,开发时怎么调度;
- 缺资料时怎么办,方案和开发范围怎么确认。
其中一处是我们踩过的坑:早期在设计阶段内跑独立评审和多轮自审,阶段内一出现循环就非常耗时,后来改成方案只生成一次、由人来审。
设计阶段读什么、谁来做、交出什么

设计阶段的输入全部来自需求阶段的交接:spec、决定记录、仓库和代码基线,以及还在对齐中的延期项。
做事的仍是主 Agent。它加载设计阶段的主 skill,再按需调用一个专门负责写方案、拆任务的 skill,并按这次选定的平台读对应的编码规范。
这个阶段不做三件事:不重做需求,不写生产代码,不跑构建和测试。
必须交出七份文件:
- 实现方案:整体怎么做,风险越高写得越细;
- 决定记录:设计阶段定下来的架构决定和延期项;
- 技术方案文档:每个模块一份,按固定模板写,给人审;
- 测试意图:每条验收对应哪些测试,测试怎么写;
- 任务说明(tasks.md):给人读的任务列表;
- 任务图:由任务说明编译出来,开发阶段按它调度;
- 交接文件:引用以上所有文件,加上代码基线、风险、阻塞项和开发授权。
另外几份按情况生成。验收需要模拟接口状态时,记录用哪些本地数据。架构约束多的复杂目标,额外冻结一份架构约定,写明角色、负责人、公开签名和依赖方向,开发阶段直接用,不重新推导。
架构问题沿用需求阶段的澄清方法
设计阶段也有要问人的问题,问法和第 03 篇一样:先查后问;有依赖的一次问一个,互不依赖的合并成一轮,最多 3 个;每题带依据和推荐。
区别在问什么。需求阶段问的是各方资料之间的分歧,设计阶段问的是架构判断。交给人的只有六类:会改变业务结果的,改变架构边界的,改变仓库范围的,涉及兼容策略的,需要接受风险的,要写外部系统的。
有一类容易漏掉。有些内部实现看起来只是技术细节,但改变了请求的等待、完成或通知顺序,改变了取消的效果,或者决定了结果是否交给用户。这类也算设计决定,要问。
文件路径、类型名、检查命令不问,由代码和规范推导。
问完写决定记录。设计阶段的决定记录专门记约束代码形态的事:
- 状态和生命周期由谁负责;
- 运行时的依赖方向;
- 对象怎么构造、怎么注入;
- 并发和取消怎么处理;
- 新旧实现怎么替换。
每条写决定、理由、影响的约定、替代了哪条旧决定、涉及哪些仓库和证据。开发者确认之后才写,写入后只追加,不修改。
Agent 想多做的东西,先停下来单独问
写方案时,需求之外的内容也可能被带进来:预留以后可能用到的能力,抽一个通用基类,加一层兼容,顺便重构,优化性能,补监控,升级组件。
这些可能都有道理,但不在这次需求里。设计阶段的规则是:出现这类内容时,先暂停这个分支,向开发者说明新增什么、收益、成本、风险,以及对这次交付的影响,单独问要不要纳入。确认之前只记成「范围外候选」,不进方案、任务和写入范围。
方案里新增的东西也要找得到依据:
- 新增一个类、接口或配置项,要说清谁负责它、谁用它、为什么不能并入已有的类型;
- 新增空值兜底、重试、降级这类防御分支,要说清风险从哪来、什么情况会触发、用哪条测试覆盖;
- 为扩展性新增抽象层,要有第二个真实场景或明确的近期计划,否则只记成未来候选。
如果发现的是更大的变化,比如要改的仓库、接口或验收标准变了,设计阶段不自己扩,退回需求阶段重新确认。
技术方案文档写什么:五部分内容、四张图、每条验收由哪里实现和怎么测

技术方案文档是给开发者审的那份方案,每个模块写一份。内容按团队的固定模板分五部分:
- 这次要做什么、不做什么、怎样算验收通过;
- 依据的事实和约束:哪个仓库、哪个提交、已有的实现;
- 设计决定:复用哪些组件,谁负责什么,对外的接口和签名,状态怎么变化,调用顺序;
- 实现和任务:改哪些文件,任务之间的依赖;
- 验证和风险:要跑哪些测试,还有哪些没验证、什么情况会挡住开发。
文档里还要画四张 Mermaid 图,两张讲结构,两张讲流程:
- 架构图:模块边界和依赖方向;
- 类关系图:真实的类型、接口之间谁调用谁、谁持有谁;
- 主流程时序图:从用户触发到看到结果,中间的调用和状态变化;
- 异常时序图:失败、取消、超时或结果晚到时怎么处理、怎么恢复。
图里的参与者和调用必须来自现有代码或已确认的设计,不能为了把图画完整而添加机制。简单的改动确实用不上某张图,要写明原因和依据;资料不够不算不适用。
文档最后是一张验收对照表,把 spec 里的每条验收逐条列出来,写明三件事:在设计里由哪部分实现,用哪条测试验证,现在是什么状态。设计阶段测试还没跑,状态只能写「待验证」。这张表保证每条验收都有对应的设计和测试,拆任务时不会漏掉。
写完后 Agent 按清单自查:只有一个一级标题,没有未替换的占位符,四张图齐全,验收对照表列全了每条验收、没有空格子。缺了就自己补,补完再查一遍,不为这些问人。
开发者确认方案之后,技术方案文档默认发到团队的文档平台,链接返回给开发者。
方案只生成一次,由人来审

踩过的坑:阶段内的评审循环
早期的设计阶段里有独立评审和多轮自审:Agent 生成方案,评审 agent 挑问题,Agent 修改,再审一轮。
问题是太慢:阶段内一旦有循环,就非常耗时。后来把它去掉了,尽量让人来审。
现在的做法:
- 技术方案一次生成(oneshot),不另起独立评审,也不多轮自审;
- 方案好不好由人判断:开发者审这次生成的方案质量如何;
- 人审发现的问题,用来提高之后一次生成的质量,不在这次交付里多跑几轮。
上一节的自查清单不是评审循环。它只查机械问题:缺图、表格格式坏了、对照表漏了某条验收。这些对照清单就能补,有进展就继续,不设固定次数,也不判断方案本身好不好。
自动检查通过、Agent 自审、开发者没有回复,都不算方案确认。确认只来自开发者的明确回答,做法见最后一节。
人审出来的问题怎么沉淀回去、让下一次生成更好,放到第 11 篇讲。
按业务行为拆任务

方案回答的是怎么做,任务回答的是由谁做、按什么顺序做。
先说背景。我们做移动端开发,一个需求通常要同时改 Android 和 iOS 两端,两端的技术栈不同。所以最顺手的拆法是按端拆:Android 一个任务,iOS 一个任务。再细一点,每端按层拆:数据、逻辑、UI 各一个任务。
这两种拆法的问题都出在验证上:
- 按端拆,一个任务包了这一端的全部改动,「完成 Android 端」做没做完,只能等整端写完一起看;
- 按层拆,数据层、逻辑层单独做完,跑不出用户能看到的结果,验证不了任何一个业务行为。
设计阶段的拆法是先列出这次要实现的可观察业务行为:用户做了什么,系统给出什么结果,包括正常情况、异常情况和需要保护的已有行为。然后判断哪些行为能独立实现、独立验证,最后才对应到端、代码分层和文件。
一个任务仍然只属于一个仓库、一个端,但它实现的是一个具体行为,比如「Android 上取消超时未支付的订单」,而不是「Android 端的全部改动」。任务内部沿用代码已有的分层,不为每个行为单独复制一套数据、逻辑、UI。两端都做完才能看的联合验证,放在单独的验证环节,不作为每个任务的开工条件。
每个任务要能判断做没做完。「实现模块」「完成整端 UI」「完善异常处理」这类描述判断不了,不能用。
一个合格的任务描述,用一个通用的例子:
取消超时未支付的订单。只改订单状态相关的文件和对应测试;依赖已经确认的超时事件格式;重复收到同一事件时只处理一次。覆盖四种场景:已超时、未到时间、重复事件、已经支付。用订单相关的定向测试验证,四种场景通过、原有支付行为不受影响才算完成。
合并任务有明确条件:两个行为共同维护一份拆不开的状态,或者是一次破坏性的接口迁移,或者拆开后没有单独验证的价值。合并要在方案里写理由。同一个页面、同一个文件、同一个负责人,都不自动等于一个任务。
依赖也要写理由:这个任务用到上游任务的什么产物,用在哪个行为上,为什么必须先完成。同层、同页面、排期方便,都不算依赖。
每个任务写清楚:开发子 agent 只看得到任务本身

每个任务除了文字描述,还有一个机器能读的 YAML 块:
yaml
id: T003
title: 取消超时未支付的订单
repository: <仓库>
depends_on: [T001]
owner: coder # 实现角色
read_refs: # 开工前要读的文件
- <spec 中对应的验收>
- <方案中对应的章节>
- <目标目录适用的规则文件>
write_scope: # 允许修改的已有文件
- <订单状态文件>
- <对应的测试文件>
create_scope: [] # 允许新建的文件,没有也写空列表
done_when:
- 四种场景按预期处理,原有支付行为不变
verify:
- <只跑这个任务相关测试的命令>
case_ids: [<对应的测试意图编号>]
写得这么全,是因为开发子 agent 拿不到设计阶段的上下文。
Claude Code 的子 agent 在独立的上下文窗口里启动,看不到主对话的历史,也看不到主 agent 调用过的 skill 和读过的文件。它拿到的主要是这几样:自己的角色说明,主 agent 写给它的任务消息,各层 CLAUDE.md 和作为项目指令加载的 AGENTS.md,仓库的 git 状态,角色定义里预加载的 skill。例外是 fork:fork 出来的子 agent 带着整个对话启动。我们派给实现、评审、测试这几个自定义角色时,用的是普通派发,不是 fork。
Codex 的 spawn_agent 也有对应的开关。目前默认开启的第一版多 agent 里,fork_context 默认关闭,子 agent 不带父会话历史。第二版多 agent 默认没开,开了之后,不写 fork_turns 就会带上父会话的全部历史,要显式写成 none。我们的项目用的是第一版。
我们的派发规则和这两个默认值一致:执行者只拿到自己的任务、写入范围、必要的规则、要读的文件和结果要求,不继承父会话,也不看其他任务。父 agent 读过的文件,子 agent 等于没读过,所以要读的都列进任务的读取清单,由子 agent 自己去读。
任务里没写的信息,子 agent 要么回来问,要么自己猜,所以要在设计阶段写全。
测试意图也在设计阶段写好,放在单独的文件里,任务按编号引用。每条测试意图写:
- given / when / then:前置条件、触发动作、预期结果;
- 实现前为什么必须失败:先写测试、确认它失败,再写实现;
- 优先级:测试团队用例里的 P0、P1 保持原优先级,必须执行。
验收需要可控的接口状态时,先复用已有的本地模拟数据。新建或修改远端 Mock 属于外部写入,要单独授权。
任务说明编译成任务图:CLI 只检查顺序

任务说明 tasks.md 是给人读的。文件里有一个任务图的头部块,写仓库、基线和必须完成的终点任务;每个任务再各有一个 YAML 块。任务图由 CLI 从这份文件编译生成,不手写,也不从聊天记录里补任务。
CLI 编译时只在顺序不确定时报错,具体是三种情况:
- 任务编号重复;
- 依赖了不存在的任务;
- 依赖成环。
两个任务的写入范围重叠,只给警告,不报错,调度时让这两个任务先后执行。
开发阶段按任务图调度。一个任务能开始,要同时满足三个条件:
- 它依赖的任务都已完成;
- 它的写入范围和正在执行的任务不重叠;
- 同时执行的数量没有超过上限。
上限默认是 3 个,写在配置里。每个任务的负责角色决定派给哪个子 agent,角色定义只写一份,同步到两个宿主,做法见第 01 篇。
CLI 读任务图时只用编号、标题、依赖、仓库、写入和新建范围、完成条件、负责角色这几项,其余字段都不检查。任务拆得对不对、描述够不够清楚、验证命令选得对不对,由 Agent 按方法写、开发者审。这和第 02 篇讲的分工一致:CLI 管结构和顺序,不管语义。
资料不全时:受影响的任务暂停,其他任务照常开发
设计阶段可能缺资料,比如接口协议还没给,某个状态的设计稿没有,文案还没定。
缺的资料记进缺口清单,每条写清:缺什么,谁负责补,影响哪些任务,补到什么程度算齐。受影响的任务和依赖它们的任务暂停,其他任务照常进入开发。
如果一个缺口只影响某个任务里的一部分功能,先把这个任务拆开,没受影响的部分照常开发。
有两类东西要区分开:
- 写代码前必须有的:业务规则,必需的设计稿属性和素材。缺了,对应的任务暂停;
- 写完代码才拿得到的:真机上的显示效果,线上的实际跳转。这些在开发和验证阶段产生,设计阶段不要求先拿到。
一个真实的例子:
- 一个前端需求要用后端的新接口,接口的新字段、开关和数据上报约定都还没定,负责人也没指定;
- 4 个任务都要用这个接口,全部暂停;
- 方案和四张图照常写完,9 条验收都写明了由哪里实现、用哪条测试验证,15 条测试意图也写好了;
- Agent 列了一份 21 项的材料清单,交给后端和合作方的负责人;
- 没有请求开发授权。
材料补齐后,Agent 核对材料,补全受影响的任务,重新编译任务图,再请开发者确认方案和开发范围。
方案和开发范围一次确认
方案写完、任务图编译通过后,主 Agent 一次展示给开发者:
- 一两句话的实现思路和主要风险;
- 每个模块技术方案的链接,每份附一句说明;
- 任务安排:先后顺序、依赖、哪些可以并行;
- 验证方式和遗留问题,还没执行的测试写「待验证」;
- 允许修改的范围,逐个仓库列出;
- 代码基线和开发位置(独立的 Git worktree,或已确认的工程目录)。
然后给三个选项:按方案开发,调整方案,暂不开发。问法沿用第 03 篇讲的宿主提问工具。
两条规则:
- 展示里必须列出开发范围,只说「方案没问题」不算开发授权;
- 确认的是任务图内的写入、隔离的工作副本和声明过的本地检查。接口同步、新建远端 Mock 这类外部写入另外授权。
一次真实的确认里,开发者的回答是「确认,按此方案开始开发并完成本地检查」,并要求保留已确认的需求和固定基线。记下来的授权范围是任务图内的写入、隔离工作副本、声明过的本地检查,外部动作一项都没有授权。
回答的原话写进决定记录和交接文件。已经有效的确认不重复问;Agent 补文档里的遗漏,不为同样的内容再问一次。
交给开发阶段的东西
设计阶段交出去的是:一份经人审过的技术方案,一张编译通过的任务图,图内的开发授权,以及每个缺口的负责人和解除条件。
回看整个阶段,Agent 负责查和写:查代码和规范,写方案和任务,按清单自查格式。人负责判断:架构决定,范围外的东西要不要做,方案质量够不够。
下一篇讲开发:多个子 agent 怎样按这张任务图并行执行。