1. 为什么内存里的 Todo 清单撑不起多 Agent 协作
如果你用 ClaudeCode 跑过稍微长一点的任务,大概率遇到过这种场景:让它先建数据库 Schema,再写 API 路由,最后做集成测试。结果上下文一压缩,或者进程崩了一次,之前规划好的任务顺序全乱了,Agent 开始对着不存在的表写查询语句。这不是模型变笨了,而是早期 Todo 模型本身的结构缺陷。
ClaudeCode 的 Task System 解决的正是这个问题。它把任务从内存里的扁平清单,升级成持久化到磁盘的任务依赖图,也就是 DAG。简单说,每个任务是一个 JSON 文件,任务之间的先后关系用 blockedBy 字段声明,多个 Agent 读写同一个.tasks/目录就能协作。适合谁?适合在本地跑多 Agent 编排、需要断点续跑、或者任务链路超过单次对话长度的开发者。
我试过用纯内存的 TodoWrite 管理一个五步任务链,第三步时手动触发了一次上下文压缩,结果 Agent 完全忘了前两步做过什么,把已经建好的表又建了一遍。Task System 的核心价值就在这里:任务状态存在磁盘上,压缩、重启、崩溃都不影响,Agent 重新拉起后调一次task_list就能恢复全局进度。
这篇文章会从任务图落盘结构讲起,给出可复制的 DAG 依赖声明和 Agent 角色分配配置,然后演示通过 TaoToken 统一通道完成一次任务图创建、断点续跑和协作验证。全程零依赖,不需要数据库,文件系统就是共享状态层。
2. TaoToken 统一通道前置配置:Base URL、Key 与 Model ID
在跑 Task System 之前,得先把 ClaudeCode 的请求通道配好。TaoToken 在这里的角色是统一 API 入口,你不需要为每个模型单独维护一套 Key 和地址,一个通道覆盖对话、编码和 Agent 场景。下面是我实测下来最稳的配置方式。
先拿 Key。打开 https://taotoken.net/api-keys ,登录后创建一个新 Key,复制出来。注意这个 Key 只在创建时完整显示一次,丢了就得重建。
然后配置 ClaudeCode 的接入信息。ClaudeCode 读取的是环境变量或 settings 文件,我推荐用 settings 方式,路径和原文保持一致,方便版本管理。在项目根目录创建.claude/settings.json:
{ "env": { "ANTHROPIC_BASE_URL": "https://taotoken.net/api", "ANTHROPIC_API_KEY": "sk-你的TaoTokenKey", "ANTHROPIC_MODEL": "claude-sonnet-4-20250514" } }三件套对应关系要记清楚:Base URL 填https://taotoken.net/api,Key 填刚才复制的,Model ID 填你实际要用的模型标识。如果你用的是 Codex 系的工具,配置写在~/.codex/auth.json:
{ "base_url": "https://taotoken.net/api", "api_key": "sk-你的TaoTokenKey", "model": "claude-sonnet-4-20250514" }Cline 或 MCP 类的工具,在设置面板里找 Base URL、API Key、Model ID 三个字段,分别填入同样的值。这里有个坑:Base URL 末尾不要加/v1,TaoToken 的通道已经处理了路径拼接,多写一层会 404。
配置完成后,可以用一条最小请求验证通道是否通:
curl https://taotoken.net/api/v1/messages \ -H "x-api-key: sk-你的TaoTokenKey" \ -H "anthropic-version: 2023-06-01" \ -H "content-type: application/json" \ -d '{ "model": "claude-sonnet-4-20250514", "max_tokens": 64, "messages": [{"role": "user", "content": "ping"}] }'返回里出现content字段就说明通道正常。这一步别跳过,后面 Task System 的所有工具调用都走这条通道,通道不通后面全是白搭。
3. 任务图落盘结构与 DAG 依赖声明可复制配置
Task System 的存储设计很朴素:每个任务一个 JSON 文件,放在.tasks/目录下,文件名格式是task_<id>.json。这个设计的好处是零依赖、可读、可手改。下面是一个四任务 DAG 的完整落盘结构。
先看单个任务文件长什么样。task_1.json:
{ "id": 1, "subject": "Setup DB schema", "description": "创建 users 和 orders 两张表", "status": "completed", "blockedBy": [], "owner": "agent-db" }task_2.json和task_3.json都依赖 task 1:
{ "id": 2, "subject": "Build API routes", "description": "基于 schema 生成 REST 路由", "status": "pending", "blockedBy": [1], "owner": "agent-api" }{ "id": 3, "subject": "Implement auth module", "description": "JWT 鉴权中间件", "status": "pending", "blockedBy": [1], "owner": "agent-auth" }task_4.json依赖 task 2 和 task 3:
{ "id": 4, "subject": "Integrate routes with auth", "description": "把鉴权挂到路由上并跑集成测试", "status": "pending", "blockedBy": [2, 3], "owner": "agent-integration" }这个 DAG 回答三个问题:什么可以做?状态 pending 且 blockedBy 为空的任务。什么被卡住?blockedBy 不为空的任务。什么做完了?status 为 completed 的任务,完成时自动解锁下游。
TaskManager 的核心逻辑是:任务完成时,遍历所有任务文件,把已完成任务的 ID 从其他任务的 blockedBy 里移除。这样 task 1 完成后,task 2 和 task 3 的 blockedBy 自动变空,两个 Agent 可以并行推进。
Agent 角色分配通过 owner 字段实现。你可以给每个 Agent 分配一个 owner 标识,Agent 启动时先调task_list,只认领 owner 匹配且 blockedBy 为空的任务。下面是一个多 Agent 的启动配置片段:
AGENT_ROLES = { "agent-db": {"skills": ["sql", "schema"], "poll_interval": 5}, "agent-api": {"skills": ["rest", "fastapi"], "poll_interval": 5}, "agent-auth": {"skills": ["jwt", "security"], "poll_interval": 5}, "agent-integration": {"skills": ["testing", "e2e"], "poll_interval": 10} }每个 Agent 循环执行:读任务列表 → 找 owner 匹配且可执行的任务 → 标记 in_progress → 执行 → 标记 completed。这套骨架不需要中心化调度器,文件系统就是协调层。
4. 验证请求与断点续跑:一次完整的协作验证动作
配置和结构都就位后,跑一次端到端验证。我用三个 Agent 模拟:agent-db 建表,agent-api 和 agent-auth 并行,最后 agent-integration 收尾。
第一步,创建任务图。通过 TaoToken 通道调task_create工具,或者直接写文件。我用工具调用的方式,Agent 的请求体里带上 tools 定义:
response = client.messages.create( model="claude-sonnet-4-20250514", system=SYSTEM_PROMPT, messages=messages, tools=TOOLS, max_tokens=8000, )Agent 会依次创建四个任务,落盘后.tasks/目录出现四个 JSON 文件。调task_list验证:
[ ] #1: Setup DB schema [ ] #2: Build API routes (blocked by: [1]) [ ] #3: Implement auth module (blocked by: [1]) [ ] #4: Integrate routes with auth (blocked by: [2, 3])第二步,agent-db 认领 task 1,标记 in_progress,执行建表,标记 completed。此时 TaskManager 自动把 task 2 和 task 3 的 blockedBy 清空。再调task_list:
[x] #1: Setup DB schema [ ] #2: Build API routes [ ] #3: Implement auth module [ ] #4: Integrate routes with auth (blocked by: [2, 3])第三步,agent-api 和 agent-auth 同时启动,各自认领 task 2 和 task 3,并行执行。这一步是验证多 Agent 协作的关键:两个 Agent 读的是同一份任务文件,但操作的是不同任务,不会互相覆盖。
第四步,模拟断点。在 task 2 和 task 3 都标记 completed 之前,手动 kill 掉 agent-api 进程。此时磁盘上 task 2 的状态是 in_progress。重启 agent-api,它启动时先调task_list,看到 task 2 还是 in_progress 且 owner 是自己,于是重新执行。这就是断点续跑:状态在磁盘上,进程重启不丢。
第五步,task 2 和 task 3 都完成后,task 4 的 blockedBy 自动清空,agent-integration 认领并执行集成测试。最终task_list输出:
[x] #1: Setup DB schema [x] #2: Build API routes [x] #3: Implement auth module [x] #4: Integrate routes with auth整个流程走完,你可以看到 Task System 的三个核心能力:持久化让状态跨进程存活,DAG 让依赖自动解锁,owner 字段让多 Agent 各司其职。验证模型行为是否符合预期时,可以到 https://taotoken.net/models 对照模型能力说明,确认当前 Model ID 支持工具调用。
5. 常见报错排查:401、local proxy failed 与 reading choices
跑 Task System 时踩过的坑集中在通道和工具调用两层。下面按真实报错对照排查。
401 Unauthorized。最常见的原因是 Key 没配对,或者 Base URL 写成了https://taotoken.net/api/v1。检查.claude/settings.json里的ANTHROPIC_API_KEY是否和 https://taotoken.net/api-keys 里创建的一致。另一个隐蔽原因是环境变量覆盖:如果你 shell 里 export 了旧的ANTHROPIC_API_KEY,settings 文件里的值会被覆盖。用env | grep ANTHROPIC确认一下。
local proxy failed。这个报错通常出现在你本地起了代理层但配置没对齐。TaoToken 通道本身不需要额外代理,直接把 Base URL 指向https://taotoken.net/api即可。如果你之前配过其他工具的代理设置,检查~/.codex/auth.json或 Cline 设置里有没有残留的 proxy 字段,清掉。
Error reading choices。这个报错来自响应解析层,通常是 Model ID 写错了,或者请求体格式不对。确认ANTHROPIC_MODEL填的是有效标识,比如claude-sonnet-4-20250514。如果你用的是 OpenAI 兼容格式的请求,注意 TaoToken 的 messages 接口走的是 Anthropic 格式,字段名是messages不是choices。
OAuth token expired。如果你用 ClaudeCode 的 OAuth 登录方式而不是 API Key,token 过期后会报这个。切到 API Key 方式,在 settings 里显式配ANTHROPIC_API_KEY,不要依赖 OAuth 缓存。
工具调用返回 Unknown tool。检查TOOL_HANDLERS字典里有没有注册task_create、task_update、task_list、task_get四个 handler。Task System 的工具是自定义注册的,不是模型内置的,漏注册就会报未知工具。
任务状态被覆盖。多 Agent 并发写同一个任务文件时,如果两个 Agent 同时读、改、写,后写的会覆盖先写的。解决办法是写入前重读文件、校验 status 是否符合预期,再原子写回。课程里用的是先写临时文件再 rename 的方式,你可以照搬。
排查顺序建议:先 curl 验证通道通不通,再确认 Model ID 和 Key,最后查工具注册和并发写入。通道层的问题占八成,工具层的问题占两成。
6. 长期编码与 Agent 编排的通道选择
Task System 跑通之后,你会发现它真正的价值不在单次任务,而在长期运行的 Agent 编排。多个 Agent 持续读写任务目录,任务图不断扩展,这时候通道的稳定性和计费透明度就变得重要。
如果你只是偶尔跑一次任务图验证,用按量计费的 API Key 就够了,到 https://taotoken.net/api-keys 创建一个,配到 settings 里即可。如果你要长期跑编码 Agent、让多个 Agent 持续协作,Coding Plan 更合适,它在长时任务和 Agent 场景下有更稳定的配额策略,具体可以看 https://taotoken.net/coding-plan 。
接入文档在 https://taotoken.net/doc ,里面有各工具的完整配置示例,包括 ClaudeCode、Codex、Cline 的 settings 模板。遇到配置问题先翻文档,大部分报错都有对照说明。
最后给一个实用技巧:Task System 的任务文件是纯 JSON,你可以用jq快速查看全局状态。比如jq -r '.status + " #" + (.id|tostring) + " " + .subject' .tasks/task_*.json能一行列出所有任务的状态和标题。调试多 Agent 协作时,这个命令比调task_list还快。任务图跑顺了,你会发现多 Agent 协作没那么玄乎,核心就是把共享状态放到一个所有 Agent 都能读写的地方,文件系统就是最朴素也最可靠的选择。