iT邦幫忙

2026 iThome 鐵人賽

DAY 25
0
AI Engineering

打造具備記憶與執行能力的常駐 AI Agent:Hermes Agent × Gemini × MCP 的 Harness 設計系列 第 25 篇

【Day 25】打開 mcp serve 以為會拿到 agent,拿到的是一座訊息橋

  • 分享至 

  • xImage
  •  

前面幾天都在把別人的能力接進來,今天反過來,看這個 agent 能以什麼形式被別人呼叫。它有四個指令名字裡帶 serve 或 peer,mcp serve、serve、acp、peer。四個做的事各不相同,其中只有一個是 agent 對 agent 的委派。


直接握手問它給什麼

hermes mcp serve 走 stdio,拿 JSON-RPC 打一次 initialize 加 tools/list 就看得到全部。回來的握手資訊:

欄位 值
protocolVersion 2025-11-25
serverInfo.name hermes
capabilities experimental、prompts、resources、tools 四項,listChanged 全為 false
instructions 167 byte

那段 instructions 把用途寫得很直接:

Hermes Agent messaging bridge. Use these tools to interact with conversations across Telegram, Discord, Slack, WhatsApp, Signal, Matrix, and other connected platforms

這個 server 暴露的是訊息層,呼叫端拿到的是讀寫對話的能力。 十個工具按職責分三組:

  • 讀對話:conversations_list、conversation_get、messages_read、attachments_fetch
  • 等事件:events_poll、events_wait
  • 送訊息與權限:messages_send、channels_list、permissions_list_open、permissions_respond

工具清單裡沒有「把一段任務交給這個 agent 去做」這種東西。要讓它做事,走的是送一則訊息進它的對話,再從同一座橋把回覆讀回來。


十個工具 7,629 byte

工具 schema byte 其中描述
conversations_list 979 456
events_poll 962 470
messages_send 925 514
events_wait 910 407
attachments_fetch 745 314
messages_read 742 332
channels_list 677 314
permissions_respond 597 190
permissions_list_open 584 289
conversation_get 508 149
合計 7,629 3,435

描述佔 45%。自建那個 MCP 的五個工具量到的是 54%,兩組都落在將近一半的位置。

這座橋掛到另一個 profile 身上的代價可以直接疊:同一台機器上那個 profile 目前的工具 schema 是 37,012 byte、20 個工具,接上去之後工具數加五成,byte 數加兩成。工具個數與 schema byte 的成長比例對不上,這一組工具的參數結構相對簡單。

量測工具這一側有個限制要先講。prompt-size 報的 20 個工具是內建工具集,它建的是離線檢視用的 agent,MCP 掛載的工具不在它的統計裡。MCP 這一側的 byte 要自己打 tools/list 算。


四個指令各自的位置

指令 對外暴露什麼 呼叫端是誰
hermes mcp serve 訊息橋接的 MCP server,十個工具 任何 MCP client
hermes serve JSON-RPC/WebSocket 後端,預設 port 9119 桌面應用程式與遠端 client
hermes acp ACP 模式 VS Code、Zed、JetBrains
hermes peer 把另一台機器的 gateway 註冊成 peer 這台機器上的 agent 或人

agent 對 agent 的委派在 hermes peer。 它的說明寫的是:hermes peer dm <peer>[/<agent>] "..." 把訊息送進遠端 agent 的 Bot Chat,印出回覆,是 hermes -p <bot> chat 的跨機器版本。

長時任務走另外三個子指令:

  1. peer run 送出一段長任務並回傳 run ID,支援 --idempotency-key
  2. peer status 讀該次執行的狀態與最終輸出
  3. peer stop 停掉其中一次執行而不影響同機器上的其他輪次

退出碼分三種:0 送達、1 投遞或 peer 錯誤、2 用法錯誤。前置條件是對方的 gateway 要跑 api_server 這個平台,它的 API_SERVER_KEY 以憑證形式存在本機的 .env。

這個形狀與前兩天的非同步工具是同一套想法。送出之後拿一個代號,之後憑代號查狀態,--idempotency-key 讓重送同一個請求不會變成兩次執行。


用 chat completions 串 agent 的那個反例

前面量可替換性那天留下一個失敗案例,剛好是這件事的反面。當時把一個 agent 的 OpenAI 相容端點填進另一個 agent 的模型欄位,外層以為自己接的是模型,內層實際是個會自己跑工具迴圈的 agent。

內層把它內部已經執行過的 tool_calls 一併回在回應裡,外層照 OpenAI 的語意理解成「這是要我執行的工具」,在自己的工具表裡找不到:

⚠ Unknown tool 'get_environment_status' — sending error to model for agent-correction (1/3)
✗ Max retries (3) for invalid tool calls exceeded. Stopping as partial.

tool_calls 這個欄位在兩邊的語意不同。 模型回它表示「請呼叫端執行」,agent 回它表示「我執行過了」,欄位名一樣,方向相反。

peer 與 mcp serve 兩條路都避開了這個問題。 前者把對方當成會回話的對象,收到的是最終文字,後者把對方的能力包成工具,由呼叫端決定要不要執行。兩條路都把 agent 放在 agent 的位置上。

一個元件回傳的欄位要怎麼解讀,取決於它在架構裡被放在哪個位置


跨過邊界的與留在原地的

被呼叫的那一側是一個完整的 agent,它有自己的身分宣告、記憶與工具集。委派時哪些東西跟著過去:

項目 跨不跨邊界
任務描述 跨,就是送過去的那段文字
呼叫端的 system prompt 與記憶 留在呼叫端
被呼叫端的身分宣告與記憶 留在被呼叫端,並且作用在這次執行上
工具執行的結果 以回覆文字的形式回來

委派出去的那段任務,實際是在另一套身分與另一組記憶底下被執行的。要它照某個規則做事,規則得寫在那一側,或者逐次寫進任務描述裡。


心得

打 tools/list 之前,預期看到的是一個可以接受任務的工具。回來的清單第一個是 conversations_list,第二個是 conversation_get,看到第三個 messages_read 的時候才確定方向整個不同。

instructions 那 167 byte 把它講得很清楚,messaging bridge。這個欄位在 MCP 的握手裡是給呼叫端看的說明,平常容易當成客套話跳過,這次它是唯一一句直接回答「這個 server 是做什麼的」的內容。

指令名稱裡的 serve 指的是「把某個東西對外提供」,至於提供的是哪個東西,名稱裡沒有寫。四個指令都叫 serve 或 peer,要分辨只能一個一個打開看。

握手回傳的 instructions 是 server 自己對用途的宣告,比指令名稱更接近它實際做的事


明天

同一支私鑰,換一種路徑寫法,判定從放行變成要確認。


上一篇
【Day 24】工具就在手上,模型查了三分鐘別的東西
系列文
打造具備記憶與執行能力的常駐 AI Agent:Hermes Agent × Gemini × MCP 的 Harness 設計 共 25 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言