Skip to content

跟成熟 coding agent 學設計:系列總覽——拆五個專案的原始碼,蓋自己的 agent

2026年8月30日 1 分鐘
TL;DR 我在寫自己的 Python coding agent「rivumi」,這個系列把 pi、oh-my-pi、opencode、codex、claude-code 五個成熟專案的原始碼逐題對照,也對照 Rivumi 現在已經落地的 TUI、外部 CLI runtime、local gateway、usage/OTel/session 工具與 Cloudflare 切片。每篇固定走「設計問題→五家做法→rivumi 選擇→學術依據→改善路線」五段,證據一律給到 file#symbol 層級。
目錄
  1. 為什麼自己寫一個 coding agent
  2. 五個參考專案是誰
    1. pi(badlogic/pi-mono)
    2. omp(can1357/oh-my-pi)
    3. opencode(sst/opencode)
    4. codex(openai/codex)
    5. claude-code(decompiled source)
  3. 這個系列怎麼讀
  4. 證據標準
  5. 參考資料

🌏 English version

過去半年我在寫一個自己的 coding agent,叫 rivumi。卡關的次數遠比想像多:agent loop 要怎麼收尾、審批要做到多細、session 斷線怎麼續、小模型亂吐 diff 怎麼擋。每次憑空設計,兩週後就會發現某個開源專案早就踩過同樣的坑。

所以我把流程反過來:先讀五個成熟專案的原始碼,再決定 rivumi 怎麼做。讀出心得的東西太多,乾脆寫成系列。這篇是總覽,講清楚三件事:rivumi 在解什麼問題、五個參考專案各自是誰、這個系列怎麼讀。

為什麼自己寫一個 coding agent

市面上的 coding CLI 已經夠多了,再寫一個的理由只有一個:你想要的能力組合沒有人賣。

我要的是一個 Python-first 的 agent:日常可以當互動式 CLI 用,進 CI 或之後丟上 Cloudflare 時,切到一個有界、可稽核的 headless 模式。聽起來簡單,但這句話裡藏著一堆設計決策——工作區要隔離到什麼程度、patch 套用前誰簽核、驗證不過算不算失敗、模型 API 換一家要改多少程式。

rivumi 的架構刻意分成兩條平行的執行路徑:

  1. 原生 harness:自己擁有 agent loop、審批、session、工具集、驗證閘門和 model API adapter。
  2. 外部 CLI runtime:明確選定的外部 coding CLI(Claude Code、Codex CLI、OpenCode、Pi、OMP)當 backend,它們跑自己的 loop,但共享 rivumi 的對話 UI、工作區安全、patch 稽核和驗證邊界。

關鍵紀律是一條路徑永遠不偽裝成另一條。外部 CLI 就是外部 CLI,不會假裝那是原生實作。這條紀律本身,就是讀了別人的原始碼之後才學會的。

現在的 Rivumi 已經不只是早期 Python harness。除了 provider-neutral ModelProvider contract、state-first event journaling、rivumi resume、runtime-first TUI、local model gateway,以及 Worker control plane + Cloudflare Sandbox 的受限部署切片,原生 loop 也已有 allowlist MCP、明確 JSONL 記憶、context pressure 自動壓縮、model fallback、靜態價格表成本估算、ripgrep-backed 搜尋與有界工具批次。這些都是可跑、可測的 baseline;跨 runtime parity、完整 provider 價格覆蓋、hostile-code production hardening 和實際 production traffic 仍未由這些本機實作證明。

五個參考專案是誰

五個專案的 shallow clone 都在我的機器上,以下描述是我實際看過頂層結構後寫的,不是官網文案。

pi(badlogic/pi-mono)

TypeScript monorepo,走極簡路線。packages/ 底下切成 agent(agent loop)、ai(provider 層)、coding-agenttuiprotocolserversession-backendstelemetryevals。它的價值在於小:整個 loop 就是 pi-mono/packages/agent/src/agent-loop.ts#agentLoop 一個 exported function,適合當「最小可行 agent」的教科書讀。rivumi 的 provider 表就是從 packages/ai 的定義衍生來的。

omp(can1357/oh-my-pi)

pi 的 fork,然後瘋狂加料。TS packages/ 多出一堆 pi 沒有的東西:snapcompact(context 壓縮)、mnemopi(跨 session 記憶)、hashline(hash 錨定的行編輯)、catalog(model 資料庫)、metaharness(實驗基礎設施)、collab-web(多人協作)。底層熱路徑另外補了 Rust crates:pi-shellpi-walkerpi-ast。同一個問題先看 pi 的極簡答案、再看 omp 加了什麼,兩代演進本身就是一份設計文件。

opencode(sst/opencode)

TypeScript,規模完全是另一個量級。engine 在 packages/core(session、config、provider、credential),外面掛了 clituidesktopserversdkplugincodemode(工具呼叫編譯成程式批次執行)、containers 等三十幾個 package。想看「一個 agent 專案長成一個平台之後」長什麼樣,看它。

codex(openai/codex)

OpenAI 的官方 CLI,核心在 codex-rs/——一個 Rust workspace,crate 數量破百:coretuiapply-patchrollout(session 錄製)、mcp-servercode-mode-*,還有一整套安全棧:sandboxinglandlock.rsbwrap.rs 等)、linux-sandboxwindows-sandbox-rsexecpolicyshell-escalationnetwork-proxy。OS 級沙箱和危險指令攔截,目前公開原始碼裡做得最完整的就是它。

claude-code(decompiled source)

先誠實講:anthropics/claude-code 的官方 repo 只發布 minified bundle,我手上這份是社群反編譯/重建的 v2.1.88 原始碼。src/ 底下的 query.tstools/services/context/memdir/skills/hooks/ 結構清楚到驚人,symbol 名稱有可能與原版有出入,引用時我會標注這點。它是唯一能看到「產品級 agent 的內部臟器」的材料。

這個系列怎麼讀

兩部曲共 38 篇,全部中英雙語。

第一部「已實作的對照」(24 篇):rivumi 已經做掉的主題——agent loop 的形狀、workspace 隔離、approval 分級、verification gate、ModelProvider 抽象、retry policy、訂閱 OAuth、外部 CLI 當 backend、edit 工具取捨、沙箱與遠端執行、CLI 人體工學等。每篇都是「五家怎麼做 vs 我怎麼做」的正面對決,包含我做錯的部分。

第二部「改善路線與落地追蹤」(13 篇):這批文章最初從缺口出發,但 Rivumi 後來已補上多個 baseline,包括 context 壓縮、明確記憶、native MCP、hooks/skills/plugins、subagent、replay/fork、usage/OTel/成本估算、靜態 model role 路由、IDE/LSP snapshot、有界 code-mode 工具程式,以及 Cloudflare control plane。文章現在同時記錄「已落地到哪」與 remaining gaps;危險指令規則語言、全面 egress 控制、跨 runtime 一致性與 production validation 仍不能寫成完成。

每篇固定五段結構:

  1. 設計問題:這題到底在問什麼、為什麼難。
  2. 五家做法:五個參考專案各自的解法,附原始碼證據。
  3. rivumi 的選擇:我選了什麼、為什麼不同(或為什麼照抄)。
  4. 學術依據:ReAct、SWE-agent、Reflexion 這類論文或技術報告怎麼說,第一次出現就附連結。
  5. 改善路線:還能更好嗎?具體到可以動工。

證據標準

這個系列的每個主張都要求 file#symbol 層級的引用,格式如 codex-rs/sandboxing/src/landlock.rs#create_linux_sandbox_command_args_for_permission_profile——檔案加函式或型別名,不給行號(clone 會更新,行號會漂移)。查不到的就明說查不到,禁止編造。第二部的主題我會在動筆前逐一 grep 五家原始碼確認引用位置;如果某家根本沒做某件事,那也是一個值得寫下來的事實。

順帶一提,這套「先查再寫、證據落盤」的流程本身就是這個系列的方法論:我把自己開發 rivumi 時的研究筆記流程,直接搬來當寫作流程。

如果你正在寫自己的 agent、或只是想知道 Claude Code 與 Codex 的引擎蓋底下長什麼樣,這個系列是寫給你的。第一篇正式內容從 agent loop 開始——所有東西的地基。

參考資料