cezar-agent-orchestrator

弗羅茨瓦夫 Open Mercato 黑客松:#aveCezar 用 Cezar 協調程式開發代理

我在 Open Mercato 黑客松上用 Cezar 做了一場程式開發代理協調實驗:機器遙測、派送上限、cgroup 感知的有效容量,以及自適應准入調節器。人在迴路,代理在 Git 工作樹裡幹活。

  • AI 代理
  • 開源
  • 黑客松
  • 開發者工具
  • 可觀測性

#aveCezar 黑客松的主視覺:暗色技術風格的凱撒雕像、#aveCezar 字標,以及 Build Cezar with Cezar 這行標語
#aveCezar 黑客松團隊的主視覺。標語是:資源感知、規模控制、人在迴路。

TLDR: Cezar 就是 ⚡️🚀**

週五早上,我只知道有 Cezar 這東西存在。到了週六晚上,我手上已經有十幾個 Git 工作樹、一群代理、一連串準備發往上游的 pull request,還有一個正在建構……Cezar 本身的 Cezar。

這大概就是我在弗羅茨瓦夫 Open Mercato 黑客松度過的那個週末。

我不會假裝這是一篇客觀的文章。密集用了 2 天之後,我認為 Cezar 是我今年發現最有趣的工具之一。

先說清楚,Cezar 到底是什麼?

Cezar 是一套開源的程式開發代理協調器。

你不必開 5 個終端機、5 個 Codex 工作階段,還得費神記住哪個代理在做什麼;取而代之的,是一座能平行執行許多任務的控制台。

每個任務都可以有自己的 Git 工作樹。任務可以平行進行。多出來的任務就在佇列裡等待。你可以使用 Claude Code、Codex、OpenCode 或 pi,用 YAML 打造工作流程、接上檢查機制,並即時觀看代理工作。這裡也沒有另外的資料庫:Cezar 把狀態保存在普通的 .ai/cezar/ 檔案裡。

不過,最有趣的部分,要從代理能把工作再委派給其他代理說起。

這個機制叫做 派送(Dispatch)。

大致上是這樣:

Human
  ↓
Lead agent
  ├── child agent
  ├── child agent
  ├── child agent
  └── child agent

Lead 收到一個比較大的任務,把它拆解,再把更小的片段委派給它的子代理。子代理在各自的 Git 工作樹裡平行工作,最後由 Lead 收集結果。

聽起來很棒。

直到你開始想:

這些子代理,我們實際上能安全地跑幾個?

問題自己找上門

使用 Cezar 的過程中,我很快就走到一個點:委派既是它最大的優勢,也是潛在的問題。

如果一個代理可以再啟動好幾個代理,而它們每一個都在同一台機器上做真正的工作,那你需要的不只是一句單純的「執行下一個任務」。

你需要的是對規模的控制。週六晚上,Cezar 的共同創造者之一 Patryk (https://github.com/pat-lewczuk) 把我指向真正的問題:量測與自動擴展。我放下了那天一直在做的功能,因為遙測與自適應控制的價值顯然更高。

所以第一步是一個簡單的機制:

Max running dispatched tasks

由人設定硬性上限,決定最多可以同時執行多少個由派送啟動的任務。如果上限是 4,第五個子代理不會立刻啟動,而是先在佇列裡等待。

一般任務不會被這個上限擋住。

這一點很重要,因為手動上限簡單、可預測,而且把最後的決定權留給操作者。

我後來並不想把它拿掉。

恰恰相反:它成了接下來那一步的基礎。

Cezar 的 Resources 面板,帶有針對已派送任務的手動上限
Resources 面板:Max parallel tasks 設為 2,而此時 Max running dispatched tasks 是空的,也就是沒有限制。第二個上限只涵蓋已派送的任務:一般任務照常執行。 來源:撰寫本文期間從 Cezar 截取的畫面。

好,但這台機器實際上能扛多少?

當我開始進一步思考要怎麼限制代理時,一個顯而易見的問題浮了出來。

一個人到底要怎麼知道該設 2、4、8 還是 16?

下一個零件就是這樣誕生的:Machine telemetry(即時機器遙測)。

Resources 裡出現了一張卡片,即時顯示:

CPU、記憶體、load average、核心數,以及一小段 CPU 趨勢。

沒有 Prometheus。

沒有 Grafana。

沒有額外的遙測代理。

沒有資料庫。

只有機器當下的狀態。

而光是這樣,對我來說就已經非常有用。

Cezar 的 Machine 卡片,顯示即時的 CPU、RAM 與 load average 遙測資料
Machine 卡片的第一版:CPU、記憶體、load average 與核心數,全部即時更新。在這個版本裡,卡片只顯示主機資源;附註 Host totals - no cgroup limit detected for this process. 直白地說明了沒有偵測到這個行程的 cgroup 限制。 來源:Cezar 截圖,Machine 卡片 v1。

只不過,沒過多久就冒出一個有趣得多的問題。

主機說一套,容器說另一套

第一版遙測顯示的是主機資源。

在一般機器上,這沒問題。

但 Cezar 非常適合跑在 VPS、沙盒與容器上。麻煩也正是出在這裡。

主機可能有:

24 CPU
58.5 GB RAM

但 Cezar 行程實際能用的可能只有:

2 CPU
1 GB RAM

如果排程器只看主機,一切看起來都很美好。

「放輕鬆,我們有 58 GB 的記憶體。」

與此同時,容器正快要撞上自己那 1 GB 的上限。

就在那一刻,一個普通的遙測小工具開始變成有趣得多的東西。

我加上了 cgroup 偵測與 有效容量(effective capacity)。

如果行程是在 cgroup 限制下執行,Machine 卡片顯示的就是真正套用到這個行程的資源。主機總量只會保留為背景資訊。

於是在同一個畫面上,我們可以看到:

effective:
2 CPU
952 MB / 1 GB

host:
24 CPU
58.5 GB RAM

忽然之間,我們手上有了真的可以用來做決定的資訊。

Cezar 偵測到 cgroup-v2 限制,以及容器的有效容量
同一張卡片,這次是在容器裡:cgroup limits detected - cgroup-v2,有效資源是 2 CPU,以及 1.0 GB 記憶體中的 88 MB;而主機的 24 CPU 與 58.5 GB RAM 則退居為背景。現在這個行程看到的是自己的限制,而不是整台機器的資源。 來源:在 2 CPU / 1 GB RAM 容器裡執行的 Cezar 截圖。

好。既然 Cezar 能看見機器壓力……

……那就表示它不必只是把壓力顯示出來。

它可以對壓力做出反應。

而我最喜歡的那個部分,正是從這裡開始。

在手動上限之上,我加了一個 自適應准入調節器。

規則非常簡單:

人類設定最大值;自動化只能把那個上限往下調。

手動上限不會消失。

如果我輸入:

Max dispatched tasks = 8

那麼 8 就是硬性天花板。

調節器不能說:

「你的可用記憶體還很多,那就放 14 個進來吧。」

不行。

它能做的是看見記憶體壓力,然後說:

「你把最大值設在 8,但現在比較安全的做法是只放 4 個進來。」

對我來說,這才是正確的人在迴路模型。

human ceiling
      ↓
effective machine capacity
      ↓
adaptive governor
      ↓
dispatch admission

8 -> 4 -> 8

最棒的部分是,這已經不再是一張架構圖了。

它真的有效。

為了測試,我把 Cezar 跑在一個容器裡:

2 CPU
1 GB RAM

手動派送上限:

8

機器平靜的時候:

Dispatch admission: normal - 8 of 8

接著我們把容器的記憶體壓上去。

Machine 卡片會一路爬到大約:

952 MB / 1.0 GB

而調節器會切換到:

Dispatch admission: elevated - 4 of 8

也就是說,它不會改動使用者的設定。

它不會停掉已經在執行的子代理。

它只是放比較少的新任務進來。

當記憶體壓力消失,系統也平靜了一會兒之後:

4 -> 8

我們就回到正常的准入。

也就在那一刻,我心想:

好,這個小工具已經不只是小工具了。

它變成了進入協調器控制迴路的入口。

處於正常狀態的自適應准入調節器:8 of 8
Normal。沒有壓力,所以調節器放行完整的 8 of 8。容器記憶體是 1.0 GB 中的 88 MB。
記憶體壓力下的自適應准入調節器:4 of 8
Elevated。記憶體爬到 1.0 GB 中的 952 MB,准入降到 4 of 8,儘管手動上限仍然是 8。
壓力消退之後的自適應准入調節器:又回到 normal,8 of 8
Normal again。壓力已經消失,准入回到 8 of 8;容器記憶體是 1.0 GB 中的 86 MB。

用 Cezar 打造 Cezar

整段故事裡最 meta 的部分是什麼?

這些工作大部分都是用 Cezar 自己完成的。

有一棵開發工作樹總共跑了 27 個任務:

1 lead
8 implementation
15 review
3 research

最多有 5 個代理同時平行工作,某個時間點我手上有 14 個 Git 工作樹。

一個代理負責實作一個部分。

另一個負責審查它。

再一個負責 QA。

審查真的能找出真正的問題,實作被修正,測試重新跑過,改動最後才進到 PR。

有一次,審查抓到了一個很棒的細節:走勢圖(sparkline)顯示的是主機 CPU %,而它旁邊的數字卻已經代表容器的有效 CPU。

一件小事。

只不過,正是這種小事會讓遙測變得不再可信。

修好、測試、重新截圖,然後繼續前進。

這大概是我從這個週末帶走的最大收穫。

這已經不再只是「AI 會幫我寫程式」而已。

更像是:

idea
↓
lead agent
↓
dispatch
↓
worktrees
↓
implementation
↓
review agents
↓
QA
↓
human
↓
PR

工廠運轉起來了。

人類依然守在紅色按鈕旁邊。 😎

我當開源貢獻者的第一個週末

對我個人來說,這次黑客松也是我第一次認真踏入別人的開源專案。

Fork。

開分支。

規格 PR。

實作 PR。

審查。

CLA。

Rebase。

衝突。

上游。

更多修正。

而在這一切中間的某個時刻:

「天啊,我的程式碼居然就這樣以 open PR 的形式,躺在我自己在用的專案裡。」

這種感覺,跟再做一個自己的 side project 非常不一樣。

在這裡,解法要能配合的不只是你自己的工作流程。

它還得配合既有的架構、專案的理念,以及日後要維護它的人。

Open Mercato 在這一切裡的位置是什麼?

這場黑客松是圍繞 Open Mercato 生態系舉辦的。

Open Mercato 是一套開源基礎,讓你能用 TypeScript 打造 CRM、ERP 與商務系統。這個專案提供現成的架構決策與基礎機制,例如多租戶、RBAC、事件與領域模組,讓開發者和程式開發代理都不必每次重新發明系統的基本盤。

Cezar 就是從那個生態系長出來的。

而在這個週末之後,我更加明白為什麼會這樣。

如果你真的想用許多代理平行打造軟體,問題很快就會不再是:

「哪個模型最好?」

而是開始變成:

我要怎麼把這一切管好?

佇列。

Git 工作樹。

委派。

審查。

預算。

資源。

准入控制。

人在迴路。

而這正是 Cezar 開始變得有趣的地方。

接下來呢?

寫下這些文字的當下,我的改動仍然是以 open PR 的形式,等待上游審查。

本來就該如此。

開源不是對正式環境執行 git push --force。 😉

不管這些東西最後有多少會以現在的形式進到 main,我已經知道一件事:

Cezar 會留在我的工作流程裡。

⚡️🚀

編輯更新 - 21:25,2026 年 9 月 21 日

PS. 要讓工廠產線滿載運轉的祕方,就是 Open Mercato Skills:
https://github.com/open-mercato/skills

2026 年 9 月 19 日星期六,我有幸在弗羅茨瓦夫的 Open Mercato 黑客松現場,觀看 Piotr Karwatka 的 live coding 環節。

錄影在這裡:
https://www.youtube.com/watch?v=VEy3JOwH_ew

目前只有波蘭語版本。

Piotr 是 Open Mercato 的共同創辦人,也是 Cezar 的共同創造者之一:
https://github.com/pkarw


黑客松產出的 pull request

Cezar 儲存庫:https://github.com/open-mercato/cezar

Open Mercato:https://github.com/open-mercato/open-mercato