LEARN CLAUDE CODE
S03: TodoWrite — 让 Agent 学会做计划
这一课解决什么问题
让 Agent 做一个多步骤任务(比如「重构这 5 个文件并更新测试」),它经常做到第 3 步就忘了第 1 步是什么,或者跳过中间步骤直接去做最后一步。模型没有「计划」的概念——它只是在每一轮预测下一个最可能的 token。
人类做复杂任务会列清单、划掉做完的、标记正在做的。S03 就是给 Agent 装一个这样的清单系统。
核心机制
┌─────────────── TodoManager ───────────────┐
│ │
│ todos = [ │
│ {id:1, task:"读取文件结构", │
│ status:"completed" ✓}, │
│ {id:2, task:"重构 auth 模块", │
│ status:"in_progress" ⚡}, │
│ {id:3, task:"更新测试", │
│ status:"pending" ○}, │
│ {id:4, task:"运行 CI 验证", │
│ status:"pending" ○}, │
│ ] │
│ │
│ 规则约束: │
│ ┌──────────────────────────────────────┐ │
│ │ 1. 同一时间只有一个 in_progress │ │
│ │ → 强制模型聚焦,不能同时做两件事 │ │
│ │ │ │
│ │ 2. nag reminder 机制: │ │
│ │ 每次 API 回复后检查—— │ │
│ │ 如果有 pending 的 todo │ │
│ │ 就在 system prompt 注入提醒 │ │
│ │ "你还有未完成的任务,请继续" │ │
│ │ │ │
│ │ 3. 只能通过 TodoWrite 工具修改状态 │ │
│ │ 模型不能直接改数组 │ │
│ └──────────────────────────────────────┘ │
└────────────────────────────────────────────┘
工作流:
模型调用 TodoWrite(action="create", tasks=[...])
↓
TodoManager 创建清单
↓
模型调用 TodoWrite(action="update", id=1, status="in_progress")
↓
模型执行任务...
↓
模型调用 TodoWrite(action="update", id=1, status="completed")
↓
nag: "还有 3 个待办事项"
↓
模型继续下一个...
关键概念解释
- nag reminder一种注入到系统提示中的提醒消息。每次 API 调用前检查,如果有未完成的 todo,就自动在 system prompt 末尾追加一段提醒文本,确保模型不会忘记未完成的任务。 — 防遗忘的关键机制。没有它,模型做完第一步可能就直接回复用户了。
- 单一 in_progress 约束任何时刻只允许一个 todo 的状态为 "in_progress"。这是一个硬约束——如果模型试图同时标记两个为 in_progress,TodoManager 会拒绝。目的是强制模型线性推进任务。 — 防止模型在多个任务间来回跳跃导致都做不好。
对应到 Claude Code 官方的什么
TodoWriteTool
Claude Code 内置了 TodoWriteTool,机制几乎一模一样:
- 维护一个 todo list 数据结构
- 支持 create / update / delete 操作
- system prompt 中注入任务状态
- 在需要长步骤规划时自动被模型调用
官方实现额外支持 todo 的优先级排序和自动清理已完成的过旧 todo。
变更对比表
| 维度 | S02(无规划) | S03(TodoWrite) |
|---|---|---|
| 任务管理 | 无,模型自由发挥 | 结构化清单 + 状态追踪 |
| 聚焦性 | 容易跑偏、跳步 | 单一 in_progress 强制聚焦 |
| 记忆辅助 | 只靠 messages[] 上下文 | nag reminder 持续提醒 |
| 完成率 | 多步任务经常漏步骤 | 显著提升任务完成率 |
| 新增组件 | — | TodoManager + TodoWrite 工具 + nag 机制 |
洞察:TodoWrite 不是「辅助功能」,它是让 Agent 能完成复杂任务的基础设施。没有规划能力的 Agent 只能做一步到位的简单任务。一旦需要 3 步以上的协调,Todo 系统的价值就显现出来了。