RoundTable 是一個開源、可自架的「多 Agent 任務工作台」:它把協作從「聊天室/頻道」改成「Mission → Task → Event/Artifact/Approval」的物件模型,內建任務看板、人工審核閘門、append-only 活動事件流與 per-agent 權杖,技術棧是 FastAPI + Postgres + React PWA,支援 Docker Compose 與 Coolify 一鍵部署,MIT 授權。
這個專案最值得看的地方不是它多新、多紅,而是它明確寫下了一句很反直覺的設計理由:
“Reason: chat/channel model doesn’t fit mission-oriented multi-agent work.” (理由:聊天室/頻道模型不適合任務導向的多代理工作。)
作者原本讓多個 agent 在 Mattermost 上協作,最後決定整套自己寫、把 Mattermost 退役。這篇文章就來拆解:為什麼「用聊天室跑 AI 團隊」會卡住,以及一個正確的模型該長什麼樣。
一分鐘認識 RoundTable
| 項目 | 內容 |
|---|---|
| 定位 | 自架的多 Agent 任務工作台(不是聊天室複製品) |
| 核心模型 | Mission → Task → Event/Artifact/Approval |
| 後端 | Python FastAPI + SQLAlchemy 2 + Postgres(開發用 SQLite)+ WebSocket |
| 前端 | React + Vite PWA(可安裝、單一 main.jsx) |
| 認證 | 單一 operator(httpOnly cookie)+ 每個 agent 一把 opaque bearer token |
| Agent 整合 | REST 合約 + Hermes webhook 派工(MVP 用輪詢) |
| 部署 | Docker Compose(任何 VPS)/Coolify Cloud |
| 授權 | MIT |
| 狀態 | working v0(missions、看板、活動流、審核、artifact、agent token 已可跑) |
作者把 agent 命名為圓桌武士:jaeger(Data Trials)、percival(Evidence)、galahad(Coordination,擔任 orchestrator)。第一個真實任務叫 OpenEndo——docs/deployment.md 裡直白寫著「as run for the Round Table fleet, 2026-09」,也就是這是一套已經在真實 fleet 上跑的東西,不是 demo。
為什麼「聊天室」不適合多 Agent?
聊天室(Slack/Discord/Mattermost)是為人類閒聊設計的,它有三個結構性問題,一旦你的協作者是會自己動手的 agent,全部會被放大:
| 問題 | 聊天室的現實 | 對 agent 的後果 |
|---|---|---|
| 訊息沒有型別 | 一切都是一則 message,靠人腦判斷哪句是「任務」 | agent 無法可靠地「認領任務」——它讀不出結構 |
| 沒有狀態 | 沒有「這件做完沒」的欄位,狀態藏在對話裡 | 任務進度無法查詢、無法統計、無法接續 |
| 審核會淹沒 | 「請你核可」只是一則普通訊息,滑過去就沒了 | 危險操作失去人工確認的閘門 |
| 歷史是流水帳 | 要稽核「誰在什麼時候改了什麼」得自己翻 | 出事時沒有可稽核的事件流 |
換句話說:聊天室最佳化的是「人與人之間的溝通」,而多 agent 協作需要最佳化的是「工作與狀態的流轉」。這兩件事長得完全不一樣。
RoundTable 的答案是把它換成一句話:
「物件,不是房間」(Objects, not rooms.)
核心設計:七大物件取代頻道
專案 docs/design.md 開宗明義寫著 “Objects, not rooms”,並定義了七個物件:
| 物件 | 關鍵欄位 | 角色 |
|---|---|---|
| Mission | name, slug, description, status, owner | 一個專案的頂層容器 |
| Agent | handle, role, status, last_seen | agent 註冊表(idle/working/awaiting_approval/offline) |
| Task | mission, title, assignee, state, parent, linked artifacts | 派工單元——一個 agent 一次只做一件事 |
| Event | mission, actor, type, payload, timestamp | append-only 活動流 |
| Comment | 事件驅動,掛在 task 或 mission 上 | 任務周邊的討論/決策 |
| Artifact | mission/task, kind, storage ref, preview_url, produced_by | 產出物:檔案、渲染圖、code ref、連結 |
| Approval | task, requested_by, status, note | consequential 動作前的人工閘門 |
關係如下:
graph LR
M[Mission] -->|1..N| T[Task]
M -->|1..N| A[Agent]
M -->|1..N| E[Event]
T -->|1..N| E2[Event]
T -->|1..N| AR[Artifact]
T -->|1..N| AP[Approval]
AP -->|pending / approved / rejected| AP這裡有兩個設計值得特別指出:
- Artifact 掛在 Task 上,不是掛在「對話」上。 產出物與它對應的工作綁在一起,三個月後回頭找「這個模型是誰跑的」,答案不會散在訊息流裡。
- Approval 是一級公民(first-class object),不是一句話。 它有自己的狀態機(pending → approved/rejected),可以查詢「現在有幾件待 operator 核可」。
機制一:任務狀態機——review 就是人工審核閘門
Task 的狀態流轉非常精簡,但每個狀態都有意義:
stateDiagram-v2
[*] --> todo
todo --> in_progress: agent 認領
in_progress --> review: 請求審核
in_progress --> blocked: 卡住
blocked --> in_progress: 解除
review --> done: operator 核可
review --> in_progress: 退回重做
done --> [*]關鍵在 review 這個狀態就是人工審核閘門本身。它的運作方式很漂亮:
- agent 做完事,呼叫
POST /api/agent/tasks/{id}/request-approval→ task 自動轉為review,並建立一筆 Approval - operator 在 UI 上按核可/退回 → task 才往下走
也就是說,「需要人看一眼」不是靠提示詞要求 agent 自律,而是狀態機上的硬閘門。這個設計直接把「AI 自己決定要不要問人」這個不可靠的環節,變成了系統層級的保證。
AGENTS.md 甚至明文規定:新增一個狀態,必須同一次改動裡更新後端常數、UI 看板、以及 docs/agent-integration.md 三處。這是很成熟的「改一處、同步三處」紀律。
機制二:append-only 事件流(可稽核)
系統裡「發生過的事」全部寫進 Event,且每筆都帶 actor_type(human/agent/system):
mission.created / mission.updated
agent.added / agent.removed
task.created / task.state_change
comment
approval.requested / approval.decided
artifact.added
後端 events.py 的 record_event() 做兩件事:持久化 + 廣播到 WebSocket hub(頻道 mission:{id} 與 board)。
這個設計回答了一個自架 agent 最常被問的問題:「出事的時候,你要怎麼知道是哪個 agent、在什麼時候、做了什麼?」 答案不是去翻對話,而是查事件流——因為每一次狀態變更都被強制記錄(AGENTS.md 的 reviewer checklist 第 2 條就是「每個 state change 都要記 Event」)。
機制三:三欄式介面
Mission 檢視頁採三欄配置,對應三種不同的工作模式:
| 欄位 | 內容 | 用途 |
|---|---|---|
| Timeline(左) | 結構化事件流 | 「剛剛發生了什麼」 |
| Board(中) | 依狀態分欄的 kanban | 「現在卡在哪」 |
| Roster(右) | agent 清單+狀態+派工表單 | 「誰在做什麼、要派誰」 |
派工流程是:新 task → 選 assignee → 寫 task brief。這一氣呵成的動作,在聊天室裡要拆成「開一個 thread、@某個 bot、祈禱它讀懂」。
Agent 怎麼接進來?——REST 協定
Agent 不需要任何特殊 SDK,只要會打 HTTP:
身份:每個 agent 一把一次性印出的 opaque token,資料庫內以 sha256 儲存(明文永不落地)。token 存進 agent 的 ~/.hermes/.env。
Agent 端點:
| Method / Path | 用途 |
|---|---|
GET /api/agent/me | 身份+狀態(叫越勤=presence heartbeat) |
GET /api/agent/missions | 我參與的 missions |
GET /api/agent/missions/{id}/context | 完整 mission brief + tasks |
GET /api/agent/tasks?state=todo | 我的待辦 |
PATCH /api/agent/tasks/{id} | 改狀態(todo/in_progress/review/blocked/done) |
POST /api/agent/tasks/{id}/comments | 進度備註 |
POST /api/agent/tasks/{id}/request-approval | 請求審核(→ task 轉 review) |
POST /api/agent/tasks/{id}/artifacts | 交付產出物(multipart) |
派工的兩種模式(這裡最務實)
Push 模式(已實作,未來主力):operator 指派任務時,伺服器把 dispatch payload POST 到該 agent 的 webhook_url(Hermes inbound webhook → 用 payload 當 context 跑 agent)。
Poll 模式(MVP,2026-09-05 上線,目前實際在跑):
“Push webhooks are the future; the MVP loop is polling, so no agent gateway needs a public inbound port.”
流程是:
- operator 發 token → 存進 agent 的
~/.hermes/.env - agent 跑 每 15 分鐘一次的 cron,打
GET /api/agent/tasks?state=todo,做掉被指派的任務,再透過 agent API 回報 - operator 在看板上即時看到進度,不需要任何額外基礎設施
這個取捨值得學:作者沒有為了「架構漂亮」去卡在 webhook 的公開埠/TLS/簽章驗證上,而是先用輪詢把整條 loop 跑通。輪詢讓 agent gateway 不需要對外開 inbound port——對自架環境來說,這往往是能不能落地的關鍵。
未來規劃中的 hermes_plugins.roundtable 外掛會提供原生工具(rt_list_tasks、rt_update_task、rt_comment、rt_upload_artifact、rt_request_approval)+ presence heartbeat,讓 agent 在 UI 上即時顯示 working/awaiting_approval,並擺脫 webhook 管線依賴。
安全姿態
自架 + agent 自動動手,安全設計不能含糊。專案的做法:
| 面向 | 做法 |
|---|---|
| 註冊 | 完全關閉——只有一個 operator + 被邀請的 agent |
| Agent 權杖 | opaque、sha256 儲存、只印一次 |
| Session | httpOnly cookie,MC_COOKIE_SECURE=true 時加 Secure |
| 授權 | agent 路由強制 ownership 檢查——只有 assignee 能移動自己的 task |
| Artifact 下載 | 一律走認證(cookie 或 bearer) |
其中「只有 assignee 能移動自己的 task」這條特別重要:它防止了 A agent 去改 B agent 的工作狀態——在多 agent 系統裡,這是很容易被忽略、但一忽略就整個信任鏈崩掉的漏洞。
部署:兩條路
路線 A —— Docker Compose(任何 VPS)
git clone https://github.com/wckdboy/RoundTable.git
cd RoundTable
cp .env.example .env # 設定 MC_DB_PASSWORD / MC_OPERATOR_PASSWORD / MC_SESSION_SECRET
docker compose up -d --build
# 開 http://<host>:8000
Compose 內含 postgres:16-alpine(帶 pg_isready healthcheck,api 等 db healthy 才起)+ 兩個持久化 volume(rt-postgres、rt-data)。前端由建置階段打包,由 FastAPI 從單一 origin 提供(所有非 API 的 GET 都回 index.html,交給前端路由)。前面掛 Caddy/nginx 做 TLS。
路線 B —— Coolify Cloud(作者自己跑的路線):建立 Postgres 資源 → 建立 Application(Dockerfile build pack、port 8000、開啟 connect to Docker network 讓它能用 uuid 連到 DB)→ 設環境變數 → 掛 /srv/data → 部署。之後 git push 到 main 即自動重新部署,volume 與 postgres 資料保留。
首次開機會自動 seed operator 與 MC_AGENT_SEEDS 定義的 agent,發 token 則可走 UI 或容器內:
docker compose exec api python -m mission_control.issue_token jaeger
工程紀律:一份寫給 AI 的 AGENTS.md
這個 repo 有一份 AGENTS.md(專門給「參與這個專案的 AI agent」讀的規範),內容值得直接引用——因為它本身就是「如何讓 AI 好好貢獻程式碼」的範例:
| 規則 | 原文 |
|---|---|
| 小步、無聊技術 | “Small diffs, boring tech. Prefer the simplest correct change… no new frameworks without a documented need.” |
| 單一真相 | “One origin, one truth. The backend owns state; the UI reads/writes REST + WebSocket only. Never duplicate state in the frontend store.” |
| 密鑰 | “Secrets never in git. Tokens are hashed at rest (sha256); plaintext is printed once.” |
| 推送前把關 | “Smoke before push: ./.venv/bin/python smoke_test.py must stay green.” |
| 前端不加依賴 | “Keep JSX dependency-free (no router / UI libraries without discussion).” |
再加上一份 Reviewer checklist(每個新 agent 路由要檢查 ownership、每個 state change 要記 Event、除了一次性 token 什麼都不准印)。
如果你正在跟 AI 一起寫程式,這三條「小步、單一真相、密碼不進 git」幾乎可以直接搬到自己的專案。
它跟 LangGraph/CrewAI/AutoGen 差在哪?
這是最容易誤解的地方。它們不是同一層的東西。
| LangGraph | CrewAI | AutoGen | RoundTable | |
|---|---|---|---|---|
| 本質 | 開發框架/函式庫 | 開發框架/函式庫 | 開發框架/函式庫 | 自架工作台(有 UI) |
| 核心概念 | 圖狀態機 | 角色任務委派 | 對話驅動 Actor | 物件:Mission/Task/Approval |
| 人類介入 | interrupt(原生) | human_input(有限) | UserProxy(彈性) | Approval 物件(一級公民) |
| 內建任務看板 | ❌ | ❌ | ❌ | ✅ |
| 內建審核待辦佇列 | ❌ | ❌ | ❌ | ✅ |
| 可稽核事件流 | 部分(trace) | 有限 | 有限 | ✅(append-only) |
| 你要自己寫 UI? | 是 | 是 | 是 | 不用 |
結論很清楚:三大框架給你的是「怎麼讓 agent 動起來」;RoundTable 解決的是「agent 動起來之後,人在哪裡看、在哪裡核准、事後怎麼查」。 三者(甚至同一套)都可以當 RoundTable 背後的執行引擎——它補的不是框架的缺,而是框架與人之間那一層。
想先搞懂框架本身,可以看站上的 AutoGen:Microsoft 的多代理對話框架;想理解自動化平台怎麼串,可以看 n8n 完整教學 2026。
誠實的現況與限制
這是一個很新、很小的專案,該說的缺點要說清楚:
| 項目 | 現況 |
|---|---|
| 人氣 | 幾乎沒有(剛公開,stars 個位數);不是社群主流方案 |
| 成熟度 | v0——作者自己在 README 標示 working v0 |
| 即時性 | WebSocket hub 已就緒,但 v0 的 UI 仍用 5 秒輪詢 |
| 多 operator | ❌ 尚未支援(設計上是「一個人 + 一群 agent」) |
| 通知推播/搜尋/整合 | ❌ 全部列在 “OUT (later)” |
| Agent 派工 | push webhook 已實作但目前跑的是輪詢;Hermes 外掛還沒做 |
| 檔案儲存 | v0 用本機磁碟(storage backend 可換) |
適合誰:已經在用(或打算用)tool-using agent 做真實工作、需要「任務看板+人工審核+可稽核紀錄」、而且想自己掌握資料的個人或小團隊。
不適合誰:需要企業級 RBAC、多租戶、SLA;或只是想「跟 AI 聊天」——那用聊天室就好,這個工具對你反而太重。
對自架 Agent 團隊的三個啟示
就算你不打算裝 RoundTable,這個專案有三個設計判斷值得帶走:
- 別把 agent 塞進聊天室。 訊息是給人讀的,任務是給系統跑的。當你的協作者會自己動手,你需要的是有型別的物件(Task/Approval/Artifact),不是更多訊息。
- 審核要是一級公民。 「需要人看一眼」不能靠提示詞自律,要靠狀態機上的硬閘門。把
review做進狀態流轉,比寫一百句「請先問我」有用。 - 先用輪詢把 loop 跑通。 架構漂亮不如先能落地。輪詢不需要公開 inbound port——這在自架環境往往是「能不能上線」的分水嶺。
FAQ
RoundTable 是什麼?
一個開源、可自架的多 Agent 任務工作台。它把 agent 協作從「聊天室/頻道」改成「Mission → Task → Event/Artifact/Approval」的物件模型,內建任務看板、人工審核閘門與可稽核事件流。後端 FastAPI + Postgres,前端 React PWA,MIT 授權。
它跟 CrewAI、LangGraph、AutoGen 有什麼不同?
層級不同。那三個是開發框架(寫程式的函式庫),沒有內建 UI、看板或審核佇列;RoundTable 是工作台(有介面、有看板、有審核待辦、有事件流)。它可以跟任一框架搭配,負責「人在哪裡看、在哪裡核准、事後怎麼查」那一層。
一定要用 Hermes 才能跑嗎?
不一定。agent 只要會打 HTTP 就能接入(opaque bearer token + REST)。Hermes 是作者的主力整合路徑(webhook 派工 + 規劃中的外掛),但協定本身是通用的。
為什麼要先做「輪詢」而不是 webhook?
因為輪詢不需要 agent gateway 對外開 inbound port,也就不必先解決公開埠、TLS、簽章驗證等一整套基礎設施,就能把「派工 → 執行 → 回報 → 審核」整條迴圈跑通。push webhook 的程式碼已實作,等環境具備再切換。
需要付費嗎?
不用。MIT 授權,自己架在自己的 VPS 上即可,資料完全在自己手上(Docker Compose 或 Coolify 兩種路徑)。
結論
RoundTable 的價值不在它現在有多少星星,而在它把一句很多人心裡想過、但很少付諸實作的話寫進了設計文件:「聊天室模型不適合任務導向的多代理工作。」
它用七個物件(Mission/Agent/Task/Event/Comment/Artifact/Approval)、一個把 review 做成硬閘門的狀態機、一條 append-only 事件流,以及一套務實的輪詢派工,示範了一個「人與一群 agent 一起幹活」的工作台該長什麼樣。
如果你正在自架 agent 團隊、又被「大家在同一條頻道裡喊來喊去」搞得很亂,這個專案的設計思路——物件,不是房間——值得你花半小時讀它的 docs/design.md。
專案連結:https://github.com/wckdboy/RoundTable(MIT 授權)
