2026 年 5 月 4 日,OpenAI 工程师 Alex Kotliarskyi、Victor Zhu 和 Zach Brock 发布了 Symphony。这不是一个传统意义上的工具,而是一份 SPEC.md——一份语言无关的规范文档,描述如何把项目管理看板变成编程 Agent 的持续调度系统。
一句话的核心思路
每一个打开的 Issue,都保证有一个 Agent 在跑。
这就是 Symphony 全部的设计哲学。它不做工作流可视化、不对接任意外部服务、不做非编程自动化——它只做一件事:从 Issue Tracker 读取任务,为每个任务建立独立的工作区,然后启动 Codex Agent 去执行。
OpenAI 内部部署 Symphony 后,部分团队汇报的 PR 合并量增长了 500%。
架构拆解
Symphony 定义了七个组件,缺一不可:
| 组件 | 职责 |
|---|---|
| Workflow Loader | 解析 WORKFLOW.md(YAML 头信息 + Markdown 正文) |
| Config Layer | 带类型的配置读取,处理默认值和环境变量 |
| Issue Tracker Client | 拉取候选 Issue,同步状态 |
| Orchestrator | 轮询调度,管理并发,处理重试 |
| Workspace Manager | 为每个 Issue 创建/维护独立目录 |
| Agent Runner | 启动 Codex App Server 子进程,流式接收事件 |
| Logging/Observability | 结构化日志,可选 REST API 和人工可读看板 |
整个系统的单一权威原则(Single Authority)贯穿始终:Orchestrator 串行处理所有状态变更,防止同一个 Issue 被派发两次。
WORKFLOW.md:把 Agent 策略放进代码仓库
这是 Symphony 里最值得拿出来单说的设计决策。
其他编排系统通常把 Agent 的行为策略放在服务配置里——谁有权限访问那个服务,谁就控制 Agent 怎么跑。Symphony 把这件事翻了个面:把工作流策略写在代码仓库里的 WORKFLOW.md。
---
tracker:
kind: linear
endpoint: https://api.linear.app/graphql
api_key: ${LINEAR_API_KEY}
project_slug: my-project
active_states: [Todo, In Progress]
terminal_states: [Done, Cancelled]
polling:
interval_ms: 30000
workspace:
root: ./workspaces
agent:
max_concurrent: 10
max_turns: 50
retry_backoff_ms: 60000
---
You are a coding agent working on {{issue.title}}.
{{issue.description}}
Follow the project's CONTRIBUTING.md guidelines.
Commit your changes with a clear message.
YAML 头信息是机器可读的运行时配置,Markdown 正文是渲染后的 prompt 模板。这两个部分加在一起,就是 Agent 运行的完整策略。
为什么放在仓库里? 因为这让策略和代码一起走 review、一起进 CI、一起被版本控制。Agent 怎么跑,和代码怎么写,现在处于同一个治理框架下。
Issue 的生命周期:一台状态机
每个 Issue 在 Symphony 的编排下经历五个状态:
Unclaimed(未分配)
↓ 符合条件
Claimed(已预约)
↓ Agent 启动
Running(运行中)
↓ 失败/重试
RetryQueued(等待重试)
↓ 恢复
Released(已释放)← 成功/终止/取消
“Claimed"状态的意义在于防止重复派发:一旦 Orchestrator 把某个 Issue 标记为 Claimed,其他可能同时轮询的线程不会再为它启动第二个 Agent。
重试使用指数退避:
delay = min(10000 × 2^(attempt-1), max_retry_backoff_ms)
三条安全不变量
规范里明确列出了三条强制性的安全约束,这也是最容易被实现者忽视的部分:
- Agent 启动时工作目录必须等于 workspace_path——任何试图在 workspace 外执行命令的行为都不应被允许
- Workspace 路径必须包含在配置的根目录下——防止路径穿越
- Workspace key 只允许
[A-Za-z0-9._-]——防止注入攻击
这三条约束加在一起,确保每个 Agent 的文件系统影响范围被严格限制在自己的 Issue 工作区内。
技术选型:为什么是 Elixir?
官方参考实现用 Elixir/BEAM 写成。原因是 BEAM 虚拟机对并发进程和进程监控有原生支持——每个 Agent 就是一个独立进程,崩溃后可以被 Supervisor 自动重启,而不影响其他 Agent。
但 Symphony 的规范本身是语言无关的。社区已经出现了 TypeScript、Go、Rust、Java 和 Python 的实现。
Agent 接入:Codex App Server 模式
Symphony 的 Agent Runner 不是直接调用 CLI,而是通过 Codex App Server 的 JSON-RPC API 与 Codex 通信。这个模式允许:
- 以编程方式启动对话线程(thread)
- 流式接收每一轮的执行事件
- 记录 token 用量和速率限制信息
- 一个线程被打断后可以继续,不需要重发原始 prompt
每个 Issue 对应一个 Codex 线程,thread_id + turn_id 组合成 Symphony 内部的 session_id,用于跨轮次追踪进度。
Symphony 的价值不只是"又一个 Agent 框架”,而在于它提供了一套可被 fork 和适配的规范。你的团队不一定要用 Linear,不一定要用 Codex——规范里的状态机、安全约束和 WORKFLOW.md 机制,可以被移植到任何 Issue Tracker + 任何编程 Agent 的组合上。
对于想把 AI 编程真正集成进开发流程(而不是停留在"偶尔问问"阶段)的团队,这份 SPEC.md 值得认真读一遍。
关于
原文:An open-source spec for Codex orchestration: Symphony — OpenAI
GitHub 规范:openai/symphony SPEC.md
关注我获取更多资讯