← 返回文章选择

给长任务留下可接手的状态

长任务最怕人在忙、事没动:写清结束条件,交接留下事实,检查要能指导下一步。

我的长任务复盘里有一句:“人在活动 ≠ 任务在前进。”旁边记着三样东西:过密的进度报告、阶段切换、越来越多的验收词汇。继续发消息、加检查项、把计划拆得更细,都能占满时间,交付物却未必离可用更近一步。

开始时就写清什么叫结束

任务开头要写下五样东西:结果、验证依据、约束、边界、停止条件。有了它们,后面才判断得了工作有没有跑偏。交付一个功能,结束条件要对应用户能执行的行为,“完善实现”不算。

这五样和 Claude Code 官方最佳实践对 spec 的要求几乎一一对上:好的 spec 是自包含的,点名涉及的文件和接口,写明什么不在范围内,最后以一个端到端的验证步骤收尾。同一页还建议先让模型反过来采访你,把 spec 写完,再新开一个 session 去执行。这一步本身就是一次交接。

中途发现新的限制,就回去改这份约定。否则最初的目标在一处,后来的纠正散在聊天里,执行者手上其实是两份不同的要求。

验收用词也要固定。实现完成、测试通过、交付可用各指什么,写在同一处。交接时写下的检查结论,接手的人才不用猜它按的是哪套标准。

这其实就是 Scrum 里 Definition of Done 想解决的问题:给所有人一份“什么算做完”的共同理解,没达到的条目不能发布,连在评审会上展示都不行。借一个现成的说法,比自己造词好沟通。

交接材料要能让人从头接上

长任务跨阶段时,不管是压缩上下文还是新开 session,下一阶段都要拿到当前事实:

  • 已有产物在哪里;
  • 哪些检查真正执行过;
  • 还有哪些没完成;
  • 下一步需要什么输入。

下面是按原页阶段关系整理的图,我补上了判断和返回分支,方便说明流程;它不是哪个 Agent 产品的内部实现。

阶段交接流程,含失败修正、状态保存和下一阶段判断

查看 Mermaid 源码
flowchart TD
goal["目标、范围和验收条件"] --> phase["执行当前阶段"]
phase --> artifact["交付物和验证记录"]
artifact --> check{"本阶段满足条件?"}
check -->|否| revise["记录失败原因并修正"]
revise --> phase
check -->|是| state["保存当前状态与未完成项"]
state --> next{"还有下一阶段?"}
next -->|有| phase
next -->|无| delivery["交付最终结果"]

只留一段“已经做了很多工作”的摘要,接手的人还得重新搜集事实。框架的默认做法反而是给全量:OpenAI Agents SDK 的 handoff 转给新 Agent 后,它能看到之前的整段对话历史,想裁剪得自己写 input_filter。所以交接写多写少,是一个要自己做的取舍。状态文档可以更短,但要有能定位产物的路径、实际检查结果和还存在的问题。

压缩上下文或换 session 之后,别假定旧对话还完整地在那儿,交接材料得自己站得住。我对 Ralph loop 的记录也停在这一点:重开上下文时,工作状态必须留在可读取的材料里。

Ralph 是这条规则最极端的样本

Geoffrey Huntley 的原文里,Ralph 就是一行 shell 循环:

Terminal window
while :; do cat PROMPT.md | claude-code ; done

每一轮都是新的上下文窗口,模型什么都不记得。能接上的,全靠每轮固定喂进去的计划文件 fix_plan.md 和规格目录 specifications/,作者的说法是“每一轮用同样的方式确定性地分配栈”。他也写了它怎么坏:时不时醒来发现仓库编译不过,TODO 做完以后空转。他自己的总结是 “deterministically bad in an undeterministic world”。循环跑偏时,只能靠人判断是重置还是抢救,这正是停止条件要提前写好的原因。

Anthropic 的上下文工程文章把长任务的做法归成三类:压缩、结构化笔记、多 Agent。它点名了压缩的代价:

the loss of subtle but critical context whose importance only becomes apparent later

外部笔记,也就是 Agent 把状态写到上下文之外的文件、之后再读回来,是它列出的正式技术之一。压缩有损,所以状态要另外落盘。

子任务值得拆,前提是输入输出说得清

复盘里提到,把一个 Agent 放在需要了解太多信息的位置,会加重交接负担。能独立完成的任务,要讲清输入、交付和失败边界。这样它失败了,主流程知道哪里没完成,再决定重试、换方案还是停下。

拆分本身也有成本:子任务一多,解释背景、检查结果、协调状态的活都跟着变多,拆不拆要看收益。笔记末尾我特意记了一句“进度变慢也不要乱派 subagent”。它和“大 plan 带来虚假确定性”可以放在一起看:拆分只有在责任和结果更清楚时才有用。

拆分贵多少

这个成本有官方的量级。Anthropic 介绍自家多 Agent 研究系统时说,Agent 任务大约用掉聊天 4 倍的 token,多 Agent 系统约 15 倍。收益也是真的:Opus 4 主 Agent 加 Sonnet 4 子 Agent,在内部研究评测上比单个 Opus 4 高 90.2%。但同一篇也承认,多数编码任务真正能并行的部分比研究少,Agent 之间依赖多的任务目前不适合这么拆。

Cognition 的 Don’t Build Multi-Agents 站得更远,默认就用单线程。它的两条原则是共享完整的执行轨迹而不只是消息,以及“行动里带着隐含的决定,决定冲突就出坏结果”。例子很好记:两个子 Agent 分头做 Flappy Bird,一个把背景做成了超级马里奥的样子,另一个把鸟做错了,主 Agent 只能把两处误解拼在一起。

信息给太多会加重交接负担,给太少又各自脑补。Claude Code 的子 Agent 默认就是后一种处境:每个子 Agent 开一个隔离的新上下文,看不到你的对话历史,也看不到主会话已经读过的文件;文档同时提醒,很多子 Agent 各自带回详细结果,会大量占用主上下文。Ralph 的作者也限制并行,跑构建和测试只放一个子 Agent,否则几百个同时跑测试会造成反压。这些都可以拿来解释我那句“进度变慢也不要乱派 subagent”。

每一步检查都要能指导下一步

笔记里的测试流水线把几个角色分开:

  1. Specifier 先写验收场景;
  2. Coder 按场景生成实现;
  3. Cleaner 做审查和清理;
  4. Hardener 补针对性测试;
  5. QA 回到原来的验收标准做回归。

原方案在 Cleaner 和 Hardener 之间还有一个 Architect,我这里省掉了。这是一种职责划分的思路,实际用多少角色,要看任务和协作成本。

其中两棒值得多说一句。Specifier 写的场景,可以照 Gherkin 官方参考的尺寸来:每个例子建议 3–5 步,Then 只验证外部看得到的结果,实现细节藏进 step definitions。这和前面“结束条件要对应用户能执行的行为”是一回事。Hardener 那一步用的是变异测试:按 Stryker 文档的定义,工具自动往代码里插故障(变异体),重跑测试,测试挂了就算杀掉,测试还过就是存活。补的针对性测试,就是去杀那些存活的变异体,这比覆盖率数字更能说明测试有没有用。下面按这条流水线重画,保留了人工定义验收和最终回归之间的关系。

从需求到回归的测试流水线,人工标准贯穿验收

查看 Mermaid 源码
flowchart TD
need["需求与 PRD"] --> specifier["Specifier:场景与 Gherkin"]
specifier --> human["人工确认 QA 标准"]
human --> coder["Coder:按场景实现"]
coder --> cleaner["Cleaner:审查与清理"]
cleaner --> hardener["Hardener:变异测试与补充测试"]
hardener --> qa["QA Agent:回归验收场景"]
human -.->|提供验收依据| qa

按图的划分,人工出现在两个位置:定义阶段确认 QA 标准,回归阶段提供验收依据。所以回归对照的,始终是人工定下的那套标准。

这套分工要的是每一步的产出下一步能直接用:测试失败能指到具体问题,进度报告里的内容够判断该等待、干预还是交付。一条只写“继续处理中”的报告,读的人拿不到新状态,也就没法决定下一步。

Claude Code 的最佳实践把这件事写成了第一条:给 Agent 一个它能自己跑的检查,测试、构建或一张可对比的截图都行,并且要它拿出证据,而不是宣布成功,比如跑了什么命令、返回了什么。同一页还给了止损线:同一个问题纠正超过两次,就 /clear 重开。

这条流水线有个开源实现(gauntlet),把这点做成了硬规则:每个阶段要交一张“要求 → 证据”表,比如场景对应哪条测试、文件的变异测试结果、QA 每一步的判定;缺表或有没解释的空缺,就退回这一阶段。编排器在每道关卡后写一个 state.json,同一分支重跑时从第一个没通过的阶段接上。证据表加状态文件,正好是前面说的交接材料该有的样子。

留下几句话 读者来信

读到这里,有什么想法?欢迎留下你的看法。