Skip to content

计划与任务系统:Agent 的行动蓝图

Agent Loop、工具系统、技能系统分别提供循环机制、执行能力和领域知识。计划与任务系统提供长步骤任务的拆解、排序、追踪和验证能力。

计划与任务系统完整流程图

普通聊天的上下文是线性的,但现实任务可能是并行的、有依赖的、会回滚的。计划系统在这两者之间架桥。

为什么 Agent 需要计划

复杂任务包含多个有依赖关系的步骤。以升级 React 版本为例:

text
任务:将项目从 React 17 升级到 18

步骤 1:升级 package.json 中的 React 版本    ← 可做
步骤 2:修复被废弃的 API 调用                ← 依赖 1
步骤 3:更新依赖库到兼容版本                 ← 依赖 1
步骤 4:替换 Concurrent Mode 相关代码        ← 依赖 2、3
步骤 5:全量回归测试                         ← 依赖 4

没有计划系统时,Agent 靠上下文记忆推进。上下文会被压缩、截断、干扰。 计划系统则把进度变成显式清单,解决四个问题:

没有计划有计划
大目标模糊,易遗漏拆解,每步都是可执行小任务
依赖隐式,易搞错顺序排序,依赖显式,顺序清晰
需翻对话历史追踪,任务看板实时反映进度
做完了但可能方向错了验证,每步后对照原始目标检查

计划的制定:Plan Mode

面对复杂任务,Agent 先进入计划模式(Plan Mode),核心约束是只读不写:搜索代码、阅读文件、理解架构,但不执行修改。

text
   用户提出复杂任务


┌───────────────────┐
│ Plan Mode(只读) │
│                   │
│ 搜索代码          │
│ 理解架构          │
│ 设计方案          │
│ 列出实现步骤      │
│ 标注依赖关系      │
└─────────┬─────────┘


     人类审查计划
      ┌───┴───┐
      │       │
     通过    修改
      │       │
      ▼       │
┌──────────────────┐
│     执行阶段     │
│     (读、写)     │
└──────────────────┘

Plan Mode 分离理解和行动,在零成本阶段确认方向,避免动手后才发现方向错误的代价。

计划的产出是一份任务列表——每个任务标注做什么、为什么做、有什么前置条件。

任务的载体:任务管理工具

计划不能悬浮在空中。任务管理工具在会话中提供四件事:

  • 创建任务(将计划步骤变为显式条目)
  • 追踪状态(记录每步当前进展)
  • 管理依赖(声明谁先谁后)
  • 提供进度可见性(实时反映整体完成情况)。

计划中的每个步骤创建为一张任务卡片:

  • 做什么(subject):简短标题
  • 为什么做(description):背景、要求
  • 前置条件(blockedBy):必须先完成的任务

版本演进:v1 → v2

Claude Code 的会话内任务管理经历了两个版本:

特性v1: TodoWritev2: Task 工具集
写入工具TodoWriteTaskCreate/TaskUpdate
查询工具,只能等待系统推送 reminder 或靠自身记忆TaskList/TaskGet,可随时主动查询
存储纯内存,session 结束后丢失磁盘文件(~/.claude/tasks/),持久化
任务 ID无,靠数组索引自增数字 ID
任务依赖不支持支持 blocks / blockedBy
多 Agent 协作不支持支持团队共享 task list
并发安全无锁文件锁保护
Hook 系统支持 taskCreated / taskCompleted 钩子
恢复方式从 transcript 解析最后一条调用直接读取磁盘文件

切换逻辑:交互式会话(终端/IDE)默认启用 v2,非交互式会话(如 SDK 调用)默认走 v1。v2 启用时,TodoWrite 工具自动被禁用。两者不会同时存在。

本文后续内容默认以 v2(Task 工具集)为准。

text
任务看板
┌────┬───────────────────────┬─────────────┬──────────┐
│ ID │ 任务                  │ 状态        │ 依赖     │
├────┼───────────────────────┼─────────────┼──────────┤
│ 1  │ 升级 React 版本       │ completed   │ 无       │
│ 2  │ 修复被废弃的 API 调用 │ in_progress │ 依赖 1   │
│ 3  │ 更新依赖库到兼容版本  │ pending     │ 依赖 1   │
│ 4  │ 替换相关代码          │ pending     │ 依赖 2,3 │
│ 5  │ 全量回归测试          │ pending     │ 依赖 4   │
└────┴───────────────────────┴─────────────┴──────────┘

状态之间的流转关系:

text
pending ──→ in_progress  ──→  completed 
(未开始)      (执行中)     (完成并通过验证)
   ↑                              │
   │          验证失败            │
   └──────────────────────────────┘

依赖管理

任务通过 blocksblockedBy 显式声明依赖关系。依赖是执行时的硬性约束,未完成时不会执行后续任务。

进度看板

对人类是透明度,对 Agent 是防遗漏的安全网——上下文压缩时,任务列表保留进度信息。

从计划到执行:工作循环

text
┌──────────────────────────────────────────┐
│  1 查看看板  还有哪些 pending 任务?     │
│     │        哪些依赖已解决?            │
│     ▼                                    │
│  2 领取任务  选择可做任务,              │
│     │        标记 in_progress            │
│     ▼                                    │
│  3 执行      调用工具完成                │
│     │                                    │
│     ▼                                    │
│  4 标记完成  确认成果,标记 completed    │
│     │                                    │
│     ▼                                    │
│  5 回到 1    直到所有任务完成            │
└──────────────────────────────────────────┘

关键设计

先创建任务再执行。 创建任务本身是一次显式思考,降低遗漏概率。

单 Agent 场景也需要。 任务列表提供进度锚点(上下文压缩后仍可恢复)和人类透明度。

任务完成 ≠ 目标达成。 所有任务完成后需回到原始目标验证。

验证

三层验证:

  1. 自动化验证:运行测试、类型检查、lint
  2. 功能性验证:启动应用,实际操作
  3. 目标对照:回到用户原始请求逐条核对

验证不通过时重新打开相关任务,标记 in_progress,修复后再验证:

text
执行 → 验证 → 发现问题 → 修复 → 再验证 → 通过