過去半年看了不少 coding agent 框架,從 SWE-agent、ralph、gnhf 一路到各種「ralph 風格」實作,共通模式都偏 single-task:丟一張票、開一支 agent、完成就退場。這套模型在解單顆 issue 的時候很自然,但一旦想把它擴展到一個團隊的工作流程上,問題就接踵而來——agent 之間怎麼協調、誰拿哪張票、撞在同一個檔案怎麼辦、跑掛了誰負責收屍。多半的開源實作把這層責任丟給呼叫方自己處理。
2026-03-04 OpenAI 在 openai.com/index/open-source-codex-orchestration-symphony 釋出了一個有趣的東西:一個用 Elixir 寫的 agent 編排框架,名字叫 Symphony,MIT 授權直接放上 GitHub。它不解決「單顆 task 怎麼跑」這個問題——這是 Codex 的工作——而是回答「一個團隊規模的 task board,要怎麼長出 N 個自治 agent 同時跑」。
更有意思的是介面設計:它把 Linear 或 GitHub Project 的任務板直接當成 control plane,每張 open ticket 就自動派一支 agent 去做,跑完自己 commit、自己跑 CI、自己開 PR 回填到 ticket。OpenAI 自家在內部使用一段時間後,對外講出一個讓人有點難相信的數字:landed PR 數量提升了 5 倍。這篇就把它的設計、為什麼選 Elixir、跟其他 agent 框架的差異、實際接 Linear 的步驟,以及上 production 前需要注意的雷一次拆開。

一、從 single-task agent 到團隊規模 orchestration
過去一年的 coding agent 大致可以分成兩類。一類是 single-shot:丟一個 issue 進去,agent 跑完之後產出一個 patch 或 PR,整支進程就結束。SWE-agent、原版的 Devin demo、各種 ralph-style 腳本都屬於這類。另一類是 loop:agent 永遠在跑,自己挑事情做,做完繼續挑下一件,沒有「結束」這回事。gnhf、Aider --auto、Cursor 的 background agent 偏向這個方向。
Symphony 想要的是第三種:team-level orchestration——同時跑數十到數百支 agent,每支對應一張 ticket,跑完互不干擾,跑掛了自動重啟,整體有 dashboard 可以觀察。這個訴求乍看是「N 倍的 single-task」,但真的去實作會發現難度跳了一個量級:
- 狀態管理:每張 ticket 對應的 agent 都要有自己獨立的對話歷史、檔案 lock、context window,不能互相污染
- 失敗隔離:100 支 agent 中有一支 OOM,不能拖垮其他 99 支
- 資源排程:repo 同時被多個 agent 改,merge conflict 怎麼處理;同一張票想同時動兩個檔案誰先誰後
- 可觀測性:哪張票卡了多久、哪支 agent 燒了多少 token、哪張 PR 因為 CI 紅了被退回,都得有得查
這幾個問題如果用 Python + asyncio 解,會發現 Python 的 process 模型很難給每個 agent 一個獨立、輕量、可監控的 unit。多半實作會走 thread pool 或 celery worker,但這兩條路都不夠輕——一支 thread 開銷 8MB,celery worker 動輒要外掛 Redis 跟 supervisor 腳本。
Symphony 的選擇是繞開這層整個跳到 BEAM(Erlang 虛擬機,Elixir 的 runtime)。每一支 agent 直接是一個 BEAM process,記憶體開銷大約 2KB,十萬個一起跑也不會喘。這就是為什麼整個框架語言選 Elixir 的核心理由。
1.1 為什麼是 Elixir 而不是 Python
Elixir 在 2026 年的 AI 生態圈是相對小眾的選擇。Python 仍然是 99% agent 框架的預設語言。但仔細看 agent loop 的本質——「等一個 LLM response、跑一個 tool call、把結果塞回 context、再等下一個 response」——它根本不是 CPU bound 任務,是經典的 IO 並發問題。BEAM 在這方面的優勢非常明確:
- preemptive scheduling:每支 agent 跑超過一定 reduction 就被排程器強制切換,不會有「某支 agent 卡死整個 worker pool」的情況
- let it crash:agent 跑掛就讓它掛,supervisor 自動重啟,這跟 LLM 不可預測的失敗模式(rate limit、context overflow、tool error)很搭
- process isolation:每支 agent 自己的 heap,崩了不污染其他人;這在 Python multiprocessing 要花很多力氣才能做到
- distributed by default:BEAM 內建 node-to-node 通訊,多機部署不用另外架 message queue
OpenAI 官方部落格的說法是:「agent loop's reliance on long-running, fault-tolerant processes maps naturally to BEAM's design.」翻譯成白話就是「Erlang 為什麼從 1990 年代就被電信業拿來跑 99.999% uptime 的交換機,這套經驗剛好可以拿來跑 100 支 agent」。
二、Symphony 的核心架構與 supervision tree
Symphony 的內部抽象有三層,由上而下:
2.1 Conductor(指揮)
這是整個系統的 entry point,唯一一支跨 ticket 共享的 process。它的工作有三個:
- 拉取任務板:定期 poll Linear / GitHub Project API,看哪些 ticket 是
open且符合 agent-eligible label - 分派 agent:對每張新進來的 ticket,spawn 一支對應的 agent process
- 資源仲裁:當兩支 agent 想動同一個檔案(依 git diff 估計),決定誰先誰後
Conductor 本身不跑 LLM call,只做 routing 跟 lock。
2.2 Agent(執行者)
每支 agent 是一個獨立 BEAM process,內部跑五種角色:
| 角色 | 職責 |
|---|---|
| Planner | 拆解 ticket 描述,產出 sub-task 清單跟依賴順序 |
| Coder | 呼叫 OpenAI Codex API 寫 code |
| Tester | 寫 unit test、跑測試、收集 coverage |
| Reviewer | 對自己產出的 patch 做 self-review,跑安全性 / lint 檢查 |
| Deployer | git push、開 PR、把 PR 連結貼回 ticket |
這五個角色不是五支 process,而是同一支 agent process 的不同階段——Planner 跑完把結果丟給 Coder,狀態一路傳遞到 Deployer。會這樣設計是因為它們共享同一個 ticket 的上下文,拆成多支 process 反而要額外搬資料。
2.3 Supervisor(看守)
Symphony 的 supervision tree 是經典的 OTP 結構:
Application Supervisor
├── Conductor (one_for_one)
└── Agent Pool Supervisor (one_for_one)
├── Agent #1 (transient)
├── Agent #2 (transient)
└── Agent #N (transient)
one_for_one 表示一支子進程掛掉只重啟那一支,不會牽連其他人。transient 表示如果是正常結束(PR 開好了、ticket 關了)就讓它退場,異常結束才重啟。這跟下面這幾個失敗模式正好對得上:
- Agent OOM:自動重啟,從上一個 checkpoint 繼續
- Codex API 5xx:retry with exponential backoff,上限 3 次
- CI 紅了:agent 進入 retry 模式,根據錯誤訊息自我修復後重新 push
- Conductor 掛了:只有它自己重啟,所有 agent 不受影響
OpenAI 官方提到的 automatic agent restart on failure + configurable restart strategies 就是在講這層。

三、實際部署:把一張 Linear ticket 接過去
正式進到實作之前,要先講一句:到撰文的 2026-04-23 為止,Symphony 的 GitHub repo 累積 15K+ stars、issue 跟 PR 都還在快速堆積中,OpenAI 自己也說它是「explicitly early-stage software」。下面的指令是依照 README 跟官方 blog 整理出來的最小可跑配置,正式上 production 前一定要對著最新 release notes 再走一次。
3.1 環境前置
Symphony 需要的東西不多,但 Elixir 跟 OTP 要對齊版本:
- Elixir
1.17+/ Erlang/OTP27+ - PostgreSQL
15+(存 agent state 跟 audit log) - Redis(optional,做 rate limit 跟 distributed lock)
- OpenAI API key(Codex 跟 GPT 都會打)
- Linear API key 或 GitHub fine-grained PAT(讀寫 task board)
部署形態官方建議走 Phoenix LiveView 的 dashboard + Postgres 做狀態持久化。多 node 部署直接用 BEAM 內建的 :net_kernel 就能組 cluster,不用額外服務。
3.2 接 Linear 的最小步驟
# 1. clone
git clone https://github.com/openai/symphony && cd symphony
# 2. 安裝相依
mix deps.get
mix ecto.create && mix ecto.migrate
# 3. 環境變數
cat > .env <<EOF
OPENAI_API_KEY=sk-...
LINEAR_API_KEY=lin_api_...
LINEAR_TEAM_ID=TEAM-XXX
SYMPHONY_AGENT_LABEL=symphony
EOF
# 4. 啟動
mix phx.server
啟動後,dashboard 會在 localhost:4000 跑起來,左側可以看到 Conductor 狀態、目前掛了幾支 agent,右側是每張 ticket 的進度條。Linear 那邊只要在某張 ticket 加上 symphony label,Conductor 在下一個 poll 週期(預設 30 秒)就會撿起來,spawn 一支 agent 開始幹活。
3.3 GitHub Project 的差異
如果用的是 GitHub Project(v2,graphql 版)而不是 Linear,把 LINEAR_* 換成 GH_* 對應變數就行,內部走的 adapter 會自動切換。差別在於 GitHub Project 沒有像 Linear 那麼乾淨的「ticket lifecycle event」,Symphony 是用 polling 補。如果一個專案有上百張 ticket,poll 頻率記得調慢一點,否則容易撞到 GitHub GraphQL 的 rate limit(5000 points/hour)。
四、跟其他 agent 框架的本質差異
寫到這裡會有人問:那它跟 ralph / gnhf / SWE-agent 到底差在哪?把抽象拉開來看,差異其實很乾淨:
ralph/gnhf:抽象單位是「一份 markdown plan + 一支 loop agent」。沒有任務板,沒有多 agent 編排,所有資訊都在 plan 文檔裡SWE-agent:抽象單位是「一張 GitHub issue + 一支 agent + ACI 工具集」。有 issue 概念,但沒有跨 issue 的編排Symphony:抽象單位是「一個任務板 + N 支 agent + supervision tree」。任務板才是 source of truth,agent 是它的 execution layer
這個層級差異反映在實際使用體驗上:用 ralph 的時候,工程師花時間寫 markdown plan;用 SWE-agent 的時候,工程師花時間整理 issue 描述;用 Symphony 的時候,工程師回到他原本就在用的 Linear / GitHub Project 介面,照舊把 ticket 寫好、分配人(這個「人」現在是 agent label),剩下交給 Symphony 自己跑。
對團隊接受度而言這個切入點蠻關鍵的:它沒有要求任何人改變既有的工作流程——產品經理還是寫 ticket、工程主管還是分票,只是某些 ticket 的 assignee 從人變成了 agent label,PR 從工程師開變成 agent 自己開。Code review 的環節依然由人類做。
OpenAI 官方那個「landed PR 數提升 5 倍」的數字要怎麼解讀?我自己的看法是:這多半不是「同樣的工程師現在五倍生產力」,而是「以前不會被人類分到票的瑣碎重構、依賴升級、文檔修補,現在都會被 agent 撿起來做」。換句話說,Symphony 多出來的不是上限產出,而是底部那層長期被遺忘的小事。對 codebase 健康度而言,這層 PR 的價值反而比前者高。
五、production 上線前要避開的雷
聽起來很美好,但開源 2 個月、early-stage 的標籤不是隨便貼的。以下幾個風險都是上 production 前必須處理的:
5.1 agent run-amok:自我修改失控
一支 agent 拿到 ticket 後可能會嘗試「修復」根本不該動的程式碼,例如改了 CI/CD 設定、動了資料庫 migration、把 production secret 寫進 repo。Symphony 預設沒有強制隔離,需要在 agent config 加 forbidden_paths:
# config/runtime.exs
config :symphony, :agent,
forbidden_paths: [
"infrastructure/**",
".github/workflows/**",
"db/migrations/**"
],
require_review_for: ["package.json", "Dockerfile"]
第二層保險是強制每支 agent 跑 git diff 通過 reviewer agent 的安全檢查才能 push。
5.2 token 燒爆
一支 agent 平均跑一張中等複雜度 ticket 約消耗 30K~80K input tokens、5K~15K output tokens。如果把 100 張 ticket 同時丟進去跑,一天的 OpenAI 帳單可能就破萬美金。比較務實的做法:
- 在 Conductor 設
max_concurrent_agents,建議起步 5–10 - 給每支 agent 設
token_budget_per_ticket,超過自動暫停回報人類 - 開 Codex 的
prompt caching,長期專案的 system prompt 重複度高,可以省 30–50%
5.3 Linear / GitHub API rate limit
Linear 的 GraphQL rate limit 是 1500 requests/hour/key,GitHub Project 是 5000 points/hour。Symphony 預設 polling 30 秒一次、每次抓一頁,單一 conductor 一天大約 2880 calls,本身不會撞牆。但加上 agent 自己回填留言、改狀態、附 PR 連結,數字會跳。對策是換成 webhook 模式,Linear 跟 GitHub 都支援,Symphony 從 v0.4 開始也提供 webhook adapter。
5.4 multi-node 一致性
要跑多 node 的話,BEAM cluster 本身好組,但 PostgreSQL 那層的 agent state 要小心。預設 schema 沒有強一致性鎖,兩個 node 同時 spawn 同一張 ticket 的 agent 是有可能的。生產環境建議:
- 在
agent_assignments表上加 unique constraint(ticket_id, status='running') - 在 Conductor 啟動時做 leader election(用
:global或 Postgres advisory lock)
這幾條 README 沒寫,是踩過才會知道的東西。
六、適合誰、不適合誰
回到最現實的判斷:什麼樣的團隊現在就值得試 Symphony?
適合:
- 已經有成熟 PR review 文化、CI 強健的團隊(不會讓壞 PR 直接進 main)
- ticket 描述寫得清楚的團隊(agent 解析 ticket 跟人類一樣需要清楚的需求)
- 主要工作是 backlog 上累積的小重構、依賴升級、文檔補齊
- 已經有 Elixir 工程能力或願意投入學習
不適合:
- ticket 描述都是兩行字、靠口頭討論決定細節的團隊(agent 一定會做歪)
- 主要工作是新功能、需要架構討論的團隊(這是人的工作)
- 沒有 staging / preview env,PR 沒辦法單獨驗證的專案
- regulated industry(金融、醫療、政府),agent 自動 push code 通常 compliance 不會過
我自己的看法是:Symphony 真正的價值不是「取代工程師」這種口號,而是給平台 / DevX 團隊一個team-scale agent infra 的開源 baseline。在這個之前要做類似的事情,幾乎是每家公司自己刻一套;現在有 OpenAI 用 Elixir 認真寫的這版打底,剩下的客製化(自家 ticket system、自家 review policy、自家 budget control)就只是周邊整合,不用從零開始想 supervision tree 怎麼設計、agent process 怎麼隔離。
對 Elixir 社群而言這也是個有意思的時刻——Phoenix 之後 BEAM 生態最受矚目的應用居然是 AI agent infra,這跟 2010 年代「Erlang 是電信業專屬」的刻板印象差距很大。如果這套架構真的被廣泛採用,未來幾年 BEAM 在 AI infra 領域的能見度應該會持續上升。
參考資料
- OpenAI 官方公告:Open-source Codex orchestration framework: Symphony
- Digital Applied 技術解析:OpenAI Symphony: Autonomous Code Orchestration Framework
- Phemex 新聞報導:OpenAI Releases Symphony Framework for AI-driven Project Management
- Elixir / OTP supervision tree 文件:hexdocs.pm/elixir/Supervisor.html


發佈留言