OpenAI Symphony:把 Issue Tracker 变成编程 Agent 的调度中心

OpenAI 开源了 Symphony——一份用 SPEC.md 写成的 Codex Agent 编排规范。它的核心思路只有一句话:每一个打开的 Issue,都配一个 Agent 去跑。本文拆解它的架构设计、WORKFLOW.md 机制、安全不变量,以及 500% PR 增长数字背后的工程逻辑。

阅读时长: 4 分钟
共 1696字
作者: longlikun

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)

三条安全不变量

规范里明确列出了三条强制性的安全约束,这也是最容易被实现者忽视的部分:

  1. Agent 启动时工作目录必须等于 workspace_path——任何试图在 workspace 外执行命令的行为都不应被允许
  2. Workspace 路径必须包含在配置的根目录下——防止路径穿越
  3. 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

关注我获取更多资讯

月球基地博客公众号二维码,扫码关注获取更多 AI 与编程资讯
📢 公众号
月球基地博客作者个人微信二维码,扫码交流 AI 与编程话题
💬 个人号
使用 Hugo 构建
主题 StackJimmy 设计