從 0 開始的 AI Agent 生活 · part 18
[Agent 進階 #18] 給你的 Hermes 做一次設定健檢:五個沒人細講、但你一定會撞的雷
❯ cat --toc
TL;DR
第 13 篇說:助理發瘋八成是「車子」(工具、設定、記憶)壞了,不是「引擎」(模型)笨。這篇是那張健檢表——五個我親手踩過的設定雷。寫這篇時我回去翻 Hermes code,發現兩個「不對了」:context_length 設 nested 那個,新版已經幫你修了;MCP 環境變數那個,是我當初解錯方向——env: 才對,我卻去包 wrapper。剩三個(Qwen thinking 沒關、label 沒跟端點對齊、plist/dashboard 維運)照舊會咬。每個都附一條丟給 agent 自己跑的檢查——「連我的雷都會過時」正是重點:以現在跑的為準,別信舊記憶。

第 13 篇我說過一句話:助理開始鬼打牆的時候,先別怪模型笨——八成是它外面那一圈(工具、設定、記憶)出了狀況。模型是引擎,外面那圈是車子;車子開不動,常常不是引擎壞,是輪胎沒氣、油路堵了。
那篇是概念。這篇是那張健檢表:車子最常壞的五個地方,每個我都親手撞過、也都給你一條可以直接丟給你的 agent 去跑的檢查——因為你的 Hermes 本來就有手,叫它「讀這篇、幫自己做一次設定健檢」是最快的。
前提照舊:你已經照入門 1-8 裝好、有一個在用的 Hermes 助理。這五個雷有個共通點——就算有噴錯,錯誤訊息也看不出真正的原因(頂多是 ECONNREFUSED、401 這種),只會讓助理「怪怪的」;知道往哪看,五分鐘;不知道,耗你一整晚。
先老實說一件事:寫這篇時我回去對了現在的 Hermes code,發現五個裡有兩個要更新——一個是 Hermes 後來修了(context_length),一個是我當初根本解錯方向(MCP 環境變數)。我照樣留著、也標清楚——因為這正是重點:設定的雷會過時、你對它的理解也會,兩邊都要以現在跑的東西為準(這其實就是雷 4 那件事)。所以每個雷我都附上「現在還算不算數」跟一條不管哪一版都成立的檢查。

雷 1:context_length 設錯一層會「一直健忘」(這個新版 Hermes 幫你修了)
症狀:對話才走到一半,助理就好像忘了前面講什麼,一直在壓縮、一直在「摘要前情」。你以為是記憶太小。
當時的雷:Hermes 要知道「這顆腦能吃多少字」,才知道在多少 token 該壓縮。我踩到的那版,它只讀最上層的 model.context_length;而我(跟很多人一樣)把它塞在 provider 底下:
# 我當時的寫法:塞在 nested
providers:
ds4:
models:
deepseek-chat:
context_length: 262144
舊版讀不到這層,就一路 fallback 去查公版資料庫,拿 alias deepseek-chat 查到一個不是我 256K 的公版數字。結果:模型明明開 256K,Hermes 內部卻用一個小很多的值——壓縮觸發點是抓「那個小值的一半」,不是真正 256K 的一半,所以遠比你想的更早就開始壓縮、丟掉前面,看起來就是「一直健忘」。

現行狀態(寫這篇時我回去翻了 code):新版 Hermes 已經修了——它現在連 provider-nested 的 context_length 也會解析(get_custom_provider_context_length),你設哪一層都吃得到。所以你跑的是近期版本的話,這個雷本身已經不會咬你了。
各版本都適用的檢查:不管哪一版,Hermes 一律用它自己算出來的 context_length,你要確認那個值就是後端真的支援的——而且別只比對設定檔,要看 Hermes 實際解析到多少。三邊對一下:後端 /props 的 n_ctx、你設定的 context_length、跟 Hermes 啟動時印的 Context limit:(互動/非 quiet 模式才會印,或用 /info 查):
curl -s http://<你的-後端-ip>:<port>/props # 後端 n_ctx
# 再對照 Hermes 啟動 log 的 Context limit: 跟你設定的 context_length —— 三個要一致
進階(想調到極致再看):真正決定「壓縮前能留多少」的不只是主模型的 context window,還有摘要模型(summarizer)的 context window——
auxiliary.compression.context_length,要對齊它自己後端的n_ctx。另外壓縮觸發點預設是主模型 context window 的 50%,某些模型/路徑會自動往上調(GPT-5.4/5.5 走 Codex OAuth 路徑時 85%、GPT-5.3 Codex Spark 70%、Arcee Trinity Large Thinking 固定 75%,而且不會把你自己設更高的值調低);主模型開 256K、但 summarizer 只有 96K 的話,實際能留的還是會卡在 summarizer 的 96K。
雷 2:Qwen 沒關 thinking,同一件事慢 10 倍
症狀:助理反應很慢、每句話前面都要「想很久」;叫它做機械式的事(例如一連串生圖 / 工具呼叫)慢到懷疑人生,還常常失敗。
真相:Qwen 3 / 3.6 這類模型預設開 <think>。對需要推理的問題很好,但對聊天、對一步一步照做的 pipeline,那段思考是純浪費。我實測過同一個 prompt:關掉 thinking,1058ms → 98ms(快 10.8 倍);生圖類任務從 6-10 分鐘掉到 30-90 秒,成功率也大幅提高。

修法:如果你的後端是 vLLM / SGLang 這類本地 OpenAI 相容端點,直接在該 provider 的 extra_body 用 nested chat_template_kwargs 關掉,不用改任何程式碼:
providers:
forge-gemma:
extra_body:
chat_template_kwargs:
enable_thinking: false
補充:網路上有些教學是去改
run_agent.py、靠環境變數關 thinking——那是舊的私改 patch,換版之後常常沒重貼、就失效了。寫在 config 裡才是換版也不會掉、你能直接複製的做法。(注意:關 thinking 的寫法跟後端有關——vLLM / SGLang 這類走上面 nested 的chat_template_kwargs;阿里雲 Model Studio 則是直接在頂層放enable_thinking: false。)順帶一提,Hermes 沒有專門的
temperature:欄位——所有取樣參數(temperature / top_p / top_k)也都走同一個extra_body。所以「關 thinking」跟「調 temperature」是同一個地方的事,一次弄懂。
丟給 agent 的檢查:叫它「量一下你回一句短話要多久;如果每次都先卡個一兩秒才吐字,去 provider 的 extra_body 確認 enable_thinking 是不是 false」(延遲多少算慢跟機器/後端有關,別當死標準,對照自己平常的手感就好)。
雷 3:MCP 工具全部連不上——你 shell export 的變數傳不進去
症狀:你照第 12 篇幫助理接了一個 MCP 工具,設定看起來都對,但一呼叫就失敗——ECONNREFUSED、連到 localhost、或直接沒反應。你檢查半天找不到哪裡錯。
真相:我踩到時是這樣——我在 shell export 了 API key、服務位址,理所當然以為 MCP 工具的子行程會像一般子行程那樣繼承。但 Hermes 開 stdio 子行程時有一份環境變數白名單(_SAFE_ENV_KEYS),只放行 PATH / HOME / USER / LANG / SHELL 這類基本的;你在 shell export 的東西不在白名單就被濾掉。工具拿不到位址,只好 fallback 到 localhost → 全部連線失敗。而且它不噴「環境變數不見了」,只噴一個看起來像網路問題的錯,超難猜。

正解:別靠 shell export,把變數寫進設定檔的 mcp_servers.<name>.env:——這一區塊 Hermes 一直都會 merge 進子行程,是這些變數該待的地方:
mcp_servers:
my-tool:
command: my-real-mcp-server
env:
MY_API_KEY: "…"
MY_SERVICE_URL: "http://<你的-服務-ip>:9000"
(誠實承認:我當初反射性去包了一層 shell wrapper,把變數 export 好再 exec 真工具——其實不必要,env: 一直都是對的管道,是我當時沒搞清楚,而且把 API key 硬寫進 wrapper script 反而更不安全。這正是這篇的另一半:有時候不是 code 過時,是你對它的理解過時。)
各版本都適用的檢查:MCP 工具連不上時,先確認它要的變數有沒有真的進到子行程(有沒有寫進 config env:),再去懷疑網路。叫你的 agent「列出所有 MCP 工具、各發一次最基本的呼叫測試;失敗那個先確認 env 有沒有真的傳進子行程」。
雷 4:光看 label 會誤判——要確認跑哪個模型,查 base_url 端點比較準
症狀:你的某隻分身(sib)行為跟你預期的模型不太一樣。你去翻設定檔,provider 名字寫著 gemma、default model 也寫 gemma,看起來沒問題。
真相:設定檔裡的 label 只是你當初打的標記——它會參與一些路由(例如挑 provider 專屬的 extra_body),但不代表後端現在真的載入哪顆。我有一隻分身,provider 標籤一直寫 gemma,但那個 base_url 指的端點,某天換腦之後實際在跑 Qwen3.6-27B,label 忘了改。於是我被這個 label 誤導了好幾天——以為在跑 A,其實在跑 B。

修法 / 檢查:要知道某隻 sib 真的在跑什麼,去 curl 它 base_url 指的端點,別讀設定檔的名字。
curl -s http://<你的-後端-ip>:<port>/v1/models # 端點回報它宣稱在服務的模型;單一模型後端就等於實際載入的,要更硬的證據就看後端啟動 log 或 /props
這條不是改一次設定就結束——是要養成一個習慣:設定檔記的是「你當初打算跑什麼」,端點回報的才是「現在後端宣稱在跑什麼」;時間久了,兩邊會對不上。 這也是這整篇的核心:設定檔不是故意騙你,是環境改了、卻沒人回頭同步它。要確認現在到底跑什麼,還是看端點實際回的。
雷 5:維運面兩個雷——plist 少了 PATH、還有別亂重啟 dashboard
前面四個是設定檔裡面的;最後兩個是設定檔外面、但一樣會雷到你的。
(a) launchd plist 少了 PATH,agent 的手就「拿不到工具」。Hermes gateway 是用 launchd 起的,plist 的 EnvironmentVariables 如果只給了半套 PATH,gateway 行程就找不到你裝在 ~/.local/bin / ~/bin 的命令列工具(像 qmd、musubi)——助理「有手但抓不到工具」。修法:在 plist 的 EnvironmentVariables 補上完整 PATH(要用絕對路徑,像 /Users/你/.local/bin——launchd 不會展開 ~),子工具需要的話再加 VIRTUAL_ENV,plutil -lint 驗過再重啟。
重啟的正確做法是 bootout → 動作 → bootstrap,而且別用固定的 sleep 3 去判斷它停了——實測 bootout 指令跑完、服務不一定已經停,通常還要再等幾秒,死等會誤判。改成先抓住舊的 PID、再輪詢 kill -0 <pid> 直到它真的沒了(設個上限別無限等),bootstrap 之後用 launchctl print 確認新服務真的起來,才穩(別直接 pgrep -f gateway 判斷:那顆行程的命令列是 hermes_cli.main gateway run、不是你想的 label,而且別的 profile 也可能一起被抓到,兩邊都會誤判)。
(b) 維護 gateway 的時候,別手動重啟 dashboard。dashboard 跟 bridge 靠一個共用的 session token 互信;你手動重啟 dashboard,會讓兩邊的 token 對不上,結果現有的手機連線就噴 401「bad response」。要重啟的話,先把當前活著的 token 抓下來、再釘回去,才不會斷線。
丟給 agent 的檢查:叫它「確認你的 gateway plist 的 PATH 有含 ~/.local/bin 跟 ~/bin;然後別碰 dashboard/bridge」。
把這篇丟給你的 agent 跑一遍
這五個雷的共通點,前面說過了:就算噴錯也不指向根因,只讓助理「怪怪的」。 所以最好的用法不是你自己逐條檢查,而是直接叫你的 Hermes 讀這篇、幫自己做一次設定健檢——它有手,跑得動這些檢查。
一份可以照抄的健檢清單(成功條件寫在後面,agent 做完自己知道過了沒):
curl 你後端/props的n_ctx== 你設定的context_length?(雷 1)- 回一句短話很快、沒有「想很久」?(延遲多少算快看你自己機器的手感)(雷 2)
- 每個 MCP 工具都能發一次最基本的呼叫測試、成功?(雷 3)
- 每隻 sib 的 base_url 端點
curl /v1/models回報的模型 == 你以為的?(雷 4) - gateway plist 的 PATH 含
~/.local/bin跟~/bin?(雷 5a)
五條全過,你的車子就順了。過不了的那條,回上面對應的段落——修法都在。
這一篇是設定層的健檢;想更往下挖「記憶那一塊怎麼運作」,可以回頭配著第 13 篇看——設定先調順、再回頭理解記憶,順序別反。
同系列文章:Part 17 — 教 Hermes 自己寫技能 · Part 13 — 助理鬼打牆,先別怪模型 · Part 12 — 幫助理接上你的工具
常見問題
- Hermes 助理莫名其妙一直「忘記」前面講過的話,是記憶壞了嗎?
- 常常不是記憶壞,是 Hermes 讀到的 context_length 跟你以為的不一樣。我踩到的舊版 Hermes 只讀 top-level 的 model.context_length,你設在 providers 底下(nested)它讀不到、會掉到一個公版數字,結果在一半就開始壓縮、丟掉前面=健忘。新版 Hermes 已經修了——現在 nested 那層也會讀。不管哪一版,穩的做法是把三個值對一下:後端 /props 的 n_ctx、你設定的 context_length、跟 Hermes 啟動印的 Context limit:,別假設它讀到你以為的值。
- 為什麼我幫 Hermes 接了一個 MCP 工具,它卻一直說連不上 / 全部失敗?
- 多半是你在 shell export 的變數沒傳進去。Hermes 開 stdio MCP 子行程時有個安全白名單(_SAFE_ENV_KEYS),只放行 PATH、HOME 這類基本的;你在 shell export 的 API key / 服務位址不在名單內就被濾掉,工具只好 fallback 到 localhost、全部連線失敗,而且只噴一個像網路問題的錯。正解不是包 wrapper,是把變數寫進設定檔的 mcp_servers.<name>.env: 區塊——那一塊 Hermes 一直都會 merge 進子行程。工具連不上時先確認變數有沒有真的進到子行程,再懷疑網路。
- 怎麼確認我的 sib 到底真的在跑哪個模型?
- 去 curl 它 base_url 指的那個端點,不要看設定檔裡的 provider 名字。設定裡的標籤(label)只是你當初打的標記、不會自己更新;你換了後端腦、標籤忘了改,它就會一直誤導你。要確認,直接打 base_url 的 /v1/models 或 /props 看它回報什麼模型——那才是端點現在宣稱在服務的(單一模型後端就等於實際載入的那顆)。
- 這篇適合誰?我還沒裝好 Hermes 可以看嗎?
- 這是進階篇,預設你已經照入門 1-8 裝好、能用一個 Hermes 助理了。如果你只是想先把助理裝起來、接上手機,先回頭看入門那幾篇。這篇是給「已經在用、想把它調順、或已經開始踩雷」的人。
接著讀
- 2026-06-22[Agent 進階 #13] 助理開始發瘋?先別怪它笨——八成是「車子」壞了,不是「引擎」壞了
AI 助理鬼打牆、亂跑、卡住、答非所問,你的第一反應通常是「這模型真笨」。但根據我自己一路 debug 的經驗,八成不是模型的問題,而是它外面那一圈(工具、設定、記憶)出了狀況。模型是引擎,外面那一圈是車子——車子開不動,常常不是引擎壞,是輪胎沒氣、油路堵了。
- 2026-07-01[Agent 進階 #17] Hermes 的 /learn:讓一隻本地 27B 把「做過的事」自己寫成可重用技能
Hermes 有個叫 /learn 的指令,能把『你做過的事』自動整理成一份可重用技能(一份 SKILL.md)。這篇我把它接上自己的艦隊實測:派一張 Kanban 卡,讓一隻跑在改裝 2080 Ti 上的本地 27B 模型,3 分鐘把一次遊戲開發蒸餾成一份合格技能——還挖到兩個文件沒講清楚、實作才會踩到的細節:斜線指令 vs 派工、技能到底存哪。白話講 /learn 是什麼、怎麼用、以及它的真實限制。
- 2026-06-17[Agent 進階 #10] 一個人養一群助理:每個分身有自己的桌子、自己的腦、自己的記憶
一個助理用熟了,想再養第二、第三個?Hermes 讓每個分身有自己獨立的家(設定、記憶、個性),可以各跑不同模型、各管不同任務。這篇用白話講為什麼要分身、怎麼分,以及我實際養的那幾隻。誠實說:一般人一個就夠,這是想玩才需要的進階玩法。
- 2026-06-29[Agent 進階 #16] 同一份規格,丟給三隻分身各寫一個俄羅斯方塊:Hermes 看板派工實測
養了一群分身之後,我把同一份「做個俄羅斯方塊」的規格——就一句話、細節啥都沒講——一隻分身發一張卡,讓三隻各自一次寫完一個網頁俄羅斯方塊。我一行遊戲碼都沒碰,只負責發布。結果蹦出個意外驚喜:靠 Hermes 這套外框加一顆我自己在家調、跑在改裝 2080Ti 上的小模型,居然一次就把我沒要求的 ghost、wall-kick 都補上了。成品點開就能玩。
不想錯過新文章?
訂閱我確保不漏接!
隨時一鍵退訂。