# v2: 结构化规划与 Todo
**~300 行代码,+1 个工具,显式任务追踪。**
v1 能工作。但对于复杂任务,模型会失去方向。
让它"重构认证、添加测试、更新文档",看看会发生什么。没有显式规划,它在任务间跳跃、忘记步骤、失去焦点。
v2 只添加一样东西:**Todo 工具**。约 100 行新代码,根本性地改变了 Agent 的工作方式。
## 问题
在 v1 中,计划只存在于模型的"脑中":
```
v1:"我先做 A,再做 B,然后 C"(不可见)
10 次工具调用后:"等等,我在干什么?"
```
Todo 工具让它显式化:
```
v2:
[ ] 重构认证模块
[>] 添加单元测试 <- 当前在这
[ ] 更新文档
```
现在你和模型都能看到计划。
## TodoManager
带约束的列表:
```python
class TodoManager:
def __init__(self):
self.items = [] # 最多 20 条
def update(self, items):
# 验证规则:
# - 每条需要: content, status, activeForm
# - Status: pending | in_progress | completed
# - 只能有一个 in_progress
# - 无重复,无空项
```
约束很重要:
| 规则 | 原因 |
|------|------|
| 最多 20 条 | 防止无限列表 |
| 只能一个进行中 | 强制聚焦 |
| 必填字段 | 结构化输出 |
这些不是任意的——它们是护栏。
## 工具定义
```python
{
"name": "TodoWrite",
"input_schema": {
"items": [{
"content": "任务描述",
"status": "pending | in_progress | completed",
"activeForm": "现在进行时: '正在读取文件'"
}]
}
}
```
`activeForm` 显示正在发生什么:
```
[>] 正在读取认证代码... <- activeForm
[ ] 添加单元测试
```
## 系统提醒
软约束,鼓励使用 todo:
```python
INITIAL_REMINDER = "多步骤任务请使用 TodoWrite。"
NAG_REMINDER = "已超过 10 轮未更新 todo,请更新。"
```
作为上下文注入,不是命令:
```python
if rounds_without_todo > 10:
inject_reminder(NAG_REMINDER)
```
模型看到它们但不回应。
## 反馈循环
当模型调用 `TodoWrite`:
```
输入:
[x] 重构认证(已完成)
[>] 添加测试(进行中)
[ ] 更新文档(待办)
返回:
"[x] 重构认证
[>] 添加测试
[ ] 更新文档
(1/3 已完成)"
```
模型看到自己的计划,更新它,带着上下文继续。
## 何时使用 Todo
不是每个任务都需要:
| 适合 | 原因 |
|------|------|
| 多步骤工作 | 5+ 步需要追踪 |
| 长对话 | 20+ 次工具调用 |
| 复杂重构 | 多个文件 |
| 教学 | 可见的"思考过程" |
经验法则:**如果你会写清单,就用 todo**。
## 集成方式
v2 在 v1 基础上添加,不改变它:
```python
# v1 工具
tools = [bash, read_file, write_file, edit_file]
# v2 添加
tools.append(TodoWrite)
todo_manager = TodoManager()
# v2 追踪使用
if rounds_without_todo > 10:
inject_reminder()
```
约 100 行新代码。Agent 循环不变。
## 更深的洞察
> **结构既约束又赋能。**
Todo 的约束(最大条目、只能一个进行中)赋能了(可见计划、追踪进度)。
Agent 设计中的模式:
- `max_tokens` 约束 → 赋能可管理的响应
- 工具 Schema 约束 → 赋能结构化调用
- Todo 约束 → 赋能复杂任务完成
好的约束不是限制,而是脚手架。
---
**显式规划让 Agent 可靠。**
[← v1](./v1-模型即代理.md) | [返回 README](../README_zh.md) | [v3 →](./v3-子代理机制.md)