← All Articles

Symphony — 把 issue tracker 变成 coding agent 的 control plane

Alex Kotliarskyi, Victor Zhu, Zach Brock · Original

这篇在讲什么

Codex 团队继上一篇”repo 内 0 行人写代码”之后,遇到的下一个瓶颈不是模型能力而是人的注意力——一个工程师同时管 3-5 个 Codex session 就 context switching 累垮。Symphony 是他们的解法:把 Linear(一个流行的项目管理工具)当成 control plane,每个 open ticket 自动派一个 agent workspace,人只看结果不再逐 session 监管。文章同时公开了 Symphony 的开源 spec(github.com/openai/symphony),核心实现是一份 SPEC.md 文件,不是复杂 supervisor 系统。

Layer 1 — 核心论点链

1. 上一阶段的实验跑通了,但撞上新瓶颈

六个月前,Codex 团队为内部生产力工具立了一条强约束:repo 里所有代码必须由 Codex 生成,工程师不写一行。配套是把 repo 改造成 agent-friendly(结构、命名、文档对 agent 友好)、重投自动化测试和 guardrail(护栏,对 agent 行为的硬约束如 lint / test / sandbox),并把 Codex 当作 teammate 而不是工具。这条路跑通了,他们在前一篇 harness engineering(外壳工程,指 agent 跑代码用的执行环境与工具链)里讲过完整经过。但跑通之后,新的瓶颈浮上来——不是模型能力,是 context switching(上下文切换,人在多个并行任务间来回切的心智成本)。

“And it worked, but then we ran into the next bottleneck: context switching.” (Intro)

2. 人的注意力撞了天花板

随着 agentic work 规模扩大,每个工程师同时盯几个 Codex session(会话,与 agent 一次连续对话/任务执行的容器):分派任务、看输出、纠正方向、循环。实测下来 3-5 个就到顶,再多就开始忘哪个 session 在干嘛、在终端之间跳来跳去 nudge agent 回正轨、调试半路 stall 的长任务。作者用了一个相当狠的反讽来定性这件事:

“We had effectively built a team of extremely capable junior engineers, then assigned our human engineers to micromanaging them.” (The ceiling of interactive coding agents)

3. 视角切换:deliverable 才是单位,session/PR 不是

他们意识到自己在优化错的对象——系统围绕 coding session 和 merged PR 组织,但这两者只是手段。真正的工作单位是 deliverable:issue / task / ticket / milestone。如果不再监管 agent,而是让 agent 从 task tracker 自己拉活呢?这个反问就是 Symphony 的起点。

“We realized we were optimizing the wrong thing. We were orienting our system around coding sessions and merged PRs, when PRs and sessions are really a means to an end. Software workflows are largely organized around deliverables: issues, tasks, tickets, milestones.” (A shift in perspective)

4. Symphony 把 Linear 变成 control plane

control plane(控制中枢,决定谁去做什么的那一层)的具体形态是这样:每个 open Linear issue 映射到一个独立的 agent workspace(工作区,agent 跑命令/写代码的隔离目录),Symphony 持续 watch task board,agent crash / stall 就重启它,新工作出现就自动 pick up,整个 workflow 用 ticket status 当 state machine(状态机,按状态触发动作的调度模型)。这层抽象的关键作用是解耦了 work 和 PR:一个 ticket 可以产 0 个 PR(纯 investigation)、可以产多个 PR 跨多个 repo、也可以是分析或调研类。Ticket 因此能代表更大单位的工作——agent 拿到一个高层 ticket 后会自己分析 codebase / Slack / Notion 产出实施计划,approve 后再拆 task DAG(有向无环图,拆解出有依赖关系的子任务网络)按依赖并行执行。

“Some issues produce multiple PRs across repos; others are pure investigation or analysis that never touch the codebase.” (Turning our issue tracker into an agent orchestrator)

5. agent 自己 file 新 ticket,工作循环开始自闭合

实现或 review 中如果 agent 发现 perf 问题、refactor 机会、更好的架构,它会自己 file 新 issue 进队列等评估,其中很多 follow-up 也由 agent 接手。React 升级 ticket 标了 blocked on Vite migration,agents 真的等到 Vite 完成才动 React——DAG 的依赖关系被严肃执行。一个细节很能说明状态:他们团队一个工程师在小木屋蹭着不稳的 wifi,从手机的 Linear app 里发了三个重要改动出去——orchestrator 在 devbox(云端开发盒,远端持续运行的开发环境)上 24/7 跑,他不用本地连任何东西。

6. 效果数据与工作经济学的变化

最直接的效果是产出。OpenAI 内部某些团队三周内 landed PR 数增加 500%,Linear 创始人 Karri Saarinen 也观察到 workspace 创建数飙升。但作者强调更深的变化在团队怎么思考工作:当工程师不再开 Codex session 时,每次代码改动的 perceived cost 变得很低,启动 speculative task(探索性任务,不确定能不能成的小试验)的 cognitive cost 接近零。发起人的边界也变宽——PM 和 Designer 现在能直接 file feature request,不用 checkout repo / 不开 Codex session,拿回来的是含视频走查的 review packet(评审包,含产品里跑通的视频 + 代码 diff 的可评审材料)。Symphony 还把 monorepo(单仓多模块的代码组织方式)的 last-mile 自动化了——CI 监控、rebase(变基,把分支建在最新主干之上)、解冲突、retry flaky check(不稳定但不一定有 bug 的测试),全交给 Symphony shepherd。

“When our engineers no longer spend time supervising Codex sessions, the economics of code changes completely. The perceived cost of each change drops because we’re no longer investing human effort in driving the implementation itself.” (An increase in exploration from working this way)

7. 代价:失去 mid-flight 纠偏

从 ticket 级派活意味着失去实时 nudge agent 的能力,agent 偶尔会跑得完全不对。作者把这种失败当成系统暴露面,而不是临时手动改一下:每次跑偏之后加 guardrail / skill / 文档来补——比如新增 e2e(端到端,模拟真实用户的全链路测试)、用 Chrome DevTools 驱动 app、跑 QA smoke test(冒烟测试,验证关键路径不挂的轻量测试)。也不是所有任务都适合:模糊问题、强判断、需要专业经验的活,仍然得人开 Codex session 直接做——也是工程师最享受的部分。

8. 从 state machine 到 objective,Symphony 实例化成一份 SPEC.md

更深层的教训是:把 agent 当成 state machine 里的 rigid node 不行——模型在变强,会突破你给它划的盒子。早期版本只让 Codex 实现 task,太局限;后来给 gh CLI(GitHub 官方命令行工具)、读 CI log 的 skill,Codex 完全能跑出”closing 老 PR”或”出 abandoned vs completed 报告”这种远超 feature 实现的活。结论是给 objective 不给 strict transition,像好经理给下属派目标。

“We also learned that treating agents as rigid nodes in a state machine doesn’t work well. Models get smarter and can solve bigger problems than the box we try to fit them in.” (Progress comes with new, different problems)

这条心法直接决定了 Symphony 的实现形态——打开 repo 第一眼就能看见:

“Symphony is technically just a SPEC.md file—a definition of the problem and the intended solution. Rather than building a complex supervision system, we defined the problem and intended solutions, giving agents high-level steering.” (Using Symphony to build Symphony)

SPEC 把 service 拆成 6 层(Policy / Configuration / Coordination / Execution / Integration / Observability,从”政策定义”到”可观测性”逐层下沉)和 8 大组件(Workflow Loader / Config Layer / Issue Tracker Client / Orchestrator / Workspace Manager / Agent Runner / Status Surface / Logging)。WORKFLOW.md 是 markdown + YAML front matter,包含 tracker / polling / workspace / hooks(生命周期钩子,在 workspace 创建/run 前/run 后/删除前触发的脚本)/ agent / codex 六类配置块;prompt 用 Liquid template(一种严格模板引擎,未知变量直接 fail 而不是静默忽略)渲染。还有一个重要边界声明:Symphony 只做 scheduler+tracker reader,ticket 写、PR 链接、状态转移由 coding agent 自己用工具完成——spec 不锁死流程,让 agent 自己跑。

📌 金句摘抄

“The agents were fast, but we had a system bottleneck: human attention.” (The ceiling of interactive coding agents)

“It’s become trivial to spin up speculative tasks in Symphony. Try an idea, explore a refactor, test a hypothesis, and only keep the results that look promising.” (An increase in exploration from working this way)

“If the agent gets something wrong, that’s still useful information, and the cost to us is near zero.” (Turning our issue tracker into an agent orchestrator)

“Models get smarter and can solve bigger problems than the box we try to fit them in.” (Progress comes with new, different problems)

“So we eventually moved toward giving agents objectives instead of strict transitions, much like a good manager would assign a goal to a direct report on their team. The power of models comes from their ability to reason, so give them tools and context and let them cook.” (Progress comes with new, different problems)

“Symphony is a scheduler/runner and tracker reader. Ticket writes (state transitions, comments, PR links) are typically performed by the coding agent using tools available in the workflow/runtime environment.” (SPEC.md §1 Problem Statement)

Layer 2 — 我的标注

1. SPEC.md 即 orchestrator——“编排路径之争”工程派的最小落地

mental-models.md 里的”编排路径之争”说的是多 agent 系统里”主 agent 怎么派活”这件事的两条路:工程路线(spec / system reminder / tool description / 文档钉住行为)和算法路线(reward / policy / learned scheduler)。OpenAI 这次完全 lean 工程派——scheduler+runner 写死成代码,但 policy 全靠一份 markdown spec 加几块 YAML 配置。这不是”工程派赢算法派”,而是工程派给出了一个干净的最小工件证明:对足够强的模型,你不需要写调度算法,你只需要写一份合同。这跟你 hub 结构(SKILL.md + lens override + slot injection 进 shared primitive)是同一个动作的两个变体——把 orchestrator 实例化为 spec 而不是命令式代码。值得拿你 hub 和 Symphony spec 摆一起看一遍,看看哪些抽象层是真共通、哪些只是表面相似。

2. 自己批 PR 数指标,又拿 PR 数当头条——典型 OpenAI 营销口径

Section 3 明确说”我们在优化错的东西,PR 和 session 是 means to an end”,Section 6 又用”500% landed PR 增长”作为最显眼的效果证明。如果 PR 数确实是错的指标,正确的做法是给 ticket-level throughput 或 cycle time 数据;用”500% landed PR”做头条等于自己打脸自己的论点。500% 这个数也没基线——哪些 some teams、三周窗口怎么选的、对照组什么样,全没说。这是 OpenAI 营销博客的典型口径,值得当成 sales 文献读,不要当成方法论文献读。Symphony 的 spec 设计本身值得认真学,但效果数据要打折看。

3. “失去 mid-flight 纠偏”和你 hub 的”消化 checkpoint”是同一根轴的两端

Symphony 选择放弃 mid-flight 纠偏换 throughput——一个 ticket 派出去,agent 跑跑跑,错了就再开 issue 修。你的 deep-read hub 选的恰好是反方向:强制”消化 checkpoint”等用户回话才进讨论模块,不让 LLM 一口气把讨论 push 到底。两个选择都不是错的,只是 trade-off 不同——Symphony 在压注 agent 自我纠偏能力(“agent 出错也是有用信息”),你在压注人的判断必须留一个咽喉。这条轴可以拿来校准你自己 hub 设计里类似的决策点:哪些环节是”把 throughput 抢回来”,哪些是”必须留一个 checkpoint 给人”。再延伸一步——Symphony 之所以敢放弃 mid-flight,是因为他们配套加了 e2e / Chrome DevTools / smoke test 这些机器自动验证;你 hub 里如果想砍 checkpoint,配套要先想”什么自动验证能替代 Justin 的判断”。

sources