發布於 2026 年 4 月 27 日
原文連結:https://openai.com/index/open-source-codex-orchestration-symphony/
GitHub 連結:https://github.com/openai/symphony
六個月前,OpenAI 團隊在做一個內部效率工具時,做了一個在當時頗具爭議的決定——整個程式碼倉庫裡不允許有人寫的程式碼,每一行都必須由 Codex 生成。
為了實現這個目標,他們把工程工作流從頭重新設計了一遍:打造了一套對 AI 友善的程式碼倉庫,大力投入自動化測試和防護機制,把 Codex 當成正式的團隊成員來用。這段經歷已經在之前那篇《Harness 工程》的部落格文章裡有詳細記錄。
這套方案確實跑通了,但隨後他們遇到了新的瓶頸——上下文切換。
為了解決這個問題,他們構建了一個叫 Symphony 的系統。Symphony 是一個 AI 編排器,它把 Jira 或 Linear 這類專案管理看板變成了程式碼編寫 AI 的控制中樞:每一個待處理的任務都對應一個 AI,AI 持續運作,人只需要來審查結果就好。
這篇文章講的就是 Symphony 是怎麼做出來的——在某些團隊上,它讓最終合併的 PR 數量提升了 500%——以及如何用它把自己的議題追蹤系統變成一個永不停歇的 AI 編排器。
互動式程式碼 AI 的天花板
程式碼 AI 變得越來越好用,但無論是透過網頁還是命令列,它本質上仍然是一個互動式工具。
隨著 OpenAI 內部 AI 規模的擴大,一種新的負擔開始浮現:每個工程師同時開著幾個 Codex 工作階段,分配任務、看輸出、調整方向,然後循環往復。實際操作下來,大多數人同時管三到五個工作階段還勉強能撐住,超過這個數,效率就開始下滑——忘記哪個工作階段在做什麼,要跳來跳去地在各個終端機裡推動 AI 回到正軌,還要除錯那些跑到一半卡住的長任務。
AI 跑得很快,但瓶頸在人的注意力上。這套做法相當於組了一支能力很強的初階工程師團隊,然後讓人類工程師去盯著他們。這條路走不遠。
換個視角看問題
團隊意識到,最佳化的方向搞錯了。之前的工作流是圍繞「工作階段」和「合併 PR」來組織的,但這兩者只是手段,不是目的。軟體開發的工作本質上是圍繞可交付物來組織的——issues、tasks、tickets、milestones。
於是他們問自己:如果不再直接盯著 AI,而是讓 AI 自己去任務追蹤器裡拉任務來做,會怎樣?
這個想法變成了 Symphony——一份以文件形式寫就的「規範(spec)」,它扮演的是一個監督者的角色,負責編排 AI 的工作。
把議題追蹤器變成 AI 編排器
Symphony 的核心理念非常簡單:每一個待處理的任務,都應該有一個 AI 去把它完成。 不再需要在一堆分頁裡盯著 Codex 工作階段,而是把議題追蹤器變成控制中樞。
在這套工作流裡,每一個 Linear 議題都對應一個獨立的 AI 工作空間。Symphony 持續監聽任務看板,確保每個活躍任務都有 AI 在跑,直到完成為止。AI 掛了或者卡住了,Symphony 會重啟它;新任務出現了,Symphony 會把它撿起來分配出去。
整套工作流基於任務單狀態來驅動,把 Linear 當成一台狀態機來用。
實際用起來,Symphony 把「工作」從「工作階段」和「PR」裡解耦了出來。有些議題會跨多個倉庫產出好幾個 PR,有些純粹是調研分析,根本不碰程式碼。
一旦工作被這樣抽象化,一張任務單就可以代表更大粒度的工作單元。
團隊常用 Symphony 來編排複雜功能開發和基礎設施遷移。比如,可以直接提一個任務讓 AI 分析程式碼庫、Slack 記錄或 Notion 文件,輸出一份實作方案。方案確認後,AI 再生成一棵任務樹,把工作拆解成多個階段並定義好依賴關係。
AI 只會處理沒有被阻塞的任務,所以整個執行過程自然地以最優並行方式展開——比如 React 升級被標記為依賴 Vite 遷移,AI 就會等 Vite 遷移完成後再開始升級 React,完全符合預期。
AI 還會自己建立任務。在實作或審查過程中,它們經常會發現目前任務範圍之外的改進點——效能問題、重構機會、更好的架構方案。遇到這種情況,它們會直接提一個新議題,等人來評估和排程,而這些後續任務往往也會被 AI 接著做掉。
這種工作方式極大地降低了啟動模糊任務的心理成本。AI 做出來的東西完全偏了?也沒關係,這本身就是有價值的資訊,而且成本幾乎為零。提個任務單讓 AI 去探索原型,不滿意直接丟掉就好。
因為編排器跑在開發箱上,永遠不會下線,所以隨時隨地都可以提任務,知道一定會有 AI 來處理。團隊裡就有個工程師,在一個訊號很差的深山小木屋裡,只用手機上的 Linear App,就完成了三個重要的程式碼改動。
工作方式變了,探索性也強了
用 Symphony 之後,最直觀的變化是產出量。在 OpenAI 內部某些團隊,最初三週裡最終合併的 PR 數量增加了 500%。 在公司外部,Linear 創辦人 Karri Saarinen 也注意到在 Symphony 發布前後,工作空間建立量出現了一個明顯的高峰。但更深層的變化,是團隊看待工作的方式。
當工程師不再需要盯著 Codex 工作階段,每一次程式碼改動的「心理成本」就徹底不一樣了。不再需要人來驅動實作本身,每個改動的感知成本大幅下降。
這直接影響了大家的行為:在 Symphony 裡提一個探索性任務變得輕而易舉。試個點子、跑個重構、驗證一個假設,只留下看起來有價值的結果。
同時,發起工作的門檻也降低了。產品經理和設計師現在可以直接往 Symphony 裡提功能需求,不需要懂程式碼,也不需要自己管 Codex 工作階段。他們描述一個功能,收到的是一份完整的審查包,裡面包含功能在真實產品裡運作的螢幕錄影示範。
在大型 monorepo(例如 OpenAI 內部用的那種)裡,Symphony 還有個很厲害的地方——它會盯著 CI,在需要時自動 rebase、解決衝突、重試不穩定的檢查,把改動一路護送到主分支,不需要人來守著。當一張任務單進入 Merging 狀態時,基本上可以放心它能順利落地。
引進 Symphony 之後,更多工作委派給 AI 來做,人的精力可以聚焦在更難、更有探索價值的任務上。
新的工作方式,也帶來了新的問題
這個層級的運作方式自然也有代價。從直接盯著 AI 互動,轉變到在任務單層面分配任務,意味著失去了隨時介入、中途糾偏的機會。有時候 AI 做出來的東西完全不對路,但這些失敗本身是有價值的,它們揭示了系統的漏洞,促使整套機制變得更強健。
面對這種情況,團隊沒有選擇手動修補結果,而是給 AI 增加了防護欄和技能,讓它下次能做對。久而久之,這推動他們不斷往 harness 裡添加新能力:執行端對端測試、透過 Chrome DevTools 操作應用程式、管理 QA 冒煙測試。同時也大幅改善了文件,把「什麼是好的輸出」講得更清楚。
當然,也不是所有任務都適合 Symphony 這種工作方式。有些問題還是需要工程師直接用互動式 Codex 工作階段來做,尤其是模糊的問題,或者需要強判斷力和專業經驗的工作。實際上,這類任務往往也是工程師最感興趣、最享受的那部分。
Symphony 能涵蓋的是大量常規的實作類工作,這樣工程師就能專注於一次只啃一個硬骨頭,而不是在無數小任務之間反覆切換。
團隊還發現,把 AI 當成狀態機裡的死節點來用是行不通的。模型越來越強,能解決的問題規模遠超最初給它劃定的框框。早期做法只是讓 Codex 實作任務,這很快就顯得太侷限了。Codex 完全有能力建立多個 PR、讀取審查回饋並處理修改意見。於是給它配上了 gh CLI、讀取 CI 日誌的能力等工具,讓它去做更多事情,例如關閉舊 PR、輸出已完成與已放棄工作的報告。這些任務完全超出了最初「實作功能」這個框的範圍。
最終,團隊逐漸轉向給 AI 分配目標,而不是規定嚴格的狀態轉換流程——就像一個好的管理者給直屬下屬分配一個目標,而不是手把手指定每一個步驟。模型的價值在於它的推理能力,給它工具和上下文,讓它自己去發揮。
用 Symphony 來構建 Symphony
打開 Symphony 的程式碼倉庫,第一眼就會發現一個有意思的事:Symphony 在技術層面只是一個 SPEC.md 檔案——一份對問題的定義和預期解決方案的描述。團隊沒有去搭建一套複雜的監督系統,而是把問題和預期方向定義清楚,給 AI 做高層次的引導。
# Symphony Service Specification
Status: Draft v1 (language-agnostic)
Purpose: Define a service that orchestrates coding agents to get project work done.
## 1. Problem Statement
Symphony is a long-running automation service that continuously reads work from an issue tracker
(Linear in this specification version), creates an isolated workspace for each issue, and runs a
coding agent session for that issue inside the workspace.
...參考實作是用 Elixir 寫的——因為當程式碼的成本幾乎為零時,終於可以根據語言的特性來選擇語言了,而 Elixir 在並行處理方面有著天然的優勢。但核心思路其實就是一個 Markdown 文件,團隊鼓勵大家直接把這份 spec 丟給自己喜歡的程式碼 AI,讓它自己去實作一個版本。
Symphony 的第一個版本不過是一個跑在 tmux 裡的 Codex 工作階段,輪詢 Linear 然後為新任務啟動子 AI。能用,但不夠可靠。第二個版本住進了主專案倉庫,這個倉庫本來就是為 AI 設計的,團隊之前就建好了讓 AI 能高品質工作的 harness,Symphony 只是把這一切連接起來。
基礎功能搭好之後,團隊開始用 Symphony 來構建 Symphony 自己。
在公司內部展示了系統自動管理任務、自動附上工作證明影片之後,反響出乎意料地好:Symphony 的專案頻道開始快速增長,各個團隊自發地開始使用。在 OpenAI,內部產品市場契合度是對外發布的前提條件,而內部的使用數據已經清楚地表明,Symphony 值得分享出去。
於是團隊把核心思路抽象成一個獨立的 SPEC.md,讓 Codex 來實作它。參考實作選了 Elixir,然後持續在 spec 和實作上同步迭代。為了打磨好 spec,他們還讓 Codex 分別用 TypeScript、Go、Rust、Java、Python 實作了一遍,把結果拿來找 spec 裡的歧義、簡化系統設計。每個語言都跑通了。
整個構建過程中,團隊去掉了大量非必要的複雜度,例如對特定倉庫或 Linear MCP 的依賴。Symphony 不再依賴內部倉庫或內部工作流,核心方法變得非常簡潔:
對於每一個待處理的任務,保證有一個 AI 在它自己的工作空間裡持續運作。
除了幫助完成具體工作,開發工作流本身也變成了 AI 懂得遵循的東西。這套流程——處理一個議題、checkout 倉庫、把它設為「進行中」讓 PM 知道有人在跟、添加 PR、改為「Review」狀態、附上影片等等——之前是工程師靠默契維持的,從未文件化過。現在這些都寫進了 WORKFLOW.md,Symphony 確保 AI 都能按步驟走。如果以後想讓 AI 給完成的工作附上自我反思,加進 WORKFLOW.md 就好,Symphony 會引導 AI 走到那一步。
整個過程還用上了 Codex 的 App Server 模式——一種專為無頭執行設計的內建模式,可以透過完善的 JSON-RPC API 來程式化地與 Codex 互動,例如啟動一個執行緒、回應 turn 事件。這比透過 CLI 或 tmux 工作階段來互動要方便、可擴展得多。
Codex App Server 非常契合這個場景:在利用 Codex 提供的 harness 的同時,還有足夠多的旋鈕和鉤子可以接入。比如,為了避免把 Linear 存取權杖暴露給子 AI,團隊使用了動態工具呼叫,把原始的 linear_graphql 函式暴露給 AI——可以對 Linear 執行任意請求,而不需要透過 MCP 或把權杖暴露給容器。
下一步
Symphony 是一個刻意保持極簡的編排層。開源它的目的,是展示 Codex App Server 與 Linear 等工作流工具搭配時的潛力。作為參考實作,團隊不打算把 Symphony 當成一個獨立產品來持續維護,而是把它當成一份藍圖——就像當初很多開發者把那篇 harness 工程的部落格文章丟給自己的 AI 來搭建倉庫腳手架一樣,希望大家也把 Symphony 的 spec 和倉庫丟給自己喜歡的程式碼 AI,構建出適合自己團隊的版本。
真正的力量來自 Codex 和它的 App Server,Symphony 只是把 Codex 和 Linear 這兩個已經在用的東西連接起來,解決了工作管理這個問題。隨著程式碼 AI 的推理能力和指令遵循能力不斷提升,其他公司的瓶頸也可能會從「寫程式碼」轉向「管理 AI 工作」。讓人興奮的是,在這類程式碼 AI 系統上做實驗的門檻,現在已經出乎意料地低了。想試什麼,直接用 Codex 去做就好。
社群反響
自發布以來,這個專案已經在 GitHub 上累積了超過 15,000 顆星(截至 4 月 23 日)。
社群已經有人在行動了——有人一鍵讓 AI 在自己的 Elixir ERP 應用裡做了一個完整的儀表板,配上 GenServer 和自定義 AI 來擷取生產環境 bug 並自動提交修復;有人用 Go 搭配 Charm CLI TUI 技術堆疊實作了自己的版本;還有人把 Symphony 改造成了支援 Claude Code 和 GitHub Issues 的版本,並透過 Homebrew 提供安裝。
這正是發布一份開放規範的意義所在——給出方向,讓社群自己去跑。