Project 08. 把你的工作流画成一张图
相关讲义:L14. 从单循环到图工程
你要做什么
这是从 "Loop" 到 "Graph" 的跃迁项目。上一讲你搭了一个 maker-checker loop——实现、验证、反馈、再实现,所有决策都发生在同一个 agent 的上下文窗口里。这一讲你要做的,是把藏在循环里的结构显式地画出来:节点、边、共享状态、路由规则,一个字一个字地写清楚。
你会做三个递进的实验:先把 P07 的 maker-checker loop 画成一张显式图,再给图加一个并行 fan-out/fan-in 节点,最后加一条条件回退边和一个人工审批节点。做完你会亲身感受到一件事:图不是新发明,是当你的 loop 复杂到一定程度后,它自己变成的样子。
用什么工具
- Claude Code 或 Codex
- Git
- 你在 P07 搭好的 maker-checker loop(或任何一个你能反复跑的 agent 工作流)
- 一个文本编辑器或绘图工具(画图不是为了好看,是为了把结构写清楚;
mermaid或手写graph.md都行)
具体步骤
准备工作
- 从 P07 完成后的仓库出发,或者直接用你正在跑的任何 agent 工作流。
- 创建三个分支:
p08-explicit-graph、p08-parallel、p08-human-in-the-loop。 - 准备一个
state.md作为共享状态文件:需求、进度、验证结果都写在这里。这是图的"公共工作台"。
实验一:把 Loop 画成显式图
切到 p08-explicit-graph 分支。
- 列出所有节点:把 P07 maker-checker loop 里的每一步写成一个节点。每个节点写清楚:它的职责、它的输入、它的输出、它是 agent 还是确定性代码。
- 画出所有边:列出节点之间的每一条边。重点标注两条特殊边:
- 条件边:验证通过/失败,走哪条
- 回退边:失败回到哪个节点
- 写共享状态:明确列出状态里有哪些字段(需求、代码、测试结果、审查结论),谁读谁写。
- 写路由规则:用最简单的 if-then 语言写下"下一步去哪"的规则,比如:
if 验证通过 → 合并节点 if 验证失败 → 实现节点 if 实现节点信息不足 → 研究节点 - 写成
graph.md:把以上内容整理成一份文档。用 mermaid 画一张图,附上节点表和路由规则。 - 回答这个问题:画完之后,找出至少一条原来是隐式的边——以前藏在 agent 上下文里、你自己都不知道它存在的决策路径。
实验二:加一个并行 Fan-out / Fan-in 节点
切到 p08-parallel 分支。
- 选一个可以并行的点:找任务里一个可以拆成两个独立部分的地方。比如:
- 实现拆成两个独立模块,两个 agent 并行写
- 验证拆成两个独立审查:一个跑测试和 lint,一个做代码审查(不同的指令、不同的关注点)
- 研究拆成两个方向,两个 agent 各查一路
- 写 fan-out 规则:共享状态里记录"这个任务被拆成 N 个并行子任务",每个子任务一个独立的 context、一个独立的节点。
- 写 fan-in 规则:所有子任务完成后,谁来合并结果?合并的标准是什么(比如:两个审查都通过才合并,还是有一个通过就行)?
- 用 worktree 隔离:每个并行子任务在独立的 git worktree 里跑,物理上避免文件碰撞(回顾第十三讲的 Worktree 原语)。
- 跑一次并记录:记录并行前后 wall-clock 时间、token 消耗、结果质量。并行真的更快吗?还是协调开销吃掉了省下的时间?
实验三:加一条回退边和一个人工审批节点
切到 p08-human-in-the-loop 分支。
这是三个实验里最重要的一个。你要在图上加两种节点:
- 条件回退边:给验证节点加一条"部分通过"的路径——不是全盘打回实现节点,而是带着具体反馈回到产生问题的那个节点。比如:测试全过但代码审查发现需求理解有误,回退到研究节点而不是实现节点。这要求你的共享状态里记录"问题出在哪一层"。
- 人工审批节点(Human-in-the-loop):在合并节点之前加一个人工节点。走到这里,图停下来,等你在
state.md里写"批准"或"打回"。审批节点可以有一个超时规则:N 小时后没响应,自动打回或自动升级。 - 写 interrupt 的格式:审批请求怎么写清楚——发生了什么、改了什么、为什么需要人、批准/打回的后果各是什么。
- 跑至少 2 轮完整流程:每一轮都走到人工审批节点,你自己批准或打回一次。记录:你的审批决策和验证节点的判断一致吗?审批节点拦住过什么验证节点没拦住的吗?
怎么衡量结果
| 指标 | 实验一(显式图) | 实验二(并行) | 实验三(人机协同) |
|---|---|---|---|
| 结构可见性 | 找出了几条隐式边? | 共享状态能否支撑并行子任务? | 回退边能否精确定位问题层? |
| 失败定位 | 失败时能否直接指出是哪条边错了? | 并行子任务失败时,能定位到哪一个? | 审批打回时,能指出是哪一层的问题吗? |
| 协作开销 | 写图花了多久? | 并行省下的时间 vs 协调开销 | 审批等待时间 vs 拦住的问题价值 |
| 可观测性 | 每一步发生了什么,现在看得见了吗? | 每个并行子任务的状态可见吗? | 审批请求写得够清楚吗? |
| 可靠性 | 图描述和实际运行一致吗? | fan-in 合并标准靠谱吗? | 超时/升级规则真的会触发吗? |
要交什么
graph.md(实验一的完整图描述:mermaid 图 + 节点表 + 边表 + 共享状态字段 + 路由规则)- 实验一发现的隐式边清单(至少一条)
- 实验二的 fan-out/fan-in 规则和一次并行运行记录(时间/成本/质量对比)
- 实验三的回退边规则、审批节点格式和 2 轮人机协同记录
- 最终复盘:从 loop 到 graph,你的工作方式发生了什么变化?哪些任务值得画图,哪些不值得?
对应讲义
- Lecture 14 — 从单循环到图工程
- Lecture 13 — 从手动驱动到自动循环(你的 loop 就是图里的一个节点;这个项目是把节点的内部结构摊开)
- Lecture 09 — 为什么 agent 会提前宣告完成(验证节点为什么必须独立于实现节点,在图中是结构问题)
- Lecture 11 — 为什么可观测性属于 harness 的一部分(图越复杂,越需要看到每个节点在做什么)