LEARN CLAUDE CODE

S07: Task System — 持久化任务图

问题:为什么需要任务图?

在 S01-S06 的世界里,Claude Code 可以用内置的 TodoManager 跟踪待办事项。但 TodoManager 有两个致命缺陷:

核心矛盾:上下文窗口是有限的临时内存,但项目任务是长期存在的。把任务放在上下文里,就注定会在压缩时丢失。必须把任务持久化到磁盘。

解法:每个任务一个 JSON 文件

解决方案很直接——在项目根目录创建 .tasks/ 目录,每个任务是一个独立的 JSON 文件。文件名就是任务 ID(例如 .tasks/task-001.json)。

{
  "id": "task-001",
  "title": "实现用户认证模块",
  "status": "in_progress",
  "owner": "agent-alpha",
  "blockedBy": [],
  "description": "实现 JWT 登录和注册接口",
  "createdAt": "2025-01-15T10:00:00Z",
  "completedAt": null
}

{
  "id": "task-002",
  "title": "编写认证单元测试",
  "status": "pending",
  "owner": null,
  "blockedBy": ["task-001"],
  "description": "为认证模块编写 Jest 测试",
  "createdAt": "2025-01-15T10:01:00Z",
  "completedAt": null
}

关键字段是 blockedBy——它是一个任务 ID 数组,表示"我被这些任务阻塞了"。这构成了一个 有向无环图(DAG)

DAG 可视化

任务依赖图(DAG)示例: ┌────────────┐ ┌────────────┐ │ task-001 │ │ task-003 │ │ 用户认证 │ │ 数据库 Schema│ │ [进行中] │ │ [已完成] ✓ │ └─────┬──────┘ └──┬────┬────┘ │ │ │ ▼ │ ▼ ┌────────────┐ │ ┌────────────┐ │ task-002 │ │ │ task-005 │ │ 认证测试 │ │ │ 数据迁移 │ │ [阻塞中] ✗ │ │ │ [已完成] ✓ │ └─────┬──────┘ │ └────────────┘ │ │ ▼ ▼ ┌─────────────────────────┐ │ task-004 │ │ 集成测试 │ │ blockedBy: [002, 003] │ │ [阻塞中] ✗ │ └─────────────────────────┘ 箭头方向 = "被依赖于" task-004 同时被 task-002 和 task-003 阻塞 task-003 已完成,但 task-002 还没完成 所以 task-004 仍然不能开始

三个核心问题

任务系统的核心价值在于随时能回答三个问题:

问题查询逻辑意义
什么可以做? status == "pending" && blockedBy.length == 0 没有阻塞的待办任务,代理可以立即认领
什么被卡住了? status == "pending" && blockedBy.length > 0 有依赖未完成的任务,需要先完成前置任务
什么做完了? status == "completed" 记录进度,触发下游任务解锁

自动清理依赖

当一个任务被标记为 completed 时,系统会扫描所有其他任务的 blockedBy 数组,把该任务 ID 移除。如果移除后 blockedBy 变成空数组,那个任务就从"阻塞"变成"可执行"——自动解锁。

task-001 完成
扫描所有 blockedBy
移除 "task-001"
task-002 解锁
task-002 可执行

对比:TodoManager vs Task System

维度TodoManager(S01-S06)Task System(S07)
存储位置内存(上下文窗口内)磁盘(.tasks/ 目录)
依赖关系blockedBy 字段形成 DAG
压缩后丢失完好无损
多代理共享不可能文件系统天然共享
可视化扁平列表依赖图

对应官方工具

TaskCreateTool / TaskUpdateTool / TaskListTool / TaskGetTool

Claude Code 官方的四个任务工具直接对应这套设计。TaskCreateTool 创建任务 JSON 文件,TaskUpdateTool 更新状态并自动清理依赖,TaskListTool 列出所有任务并按状态过滤,TaskGetTool 读取单个任务详情。

关键洞察:任务系统不是"待办清单应用"——它是代理的外部记忆。上下文窗口是短期记忆,.tasks/ 目录是长期记忆。代理通过读写文件来"记住"自己该做什么,即使上下文被完全压缩也不会丢失方向。