乐于分享
好东西不私藏

如果你用AI开发工具在写代码过程中遇到需要不停去监督AI干活,并且不厌其烦对其调教,codex开源的这个 Symphony也许能帮到你

如果你用AI开发工具在写代码过程中遇到需要不停去监督AI干活,并且不厌其烦对其调教,codex开源的这个 Symphony也许能帮到你

写在前面:

你有没有过这种经历?你如果是用AI做开发的重度体验者,本来想让 AI 帮你写代码省点力,结果你花了整整一天盯着它干活:一会儿要纠正它的错误,一会儿要给它补充上下文,一会儿要重新写提示词,一会儿还要检查它生成的代码有没有 bug;尤其是在同一个工具里开多个会话的时候,你会发现不同的会话的上下文有的时候并没有被保存和互用,新开一个会话,需要扫描整个项目,浪费token就是浪费钱啊,有没有更好的办法可以解决这个问题呢? codex最近发了一篇文章,描述了他们解决办法,并且开源了这个工具,大家可以使用看看能否解决到这个问题。


其实使用AI开发这个过程,现在开发者是又爱又恨,像我这种每天坐在电脑面前十多个小时,感觉AI好像又好用了好像提效也不是那么明显,尤其上盯着Token消耗的账单的时候,或者使用AI修改一个很简单的问题的时候,你会尤其是烦躁。你会很想把AI工具丢掉重新回到“古法编程”,这不是你一个人有这个想法,也不完全是 AI 能力不够的问题。现在 AI 编程最大的瓶颈,已经悄悄从 “模型能写多少代码” 变成了 “人能监督多少 AI”。OpenAI 的工程师们做过测试:一个人最多只能同时管理 3 到 5 个 AI 编码会话,再多就会因为频繁的上下文切换而彻底崩溃。

我们都变成了 AI 的 “监工”,想想看,现在我们是怎么用 AI 写代码的:

打开一个新的 AI 会话,写一大段提示词描述需求,等 AI 生成代码,检查有没有问题,如果有问题,再写提示词让它修改,重复这个过程直到代码能用。

一个 AI 还好。但如果你的项目有 10 个 bug 要修,20 个小功能要加呢?你就会变成一个手忙脚乱的 “AI 保姆”:同时开着五六个终端窗口,每个窗口里都有一个 AI 在干活,你得挨个喂提示词,挨个检查输出,挨个处理它们遇到的问题。

更糟糕的是,AI 不会自己停下来。它可能会在一个错误的方向上越走越远,直到你发现并纠正它。这意味着你必须时刻盯着它,不能分心。结果就是,AI 确实在帮你写代码,但你却比以前更累了。

1. OpenAI 的解决方案:Symphony

面对这个所有人都在头疼的问题,OpenAI 没有去做一个更大的模型,也没有做一个能同时显示 20 个窗口的仪表盘。他们做了一件更根本的事情:彻底重写了人和 AI 之间的协作流程。

这个方案叫做Symphony,已经在 GitHub 上开源了。它不是一个新的聊天式编程助手,也不是一个 IDE 插件。它更像是一个 “AI 自动调度中心”,让 AI 自己管理自己,而你只需要做最终的验收工作。

Symphony 的核心理念非常简单:别再监督 AI 了,让 AI 从你的任务看板上自己拉活干。

2. Symphony 是怎么工作的?

Symphony 的工作流程和你现在的开发流程几乎一模一样,只是把中间最累人的部分自动化了:

你在任务看板上创建任务,就像平时一样,在会话里,写清楚你要做什么:”修复用户登录时的密码错误提示”、”给商品列表添加分页功能”。不需要写复杂的提示词,就用你平时和团队沟通的语言。

  • Symphony 自动发现新任务

Symphony 会每隔一段时间轮询你的任务看板。当它看到一个标记为 “待处理” 的任务时,就会自动为这个任务创建一个完全隔离的工作空间和一个独立的 Git 分支。

  • AI 在沙盒里独立完成任务

Symphony 会启动一个 Codex AI 智能体,让它在这个隔离的沙盒里工作。AI 会自己理解需求,自己写代码,自己跑测试,自己处理遇到的问题。整个过程不需要你任何干预。

  • AI 提交 “工作量证明”

这是 Symphony 最厉害的地方。AI 写完代码后,不会直接把代码甩给你。它会自动生成一套完整的 “工作量证明”,包括:

所有单元测试和集成测试的运行结果,代码审查意见和复杂度分析

代码变更的详细说明,甚至还有一个代码走查视频,演示它写的代码是怎么工作的,你只需要做最终验收,当所有测试都通过,所有准备工作都完成后,AI 会自动创建一个 Pull Request。你只需要看一下 AI 提交的 “工作量证明”,如果觉得没问题,点一下批准,代码就会自动合并到主分支。

3. 为什么 Symphony 能解决问题?

Symphony 和其他 AI 编程工具最大的区别在于,它改变了人和 AI 的关系:

从 “同步监督” 变成 “异步验收”:你不需要坐在那里盯着 AI 干活,它会自己跑。你可以在任何方便的时候来检查结果。

从 “管理 AI 会话” 变成 “管理工作任务”:你不需要关心有多少个 AI 在运行,它们在哪个分支上干活。你只需要关心任务有没有完成,质量好不好。

从 “人适应 AI” 变成 “AI 适应人”:你不需要学习怎么写完美的提示词,也不需要改变你的工作习惯。AI 会适应你已经在用的工具和流程。

OpenAI 自己的团队使用 Symphony 后,效果非常惊人:在前三周,一些团队的 Pull Request 数量就增长了 500%。这不是因为 AI 写代码变快了,而是因为一个工程师现在可以同时管理几十个 AI 任务,而不是只能管理 3 到 5 个。

4. 如何开始使用 Symphony

Symphony 目前处于工程预览阶段,采用 Apache 2.0 开源协议。你可以在 GitHub 上找到官方的 Elixir 实现,也有社区贡献的 TypeScript 版本。

最简单的开始方式是:

克隆官方仓库:https://github.com/openai/symphony

按照 README 中的说明配置你的 Linear 或 GitHub Issues 账号

运行启动脚本

在你的任务看板上创建一个任务,标记为 “Todo”

等待 Symphony 自动处理

需要注意的是,Symphony 目前最适合在有良好测试覆盖的代码库中使用。如果你的项目没有自动化测试,AI 就无法验证自己写的代码是否正确,你还是需要手动检查。

5. 写在最后

AI 编程的发展速度快得惊人。一年前,我们还在为 AI 能补全一行代码而惊叹;现在,AI 已经能独立完成整个功能了。但随着 AI 能力的提升,我们也遇到了新的问题:如何有效地管理和利用这些 AI 能力。

Symphony 给了我们一个很好的答案:不要试图去监督每一个 AI 的每一个动作,而是要建立一个系统,让 AI 在这个系统里可靠地工作,而人只需要在最高的层面上做决策和验收。

我最近其实就非常讨厌当 AI 的 “监工”,有的时候给codex下一个任务,一会儿又得回去看一眼,看看他改的如何了,最近,我会试试 Symphony,并写一个测评,看看是不是能达到原文那样的效果。

6. 文章链接原文

链接:

https://openai.com/index/open-source-codex-orchestration-symphony/

7. AI直接翻译的内容,供参考

Codex 编排开源规范:Symphony

作者:Alex Kotliarskyi、Victor Zhu、Zach Brock

收听本文 13:57 分享

六个月前,在开发一款内部生产力工具时,我们团队做出了一个在当时颇具争议的决定:我们将完全不编写任何人工代码来构建代码库。项目仓库中的每一行代码都必须由 Codex 生成。

为了实现这一目标,我们彻底重新设计了工程工作流。我们构建了对代理友好的代码仓库,大力投入自动化测试和防护机制,并将 Codex 视为一名正式的团队成员。我们在之前关于工程 harness 技术的博客文章中记录了这一历程。

这一尝试取得了成功,但随后我们遇到了下一个瓶颈:上下文切换

为了解决这个新问题,我们构建了一个名为 Symphony 的系统。Symphony是一个代理编排器,它能将 Linear 这类项目管理看板转变为编码代理的控制平面。每个待处理任务都会分配一个专属代理,代理会持续运行,最终由人类审核结果。

本文将介绍我们如何创建 Symphony—— 它使部分团队的合并拉取请求数量提升了 500%—— 以及如何使用它将你自己的问题跟踪器转变为全天候运行的代理编排器。

交互式编码代理的天花板

尽管编码代理的使用门槛越来越低,但无论是通过网页应用还是命令行界面访问,它们本质上仍然是交互式工具。

随着 OpenAI 内部代理工作规模的扩大,我们发现了一种新的负担。每位工程师需要打开多个 Codex 会话、分配任务、审核输出、引导代理,然后重复这一过程。在实际操作中,大多数人最多只能同时舒适地管理 3-5 个会话,超过这个数量后,上下文切换就会变得非常痛苦。再往后,生产力会急剧下降:我们会忘记哪个会话在做什么,在多个终端之间跳转来让代理回到正轨,还要调试中途卡住的长时间运行任务。

代理的速度很快,但我们遇到了系统瓶颈:人类注意力。我们实际上组建了一支能力极强的初级工程师团队,却让我们的人类工程师去做微观管理他们的工作。这种模式无法规模化。

视角的转变

我们意识到自己优化错了方向。我们一直在围绕编码会话和合并的 PR 来构建系统,但 PR 和会话其实只是达成目的的手段。软件工作流本质上是围绕可交付成果组织的:问题、任务、工单、里程碑。

于是我们问自己:如果我们不再直接监督代理,而是让它们从我们的任务跟踪器中主动拉取工作,会发生什么?

这个想法催生了 Symphony—— 一份作为监督者来编排代理工作的书面规范。

将问题跟踪器转变为代理编排器

Symphony 源于一个简单的理念:任何待处理的任务都应该由代理自动接手并完成。我们不再需要在多个标签页中管理 Codex 会话,而是将问题跟踪器变成了控制平面。

在这种架构下,每个打开的 Linear 工单都对应一个专属的代理工作区。Symphony 会持续监控任务看板,确保每个活跃任务都有一个代理在循环运行,直到任务完成。如果代理崩溃或卡住,Symphony 会重启它;如果有新任务出现,Symphony 会立即接手并开始组织工作。

我们基于工单状态构建了工作流,将任务管理工具 Linear 用作状态机。

编码代理将 Linear 作为状态机与我们协同工作。

在实际应用中,Symphony 将工作与会话、拉取请求解耦。有些问题会跨仓库产生多个 PR,而有些则是纯粹的调查或分析工作,根本不会触及代码库。

一旦工作被这样抽象化,工单就可以代表更大的工作单元。

我们经常使用 Symphony 来编排复杂的功能开发和基础设施迁移。例如,我们可能会提交一个任务,要求代理分析代码库、Slack 或 Notion 中的信息,并生成一份实施计划。当我们对计划满意后,代理会生成一棵任务树,将工作分解为多个阶段并定义任务之间的依赖关系。

代理只会开始处理未被阻塞的任务,因此执行过程会自然且最优地以并行方式展开,形成一个有向无环图(DAG)。例如,我们将 React 升级标记为依赖于 Vite 迁移。正如预期的那样,代理只有在 Vite 迁移完成后才会开始升级 React。

代理还可以自己创建工作。在实施或审核过程中,它们经常会发现超出当前任务范围的改进点:性能问题、重构机会或更好的架构。当这种情况发生时,它们只需提交一个新工单,我们可以在之后评估并安排时间 —— 这些后续任务中的许多也会被代理自动接手。虽然我们会监督这一过程,但代理会保持工作的条理性并推动其向前发展。

这种工作方式极大地降低了启动模糊任务的认知成本。如果代理做错了,那仍然是有用的信息,而我们付出的成本几乎为零。我们可以非常低成本地提交工单让代理去做原型设计和探索,然后丢弃任何我们不喜欢的结果。

由于编排器运行在开发服务器上且永不休眠,我们可以从任何地方添加任务,并知道代理会接手它。例如,我们团队的一位工程师在一个网络很差的舒适小屋里,通过手机上的 Linear 应用完成了三项重大变更。

这种工作方式带来的探索性提升

在观察使用 Symphony 工作的效果时,最明显的变化是产出量。在 OpenAI 的部分团队中,我们看到合并的 PR 数量在前三周内增加了 500%。在 OpenAI 之外,Linear 创始人 Karri Saarinen 也提到,随着 Symphony 的发布,创建的工作区数量出现了激增。然而,更深层次的转变是团队对工作的思考方式。

当我们的工程师不再需要花费时间监督 Codex 会话时,代码变更的成本结构发生了彻底改变。由于我们不再投入人力来推动实施本身,每次变更的感知成本大幅下降。

这改变了我们的行为。在 Symphony 中启动探索性任务变得轻而易举:尝试一个想法、探索一次重构、验证一个假设,只保留那些看起来有前景的结果。

它还扩大了能够发起工作的人员范围。我们的产品经理和设计师现在可以直接向 Symphony 提交功能需求。他们不需要检出代码库或管理 Codex 会话,只需描述功能,就能收到一份包含功能在真实产品中运行的视频演示的审核包。

Symphony 在大型单体仓库(比如 OpenAI 内部使用的那个)中也表现出色,在这些仓库中,合并 PR 的最后一步往往缓慢且脆弱。该系统会监控 CI 流程、在需要时进行变基、解决冲突、重试不稳定的检查,并全程引导变更通过流水线。当工单到达 “合并” 状态时,我们有很高的信心认为变更会在无需人工干预的情况下进入主分支。

Symphony 实施前后对比实施 Symphony 后,我们将更多工作委托给代理,专注于更困难、更具探索性的任务。

进步伴随着新的、不同的问题

在这个级别上运行也存在权衡。当我们从交互式引导代理转变为在工单级别分配任务时,我们失去了在执行过程中不断微调并在需要时纠正方向的能力。有时代理会产出完全偏离目标的结果。但这也是有用的 —— 这些失败暴露了系统中的漏洞,并帮助我们使其更加健壮。

我们没有手动修补结果,而是添加了防护机制和技能,以便代理下次能够成功。随着时间的推移,这促使我们为 harness 添加了新功能,比如运行端到端测试、通过 Chrome DevTools 驱动应用以及管理 QA 冒烟测试。我们还显著改进了文档,并明确了 “好” 的标准是什么。

并非所有任务都适合 Symphony 的工作方式。有些问题仍然需要工程师直接使用交互式 Codex 会话,尤其是那些模糊不清或需要强大判断力和专业知识的工作。实际上,这些通常是我们的工程师最感兴趣和最享受的任务。

不同之处在于,Symphony 可以处理大部分常规实施工作。这让工程师能够一次专注于一个难题,而不是不断在小任务之间切换上下文。

我们还了解到,将代理视为状态机中的刚性节点效果不佳。模型变得越来越智能,能够解决比我们试图限制它们的范围更大的问题。我们早期的代理工作只要求 Codex 实施任务,这种方法被证明过于局限。Codex 完全有能力创建多个 PR,以及阅读审核反馈并解决问题。因此,我们为它提供了工具 ——gh CLI、读取 CI 日志的技能等 —— 现在我们可以要求 Codex 做更多事情,比如关闭旧 PR 或生成已完成与已放弃工作的报告。这些类型的任务远远超出了最初的功能实施范围。

因此,我们最终转向了给代理分配目标而不是严格的转换规则,就像优秀的管理者会给团队成员分配目标一样。模型的力量来自于它们的推理能力,所以给它们工具和上下文,让它们自由发挥。

使用 Symphony 构建 Symphony

当你打开 Symphony 代码仓库时,你会注意到的第一件事是,Symphony 从技术上讲只是一个SPEC.md文件 —— 一份对问题和预期解决方案的定义。我们没有构建复杂的监督系统,而是定义了问题和预期解决方案,为代理提供高层引导

目的:定义一个编排编码代理以完成项目工作的服务。## 1. 问题陈述Symphony是一个长期运行的自动化服务,它持续从问题跟踪器(本规范版本中为Linear)读取工作,为每个问题创建一个隔离的工作区,并在该工作区内为该问题运行一个编码代理会话。该服务解决了四个运营问题:- 将问题执行转变为可重复的守护进程工作流,而非手动脚本。- 在每个问题的工作区中隔离代理执行,使代理命令仅在每个问题的工作区目录中运行。- 将工作流策略保存在代码库中(`WORKFLOW.md`),使团队能够将代理提示和运行时设置与代码一起版本化。- 提供足够的可观测性来操作和调试多个并发代理运行。实现应明确记录其信任和安全态势。本规范不要求单一的审批、沙箱或操作员确认策略;某些实现可能针对具有高信任配置的可信环境,而其他实现可能需要更严格的审批或沙箱。重要边界:- Symphony是一个调度器/运行器和跟踪器读取器。- 工单写入(状态转换、评论、PR链接)通常由编码代理使用工作流/运行时环境中可用的工具执行。- 成功的运行可能在工作流定义的交接状态(例如"人工审核")结束,而不一定是"完成"状态。

(完整规范内容见原文,此处为节选)

参考实现是用 Elixir 编写的 —— 因为当代码实际上变得免费时,你终于可以根据语言的优势来选择它们,比如 Elixir 的并发能力 —— 但核心思想可以用一个简单的 Markdown 文档来表达。我们鼓励你让你最喜欢的编码代理阅读这份规范,让它实现自己的版本。

Symphony 的第一个版本只是一个在 tmux 中运行的 Codex 会话,轮询 Linear 并为新任务生成子代理。它能工作,但不是特别可靠。第二个版本存在于我们的主项目仓库中,该仓库是为代理设计的。我们已经构建了代理 harness,为代理提供在这个仓库中高质量工作所需的技能和上下文,因此 Symphony 只是将它们连接起来。

一旦基本功能存在,我们就使用 Symphony 来构建 Symphony。

当我们内部演示这个管理任务并附上工作证明视频的系统时,反响非常积极:我们的 Symphony 项目频道迅速壮大,公司内部的团队开始自发地使用它。在 OpenAI,内部产品市场契合度是对外发布的先决条件。基于我们在 OpenAI 内部看到的使用情况,我们清楚地意识到应该将 Symphony 分享给公司以外的人。

因此,我们将这个想法提取到一个独立的SPEC.md文件中,并要求 Codex 实现它。对于参考实现,我们选择了 Elixir—— 一种相对小众但拥有出色的并发进程编排和监督原语的语言。Codex 一次性构建了 Elixir 实现,然后我们从那里不断迭代规范和实现。为了完善规范,我们甚至要求 Codex 用其他几种语言实现它 ——TypeScript、Go、Rust、Java、Python—— 并利用这些结果来识别歧义并简化系统。它在每种语言中都取得了成功。

在构建 Symphony 的过程中,我们消除了很多偶然的复杂性,比如对特定仓库或 Linear MCP 的依赖。Symphony 不再依赖我们的内部仓库或工作流。核心方法变得非常简单:

对于每个待处理任务,保证有一个代理在其自己的工作区中运行。

除了帮助完成活跃工作外,开发工作流现在也成为了代理了解并遵循的东西。开发工作流 —— 处理一个问题、检出仓库、将其标记为 “进行中” 以便产品经理知道它正在被处理、添加 PR、将其移至 “审核” 状态、附上视频等 —— 现在被记录在一个简单的WORKFLOW.md文件中。所有这些都是人类曾经遵循的过程,但从未被记录下来。我们现在不再依赖这套隐含的步骤,而是将其文档化,Symphony 确保代理遵循它。这让我们能够构建与我们并肩工作的代理。如果我们决定代理还应该在完成的工作上附上自我反思,我们只需将其添加到WORKFLOW.md中,Symphony 就会引导代理完成这一步。

我们还使用了 Codex 的应用服务器模式——Codex 内置的无头模式。这种模式允许我们运行 Codex,并通过一个文档完善的 JSON-RPC API 以编程方式与它通信,用于启动线程或响应回合等操作。这比尝试通过 CLI 或实时 tmux 会话与 Codex 交互更加方便和可扩展。

Codex 应用服务器非常适合我们的用例:我们利用了 Codex 提供的 harness,同时拥有可以插入的旋钮和钩子。例如,为了避免将 Linear 访问令牌暴露给子代理,我们使用动态工具调用来暴露原始的linear_graphql函数,该函数可以对 Linear 执行任意请求,而无需依赖 MCP 或将访问令牌暴露给容器。

下一步

Symphony 是一个有意设计得极简的编排层。我们将其开源,是为了展示 Codex 应用服务器与 Linear 等不同工作流工具结合使用时的强大功能。因此,我们不打算将 Symphony 作为独立产品进行维护。可以将其视为一个参考实现。就像许多开发者让他们的编码代理阅读工程 harness 技术的博客文章来搭建他们的仓库一样,我们希望你让你最喜欢的编码代理阅读 Symphony 规范和代码仓库,构建适合你自己环境的版本。

真正的力量来自于 Codex 及其应用服务器。Symphony 只是将我们已经在使用的 Codex 和 Linear 连接起来,以解决工作管理问题的一种方式。随着编码代理在推理和遵循指令方面变得越来越好,我们怀疑其他公司的瓶颈也将从编写代码转向管理代理工作。令人兴奋的是,现在实验这些编码代理系统的门槛低得惊人。你可以直接用 Codex 来构建东西。

社区致谢

我们很高兴看到工程社区在发布后的几周内就开始使用 Symphony,截至 4 月 23 日,它已在 GitHub 上收获超过 15000 颗星标。