当 AI 编码工具逐渐走出「单兵作战」的阶段,一个核心问题开始浮出水面:单个智能体能力再强,如何让它与团队中的其他智能体高效协作?OpenAI 给出的答案是一份规范文档——Symphony。
从「盯着会话」到「盯着任务」
在 Symphony 出现之前,工程师与 AI 编码智能体协作的典型流程是这样的:打开一个交互式会话,分配任务,审查输出,再开一个新的会话如此往复。每位工程师同时管理三至五个会话后,上下文切换就成了最大的瓶颈——没有人能在脑中同时维护那么多会话的上下文。
Symphony 试图解决的正是这个注意力瓶颈。它的核心思路很简单:不再围绕编码会话组织工作,而是围绕项目交付物。
具体来说,Symphony 将问题追踪器作为控制平面。工程师不再需要手动管理多个智能体会话,而是通过创建「问题」来分配任务,Symphony 会自动将这些任务分配给对应的智能体,持续运行直至完成。如果某个智能体崩溃或停滞,Symphony 会自动重启它;如果出现新工作,它会自动接收并开始推进。
以问题为单位的任务树
传统的工作模式下,一个编码会话的生命周期通常与一个 PR 绑定。PR 合入,会话结束。但真实项目中的任务往往不是这样运作的——一个功能需求可能涉及多个模块的改动,需要不同智能体在不同阶段协作完成。
在 Symphony 的设计里,一个「问题」可以对应一个完整的任务树。问题可以指示某个智能体先分析代码库并生成实现方案,然后由 Symphony 将这个方案拆解为多个可跨智能体调度的子任务。这意味着同一个问题可以触发多个智能体的并行工作,而不再是一个会话、一条工作线。
这种设计带来了一个关键转变:任务的粒度从「写一个 PR」变成了「完成一个交付物」。 交付物可以是代码,但也可以是设计方案、测试报告或者架构文档。这让智能体的工作输出与项目的实际需求对齐,而不是对齐某一次会话的生命周期。
工作模式的转变还带来一个隐性但重要的变化:智能体犯错的成本显著降低。 因为主要工作从「让智能体一次性完成所有事情」变成了「审查已完成的工作并决定是否驳回」。工程师的角色从执行者变成了审核者,这更符合人类协作中的常见模式。
控制平面的设计逻辑
Symphony 选择问题追踪器作为控制平面有其内在逻辑。问题追踪器本质上是项目管理工具,它记录了「谁」「什么任务」「什么状态」这些核心信息。把这个能力复用到智能体编排上,就形成了一个天然的状态机。
每个问题在追踪器中有明确的状态流转:待处理、进行中、已完成或已驳回。Symphony 正是基于这些状态来驱动智能体的工作分配。当一个问题被标记为「进行中」时,Symphony 会确保有对应的智能体正在处理它;当问题达到「已完成」状态时,Symphony 会停止分配新的子任务。
这种设计有一个实际好处:人类工程师可以通过同一个工具同时监控人类和智能体的工作进度。 不需要额外的 Dashboard 或监控面板,现有的问题追踪器界面直接复用。
SPEC 文档而非产品
Symphony 最有意思的地方在于,它不是一个复杂的监督系统或一个功能完备的平台,而是一份 SPEC.md 规范文档。
这份文档描述了三件事:问题追踪器作为控制平面的设计理念、多智能体协调的通信协议、以及任务状态机的流转规则。任何组织都可以基于这份 SPEC 文档来构建自己的编排系统。这与 OpenAI 在 AI Safety 领域推崇的「spec-first」思路一脉相承——先说清楚「要做什么」,再谈「怎么做」。
Symphony 的参考实现使用 Elixir 构建。OpenAI 选择 Elixir 的理由是它在编排与管控并发进程方面具备完善的基础能力。Elixir 的 Actor 模型天生适合这种「监控大量状态机并根据状态触发行为」的场景,这与 Symphony 的需求高度契合。
参考实现的代码结构大致如下:
# Symphony 参考实现核心概念
defmodule Symphony.Task do
# 任务状态
defstruct [
id: nil,
type: :coding, # 或 :analysis, :review, :planning
status: :pending, # pending | running | completed | failed
assigned_agent: nil,
parent_issue: nil,
subtasks: []
]
end
defmodule Symphony.Orchestrator do
# 持续监控问题追踪器,驱动任务分配
def start_link(issue_tracker) do
Task.Supervisor.async_nolink(fn ->
watch_issue_board(issue_tracker)
end)
end
defp watch_issue_board(issue_tracker) do
# 持续轮询问题状态变化,触发对应智能体
receive do
{:issue_updated, issue_id, new_status} ->
handle_status_change(issue_id, new_status)
watch_issue_board(issue_tracker)
end
end
end这段代码展示了 Symphony 的核心循环:监听问题状态变化 → 根据状态分配或重启智能体 → 等待结果 → 更新状态。 实际的参考实现远比这复杂,但核心逻辑可以简化为这个状态机。
为什么这件事值得注意
Symphony 的发布值得关注的理由不在于它是一个现成可用的产品,而在于它代表了一种正在形成的新范式。
AI 编码工具的第一阶段是个体增强:一个工程师加上一个智能体,效率提升,这是 Claude Code、Copilot 等工具做的事情。
AI 编码工具的第二阶段是批量执行:多个智能体并行工作,同时处理多个任务,但谁来协调它们?这正是 Symphony 试图回答的问题。它不解决「智能体能不能写代码」的问题,而是解决「多个智能体同时写代码时谁来负责」的协调问题。
这种转变对工程团队有几个直接影响。首先,任务的分解粒度变得更重要。 当智能体需要协作时,「把任务描述清楚」这个平时就在强调的要求变得更加关键。一个模糊的需求描述在单人会话中只是效率问题,但在多智能体协作中可能导致整个任务树的失败。
其次,人机协作的边界需要重新划定。 Symphony 将人类的角色定义为「审查者」而非「执行者」,这意味着团队需要重新思考哪些环节必须由人把关,哪些环节可以交给智能体自主完成。对于代码评审来说,这个边界相对清晰;但对于架构决策和 API 设计,人类的判断力在短期内仍然不可替代。
第三,工具链的集成方式面临调整。 问题追踪器需要与智能体调度系统打通,这对现有的 CI/CD 和项目管理流程提出了新的要求。Jira、Linear、GitHub Issues 这些工具在 Symphony 的框架下不再只是人类工程师的任务板,同时也成了智能体的工作入口。
现状与局限
Symphony 目前只是一个参考实现,不是 OpenAI 的商业产品。它的价值更多在于提供一种思路框架,而非开箱即用的解决方案。
有几个实际问题值得工程师关注。首先,状态同步的延迟。 Symphony 需要持续轮询问题追踪器的状态变化,这个过程中必然存在延迟。在高节奏的开发环境中,几秒钟的延迟可能影响智能体响应的及时性。
其次,错误恢复的策略。 文档中提到 Symphony 会在智能体崩溃时重启它,但重启后的上下文恢复是一个需要精心设计的问题。如果智能体在执行中途崩溃,重启后是重新开始还是从断点继续?这个问题的答案直接影响系统的实用性。
第三,多语言参考实现的空白。 目前只有 Elixir 的参考实现。对于使用 Python、Go 或 Rust 的团队来说,需要自行实现 SPEC 中定义的协议和状态机。这增加了采用成本,但也给了社区发挥空间。
开源社区的走向
Symphony 背后的设计思路——以项目交付物为核心、以问题追踪器为控制平面——有望在开源社区得到进一步延伸。
一个可能的方向是跨智能体的通信协议标准化。 如果不同组织基于 Symphony SPEC 构建各自的编排器,这些编排器之间能否通信?类似于 API 规范的作用,SPEC 可以成为智能体间对话的「语言」。
另一个方向是与现有工具链的深度集成。 GitHub Copilot、Cursor、Windsurf 这类 AI 编码工具目前都是独立工作,未来可能会出现一个协调层,让它们能够响应 Symphony 发出的任务调度指令。这比让每个工具各自实现编排能力更高效。
还有一个值得关注的点是可观测性。 当多个智能体同时运行时,谁来监控它们的健康状态?现有的可观测性工具主要面向人类开发的系统,需要针对智能体工作负载做定制化扩展。
写在最后
Symphony 目前只是一个参考实现,不是 OpenAI 的商业产品。它的价值更多在于提供一种思路:如何在多个自主智能体之间建立有效的协作机制。
对于正在探索 AI 辅助编程的团队而言,这份 SPEC 文档值得一读。即使不直接采用 Elixir 的参考实现,理解「以问题为控制平面」这个核心设计,对规划团队内部的 AI 工作流有参考意义。
开源社区接下来会不会出现更多基于这份 SPEC 的实现,智能体之间的协作协议是否会走向标准化,这些问题比 Symphony 本身更值得持续关注。
夜雨聆风