Task system——目标太大,拆成小任务

"大目标拆成小任务, 排好序, 持久化" — 文件持久化的任务图, 多 agent 协作的基础。

Github 原文:shareAI-lab/learn-claude-code

在TodoWrite — 没有计划的 Agent,做着做着就偏了中我们就提及到,CC 不是单纯依靠一套 Todo 来实现任务清单的,有一个专门的 task system 来维护。久等了!也恭喜你来到了这里。

问题

试想一下,Agent 接到一个项目:搭数据库、写 API、加测试。它用 TodoWrite 列了一张清单,然后开始写 API,写到一半发现没数据库表,回头补;加测试时发现 API 接口签名又变了…来回的改来改去,最后 todo 让他改的面目全非…

早在 Agent 的规划能力出现之前,我们就知道有一个叫做 Workflow 的东西,他利用 DAG 来实现判断、循环等流程,todo 应该也是这样的,之间有这依赖关系,形成一个流程图,而不是之前 todo 那种线性的。

TodoWrite 是当前任务的执行清单,保存在会话内存中。但这里需要的是任务系统:每个任务是一个 JSON 文件,任务之间有 blockedBy 依赖,跨会话持久化在磁盘上。

解决方案

Task system——目标太大,拆成小任务

相比之前,多了个功能:就是有一个 task 这个东西,他是一个 json 文件,每一个 task 就是一个 json 文件。

@dataclass
class Task:
    id: str
    subject: str
    description: str
    status: str          # pending | in_progress | completed
    owner: str | None    # Agent 名(多 Agent 场景)
    blockedBy: list[str] # 依赖的任务 ID 列表

利用这个东西来替代 Todo,但是为什么要这么做呢?原文给出了这个表格:

TodoWrite (s05)Task System (s12)
定位当前任务的执行清单可恢复的任务系统
存储进程内 / 会话状态.tasks/{id}.json
依赖blockedBy / blocks 依赖图
生命周期当前会话 / 当前任务跨会话保留
分工不负责任务认领owner / claim
状态pending / in_progress / completedpending / in_progress / completed
粒度Agent 自己的步骤可被认领、追踪、解锁的任务

这么多参数对比,实在是看不懂,别急,其实这些东西整体可以概括为三点:

  • 可恢复,且具备持久化能力;

  • 存在依赖关系;

  • 可以支持多 Agent 处理任务,具有认领追踪能力。

存储到文件

这就是其可恢复,具备持久化能力的原因。之前我们在介绍 Todo 的时候说过,这是一段上下文,跟着一起循环的,这就像我们记在脑子里的东西一样,可能次数多了就忘了,AI 自己都忘记了自己的 todo 要干嘛。

而 task system 是存在一个文件里面的,这就是他的优势,无论你怎么循环,我这个文件都在,甚至可以夸对话调用,完全不用担心这个问题。

存在依赖关系

这是最重要的。我们在开头就说过,就算 todo 我们之前设置过循环 3 次就查看一次,但是 AI 看了一次之后他要是发现了问题可能会改,但改几次可能 todo 的逻辑就被改的面目全非了。例如让你先写代码,再出设计稿,最后再出 prd,直接顺序调了过来,原因就在于没有任务之间没有相互依赖的关系。

在 task system 中,利用blockedby就可以确保某一步不做完,就休想下一步,强制 AI 按照顺序执行,禁止无逻辑跳步。

任务认领

这个主要是应对 Subagent 的,我们都知道 CC 之所以速度快很大原因在于他会把任务交给 Subagent 来执行,而不是像 codex 一样,不会主动使用 Subagent 来干活。

这个 task 就可以由主 agent 分配给这些 subagent 来干,认领了任务就可以确保互相之间不撞车。

总结

这套方案的核心就是相比于之前只是大家口头列了个任务清单,现在直接大家把任务放在 jira 和 linear 这样的工具里面了,有追责、有状态流转,而且忘记了随时都可以来看看。

Task system——目标太大,拆成小任务

CC中的task system

之前我们就说过,CC 不是只使用 todo 也不是只使用 task system,而是两者都用。交互式会话默认启用 Task,非交互式/SDK 默认用 TodoWrite。

此外,在认领的时候,还提供了一个锁机制,防止出现重复认领的竞争问题。

  • 任务文件锁proper-lockfile 锁住 {taskId}.json(最多重试 30 次,指数退避 5-100ms)。锁内:

    1. 重新读取任务(防 TOCTOU)
    2. 检查已被他人认领 → already_claimed
    3. 检查已完成 → already_resolved
    4. 检查上游未完成 → blocked
    5. 设置 owner
  • 列表级锁(agent busy 检查时):.lock 文件,原子性扫描所有任务并检查该 agent 是否已有其他 open task。