Cord:协调 AI 代理树
请提供您希望翻译成简体中文的具体文本内容,我会在保持原始格式、Markdown 语法和技术术语不变的前提下为您完成翻译。
多代理协作的挑战
AI 代理在 单任务执行 方面表现出色:给 Claude 一个明确的指令,它就能完成。
然而,现实工作很少是单一任务。它更像是一个 相互依赖任务的树结构,包括:
- 依赖 – 后续步骤依赖于前一步的结果。
- 并行 – 多个子任务可以同时运行。
- 上下文流 – 信息必须在整个工作流中无缝共享。
为什么当前的多代理框架未能奏效
- 过度专注 – 它们往往针对孤立的问题,而不是更广泛的编排挑战。
- 碎片化沟通 – 在代理之间传递上下文的机制有限。
- 可扩展性不足 – 难以在大规模下处理复杂的依赖图和并行执行。
结论:要释放 AI 代理的真正潜力,我们需要能够管理 任务树、依赖解析、并行执行 和 上下文传播 的框架——而不是仅仅针对孤立的单任务解决方案。
外部概况
| 框架 | 协调模型 | 优势 | 局限性 |
|---|---|---|---|
| LangGraph | 状态机图(节点 + 边在 Python 中定义) | • 精确、确定性的工作流 • 适用于固定的流水线 | • 图是静态的——代理在任务中途无法重新路由 • 开发者必须预见每一种可能的拆解 |
| CrewAI | 基于角色的团队(例如 researcher、analyst、writer) | • 直观、类人团队隐喻 • 易于分配高级职责 | • 角色在设计时固定 • 团队无法动态发现需要更多代理或拆分角色 |
| AutoGen | 代理之间通过群聊对话进行协调 | • 非常灵活,具备涌现行为 • 无需预先声明依赖 | • 缺乏显式结构或依赖跟踪 • 缺少权威、作用域和类型化结果 • 难以检查或调试 |
| OpenAI Swarm | 最小化交接(Agent A → Agent B) | • 轻量、实现简单 | • 仅线性——无并行或树状任务生成 |
| Claude’s Tool‑Use Loops (Anthropic) | 单代理循环并调用工具 | • 很好地处理顺序复杂性 • 适用于工具驱动的流水线 | • 在大型任务上受限于上下文窗口 • 无并行执行——单代理、单线程 |
共同点
所有这些框架都要求开发者预先定义协调结构:
- 工作流图、代理角色和交接模式在前期决定。
- 代理严格在这些边界内运行。
为什么现在这很重要?
历史上,硬编码分解是有道理的,因为早期的大语言模型在规划方面不可靠。如今的模型:
- 有效规划,并能自行将问题拆分为子问题。
- 理解子任务之间的依赖关系。
- 识别任务过大而无法一次完成的情况。
鉴于这些能力,出现了以下问题:
我们为何仍在硬编码分解?
让代理构建任务树
我构建了 Cord。你给它一个目标:
cord run "Should we migrate our API from REST to GraphQL? Evaluate and recommend."
一个代理启动,读取目标,判断在回答之前需要进行调研,并创建了以下子任务:
● #1 [active] GOAL Should we migrate our API from REST to GraphQL?
● #2 [active] SPAWN Audit current REST API surface
● #3 [active] SPAWN Research GraphQL trade‑offs for our stack
○ #4 [pending] ASK How many concurrent users do you serve?
blocked‑by: #2
○ #5 [pending] FORK Comparative analysis
blocked‑by: #3, #4
○ #6 [pending] SPAWN Write migration recommendation
blocked‑by: #5
- 没有硬编码任何工作流。
- 代理在 运行时 决定了这个结构。
- 它并行执行了 API 审计(#2)和 GraphQL 调研(#3)。
- 它创建了一个 ask 节点(#4)——向人类提问,因为推荐结果取决于规模,而这点代理无法自行发现。
- 它让 #4 依赖 #2,这样问题在审计结果的上下文中更有意义。
- 它把 #5 设为 fork,使得分析能够继承迄今为止学到的所有信息。
- 它把最终的推荐(#6)排在分析之后。
执行追踪
✓ #2 [complete] SPAWN Audit current REST API surface
result: 47 endpoints. 12 heavily nested resources...
✓ #3 [complete] SPAWN Research GraphQL trade‑offs
result: Key advantages: reduced over‑fetching...
? How many concurrent users do you serve?
Options: 100K
> 10K‑100K
● #5 [active] FORK Comparative analysis
blocked‑by: #3, #4
- 调研是并行进行的。
- 当两者都完成 且 你回答了问题后,分析任务会在包含这三项结果的上下文中启动。
- 随后它会生成一个针对你实际规模和 API 表面的推荐——而不是一篇关于 GraphQL 的通用博客文章。
Spawn vs. Fork
Key idea: Treat spawn and fork as distinct context‑flow primitives.
| 方面 | Spawn | Fork |
|---|---|---|
| 上下文 | 从干净的状态开始:仅有提示以及它明确依赖的节点结果。 | 继承所有已完成的兄弟节点结果,使子节点完整了解之前的工作。 |
| 类比 | 雇佣承包商:“这是规格,去做吧。” | 向团队成员简报:“你了解团队迄今为止学到的一切。” |
| 成本 | 重启成本低,易于推理。 | 成本更高,但在后续分析基于早期结果时必不可少。 |
| 并发 | 不相关——两者都可以并行或顺序运行。区别在于子节点知道什么,而不是执行顺序。 | 不相关——两者都可以并行或顺序运行。区别在于子节点知道什么,而不是执行顺序。 |
实际运作方式
- 独立研究任务 → 使用
spawn。
代理仅获得最小必要上下文,使每个任务相互独立且易于重新运行。 - 依赖先前工作的分析 → 使用
fork。
代理接收全部已完成的兄弟节点结果,能够综合迄今为止学到的一切。
模型可以自行决定使用哪种原语,因为它直观地理解“重新开始”和“在已有知识上构建”之间的区别。
Under the Hood
每个代理都作为 Claude Code CLI 进程运行,配备 MCP 工具,并由共享的 SQLite 数据库支持。
核心 MCP 操作
| 操作 | 签名 | 描述 |
|---|---|---|
| spawn | spawn(goal, prompt, blocked_by) | 创建一个新的子任务。 |
| fork | fork(goal, prompt, blocked_by) | 创建一个继承父上下文的子任务。 |
| ask | ask(question, options) | 向人类发出输入提示。 |
| complete | complete(result) | 将当前任务标记为已完成。 |
| read_tree | read_tree() | 获取完整的协作树。 |
工作原理
- 代理对协作树 保持无感;它们只看到上述工具,并在需要时调用它们。
- MCP 服务器强制执行 协议:依赖解析、权限范围以及结果注入。
- 当
ask节点准备就绪时,引擎会 暂停 并在终端显示提示。 - 人类的答案被存储为结果,解除下游节点的阻塞。在此模型中,人类是树中的 主动参与者,而非被动观察者。
实现细节
- 大约 500 行 Python。
- 使用 SQLite 进行持久化,使用 MCP 进行进程间通信。
瞬间领悟
在编写运行时之前,我必须先回答一个问题:Claude 真会理解这个吗?
整个设计依赖于代理能够理解它们从未见过的协作工具。如果它们分不清 spawn 与 fork,或者忽略 blocked_by,协议就会一开始就失效。
实验
- 搭建 一个仅用于测试的 MCP 服务器,配备五个工具。
- 指向 Claude Code 到该服务器。
- 运行 15 个测试——没有运行时,没有引擎,只有 Claude、这些工具和一个任务。
测试 1 – 拆解项目
- 提示:“把这个项目拆解成子任务。”
- Claude 的未被提示的行为:
- 调用了
read_tree()来检查当前状态。 - 创建了五个子节点,并给出正确的依赖顺序。
- 为每个子节点编写了详细的提示。
- 再次调用
read_tree()验证节点已创建。
- 调用了
这些我都没有指示它去做。
测试 2 – Fork 与 Spawn
- 场景:独立的研究任务 以及 一个综合步骤。
- Claude 的选择:
- 对研究任务使用
spawn(承包商式工作)。 - 对分析任务使用
fork(向团队成员简报)。
- 对研究任务使用
当被问及 原因 时,Claude 给出了我规范中的确切比喻——尽管它从未见过该规范。
结果
- 15/15 测试全部通过。
- 任务被拆分为 3–6 个子任务,且依赖关系正确。
- Claude 提出了范围明确的人类问题,而不是盲目猜测。
- 当它尝试停止一个兄弟节点却因缺乏权限被拒绝时,它没有重试或绕道,而是通过
ask parent进行升级——这正是预期的模式。
收获
那一刻证明了构建运行时是值得的。模型已经理解了协议,我只需要搭建相应的基础设施即可。
这不是
此实现使用 Claude Code CLI 和 SQLite,但协议——五个原语、依赖解析、权限范围、两阶段生命周期——独立于这些。
- 您可以在 Postgres 上实现 Cord,以进行多机器协调。
- 直接在 Claude API 上实现,而无需 CLI 开销。
- 使用多个 LLM 提供商——GPT 处理低成本任务,Claude 处理复杂任务。
- 为某些节点使用人工工作者。
协议本身就是贡献。此仓库是概念验证。
试一试
git clone https://github.com/kimjune01/cord.git
cd cord
uv sync
cord run "your goal here" --budget 2.0
你也可以将其指向一个规划文档:
cord run plan.md --budget 5.0
根代理读取 Markdown 并将其分解为协调树。无论你以何种方式编写计划——要点、章节、散文——代理都会推断任务结构、依赖关系和并行性。
注意: 需要 Claude Code CLI 且订阅中包含该功能。