← 文章列表
AI Agent

打開原始碼才發現:三個 Agent 框架,三種截然不同的設計哲學

2026-04-23 · — views

打開原始碼才發現:三個 Agent 框架,三種截然不同的設計哲學

這個系列從今天開始。我打算借助 AI 工具輔助,直接從原始碼讀起——deepagents、openclaw、hermes-agent 三個 open source Agent 框架,邊讀邊整理成筆記,帶著你一起拆。你可能以為這三個框架做的是差不多的事——不就是 LLM + tools + loop?但打開原始碼之後才發現,它們對「Agent 到底要長什麼樣」這個問題,給的答案幾乎完全不重疊。

同樣叫 Agent 框架,deepagents 的作者在意的是「怎麼讓開發者用最少的程式碼把 Agent 嵌進自己的系統」;openclaw 在意的是「怎麼讓一個 Agent 24 小時跑在你的 WhatsApp 裡而不壞掉」;hermes-agent 的作者想的是「怎麼讓 Agent 在幫你做事的同時,收集訓練資料來訓練更好的模型」。三個完全不同的問題,所以設計出三個完全不同的架構。

這篇是這個系列的第一篇,我想先用這三個框架的比較,勾出幾個值得深挖的設計問題。後續的文章會逐一深入。

讀完這篇,你會理解:

  • 為什麼同樣叫「Subagent」,deepagents 和 openclaw 的實作幾乎是兩件不同的事
  • 從三個框架的架構選擇中,可以問出哪六個 Agent 系統設計的核心問題
  • 什麼場景適合哪個框架——不是哪個比較好,而是你在解什麼問題

這篇不是框架使用教學,也不是「最佳實踐清單」。是從設計決策的角度,試著解釋這些框架為什麼長那個樣子。


三個框架,三種定位

先快速認識三個主角。

deepagents 是 LangChain AI 做的,定位是 SDK——你的 Python 應用裡需要一個 Agent,create_deep_agent() 一行叫起來,其他的它幫你想好。架構核心是一層 Middleware Stack,上面跑 LangGraph。選它,通常是因為你已經在 Python 生態裡,需要最快把 Agent 接進去。

openclaw 是社群專案,定位是個人助理平台。它連接了 20+ 個通訊頻道(WhatsApp、Telegram、Slack、Discord…),讓你的 Agent 常駐在這些平台,隨時待命。架構核心是 Channel Gateway → Session → embedded runner 這個三層結構。選它,通常是因為你想要一個「一直在線」的助理,而不是一個「被程式呼叫的服務」。

hermes-agent 是 NousResearch 做的,定位更接近研究工具。它支援 6 種執行環境(local、Docker、SSH、Modal…),有一個可插拔的 Context Engine,最特別的是有個完整的學習閉環:每次完成任務,就把 trajectory 存成 ShareGPT 格式,可以直接接到 Atropos RL 環境訓練模型。選它,通常是因為你在做 Agent 研究,或是需要在沒有標準環境的機器上跑 Agent。

用一張表快速對比:

維度deepagentsopenclawhermes-agent
定位SDK 工具箱個人助理平台自我進化代理
語言PythonTypeScript/NodePython
核心模式Middleware Stack + LangGraphGateway → Session → runnerAIAgent + 學習迴圈
主要用途嵌入自己的系統24/7 多平台助理研究 + 自主代理
LLM 彈性LangChain 任意 Model20+ Provider,自動輪換OpenAI-compat 任意端點

架構長什麼樣:三張圖看清楚

文字描述還是太抽象,直接看架構圖。

這三個框架本質上都在做同一件事:Harness Engineering——為 LLM 搭建工具鏈、狀態管理與執行控制,讓 LLM 從「回答問題的服務」變成「能完成複雜任務的 Agent」。差別在於,每個框架對「Harness 應該長什麼樣」的判斷,各自走了截然不同的路。

deepagents:Middleware Stack → LangGraph

create_deep_agent()

   Middleware Stack(有序疊加)
   ┌─────────────────────────────┐
   │ TodoListMiddleware           │  ← write_todos 工具
   │ FilesystemMiddleware         │  ← read/write/edit/glob/grep
   │ SubAgentMiddleware           │  ← task() 工具
   │ SummarizationMiddleware      │  ← 自動 context 壓縮
   │ SkillsMiddleware             │  ← 載入 SKILL.md
   │ MemoryMiddleware             │  ← AGENTS.md 記憶
   │ HumanInTheLoopMiddleware     │  ← 中斷點審批
   └─────────────────────────────┘

   CompiledStateGraph(LangGraph)
        │ 透過 checkpointer 持久化
   SQLite / Redis / Postgres

每一層 Middleware 做一件事,組合起來就是一個完整的 Agent。這個架構的核心假設是:Agent 的能力應該是可以插拔的,而不是焊死在一個大型 class 裡

openclaw:Gateway → Session → Embedded Runner

用戶輸入(WhatsApp / Telegram / Slack / CLI...)

   Channel Gateway(20+ 平台)

   Session Router(agent-scope, session-key)

   pi-embedded-runner(核心 LLM 執行引擎)
        │  ← 多 Provider,自動 failover
   Model(Anthropic / OpenAI / Google / OpenRouter...)

   Tool Execution Layer
   ┌────────────────────────────────────────┐
   │ Canvas / CronJob / TTS / ImageGen       │
   │ WebSearch / WebFetch / PDF              │
   │ Sessions-Spawn / Subagents              │
   └────────────────────────────────────────┘

   Context Compaction(自動壓縮)

openclaw 的架構核心假設是:用戶和 Agent 的互動發生在各種平台上,框架要負責把這些入口統一起來。Gateway 層讓 Agent 邏輯和通訊頻道完全解耦,你換一個平台不需要動 Agent 本身。

hermes-agent:AIAgent + 學習迴圈

用戶輸入(CLI / Telegram / Discord / Slack...)

   AIAgent.run_conversation()

   ContextEngine(pluggable)
   ┌──────────────────────────────┐
   │ CompressorEngine(預設)       │ ← 達到 threshold 自動壓縮
   │ LCM Engine(可替換)           │ ← 外部 plugin
   └──────────────────────────────┘

   MemoryManager(檔案型記憶 + 外部 provider)

   LLM Call(OpenAI-compat API)

   Tool Execution(40+ 工具)

   執行環境(6 種 Backend)
   local / Docker / SSH / Daytona / Singularity / Modal

   學習迴圈:Trajectory 儲存
   → ShareGPT 格式 → batch_runner → Atropos RL

hermes-agent 的架構核心假設是:Agent 不只是一個執行工具的服務,它應該在執行的過程中不斷學習。這個假設決定了它從 ContextEngine 到 Trajectory 儲存的整條設計鏈。


同樣叫 Subagent,差多少?

讓我用一個具體的設計問題來讓差距變得具體:當主 Agent 需要派一個子任務給另一個 Agent,這個「Subagent」應該是什麼?

在 deepagents 裡,Subagent 有三種型態,但最基本的一種是這樣的:

SubAgent(
    name="researcher",
    description="專門負責查資料的子代理",
    system_prompt="你是一個研究員,負責..."
)

本質上,它是一個宣告式的工具定義。主 Agent 呼叫它,就像呼叫一個 function。呼叫完,結果回來,任務結束。這個設計的優點是簡單、可預測、容易測試。代價是:如果子任務需要跑很長時間、需要暫停後繼續、或是父 Agent 中途 crash 了,這個模型就不好處理。

openclaw 的設計思路完全不同。它有一個 Subagent Registry,記錄系統裡每個子代理的狀態:

subagent-registry
    ├── 每個子代理的 session-key
    ├── spawn / complete / error 狀態追蹤
    ├── depth limit(防止 A→B→C→... 無限遞迴)
    └── orphan-recovery(父代理 crash → 子代理自動清理)

在 openclaw 的世界裡,Subagent 不是一次性的 function call,而是一個有生命週期的實體——它會被創建、被引導、會等待、會完成,如果父代理突然消失,它也能被正確回收。這個設計的代價是複雜,但它解決的問題是真實的:當 Agent 要長時間跑在用戶的手機上,「父代理掛掉子代理繼續消耗資源」這件事必須被處理。

這不是哪個設計比較好。是兩個框架在解不同的問題,然後做了不同的選擇。


比較之後,六個值得深挖的設計問題

讀完這三個框架,我整理出六個設計概念,覺得是 Agent 系統裡最值得花時間理解的。

1. Middleware Stack(deepagents)

deepagents 的 Agent 是由一層 Middleware Stack 組成的,每個 Middleware 負責一件事:

FilesystemMiddleware      → 增加檔案操作工具
MemoryMiddleware          → 把記憶注入 system prompt
SummarizationMiddleware   → 監控 context,超過 threshold 就壓縮
HumanInTheLoopMiddleware  → 插入人工審批的中斷點

這個模式就是 Harness Engineering 的核心體現——用一層可組合的中介層,替 LLM 建立工具使用能力、記憶管理和執行控制,而不是把這些邏輯全部混入 Agent 本身。設計洞見是:Agent 的能力不應該是一個大型 class,而是一組正交關切點的有序組合。每個 Middleware 可以單獨測試、單獨替換,整個 stack 的行為由組合決定。這和 HTTP server 的 middleware 模式(Express.js、FastAPI)是同一個概念,但用在 LLM Agent 上。

2. Pluggable Context Engine(hermes-agent)

hermes-agent 把 context 壓縮策略抽成一個獨立的介面:

class ContextEngine(ABC):
    threshold_percent: float    # 何時觸發壓縮
    protect_first_n: int        # 保護最初 N 輪(設定 context)
    protect_last_n: int         # 保護最後 N 輪(工作 context)

    def should_compress(self) -> bool: ...
    def compress(self, messages) -> messages: ...
    def get_extra_tools(self) -> list: ...  # Engine 可以注入工具!

這個設計的洞見是:不同任務需要不同的 context 管理策略。短任務不壓縮;長研究任務做摘要壓縮;複雜的多步驟任務可能需要結構化壓縮。把這個策略硬編碼進 Agent,等於把一個本來應該可以調整的旋鈕焊死了。

3. Session Registry + 孤兒恢復(openclaw)

前面已經提到了。核心問題是:子代理不是一次性呼叫,當它的生命週期比父代理還長,你需要一個中央狀態表來追蹤它。openclaw 的 orphan-recovery 機制,就是在處理這個邊界情況——在常駐型 Agent 系統裡,這個邊界早晚會遇到。

4. Memory Fencing(hermes-agent)

hermes-agent 把 memory 注入對話的方式是這樣的:

<memory-context>
[System note: The following is recalled memory context, NOT new user input.]
你喜歡 Python 勝過 JavaScript。
上次我們討論了 K8s networking 問題。
</memory-context>

為什麼要加這個 XML fence?因為如果你直接把記憶內容插進 user message,LLM 很可能把它解讀成「用戶剛剛說的話」,混淆對話脈絡。fence 加上明確的 system note,讓 LLM 知道這段是背景記憶,不是新指令。看起來是小細節,但在長期運行的 Agent 裡,這個邊界如果不清楚,對話脈絡很容易開始亂掉。

5. Auth Profile Rotation(openclaw)

openclaw 有一個 auth-profile 機制,讓你預設多組 API key,然後自動輪換:

auth-profiles(多個 API key)
    → failover(自動切換壞掉的 key)
    → cooldown(限流後冷卻計時)
    → model-fallback(找下一個可用 model)

這個設計解決的是 24/7 助理的可用性問題——當你的 Agent 要隨時在線,你不能允許因為單一 API key 被限流就讓整個服務掛掉。這是一個在「週末 demo」場景完全不需要想的問題,但在「長期運行的個人助理」場景裡是剛需。

6. Trajectory → RL 閉環(hermes-agent)

hermes-agent 最與眾不同的設計:

用戶使用 → Trajectory 自動儲存(ShareGPT 格式)

          batch_runner(批次生成訓練資料)

          Atropos RL 環境(強化學習)

        訓練更好的 tool-calling 模型

          用戶使用更好的 hermes → ...

hermes-agent 不只是一個 Agent 框架,它同時是一台資料收集機器。每一次用戶和 Agent 的互動,都在餵養下一代模型的訓練管道。這個設計的前提是 NousResearch 本身在做模型訓練——對一般的 Agent 開發者來說,這個閉環不一定能直接拿來用,但「把 Agent 的執行軌跡當作可利用的訓練資料」這個思維,值得記住。


適用場景速查

不同框架解不同的問題,選錯了再怎麼調也只是在解決本不應該存在的問題。

你的情境最適合關鍵理由
要把 Agent 能力嵌入現有的 Python 後端服務deepagents純 SDK,不需要重構現有架構,直接接 FastAPI / Flask
任務跑到一半需要人工確認,或要在多次對話之間保留執行狀態deepagentsLangGraph checkpointer 持久化狀態,HumanInTheLoopMiddleware 插入審批點
想要一個隨時待命的個人助理,同時接管多個通訊平台openclaw20+ 頻道接入,Session 常駐,隨時觸發
Agent 要 24/7 跑,不能因為某個 Provider 限流就中斷openclawAuth profile rotation 自動切換 API key 和 model
在做 Agent 研究,需要把執行軌跡拿來訓練或分析hermes-agentTrajectory 自動存為 ShareGPT 格式,直通 Atropos RL 訓練環境
Agent 要能跨環境部署(本機、Docker、SSH、Serverless 都有)hermes-agent6 種執行 backend,Modal serverless 支援按需喚起

這個系列要做什麼

我打算把這三個框架的設計決策,一個一個拆開來看。不是要寫使用教學,也不是要比較哪個框架更好。是想回答一個問題:當你在設計自己的 Agent 系統,面對某一個具體的架構問題,那些認真做過的人是怎麼想的?

上面六個設計概念,每一個背後都有不止一種可能的做法。deepagents 的 Middleware Stack 為什麼要這樣疊?hermes-agent 的 Pluggable Context Engine 在什麼情況下才值得這樣設計?openclaw 的 multi-agent 生命週期管理複雜到這個程度,真的是必要的嗎?

這些問題,後續的文章會一篇一篇回來回答。


結語:三個框架,三個對「Agent 是什麼」的不同回答。在讀懂這些差異之前,很難真正知道自己要設計的是哪一種東西。