Skip to content

Hermes Agent 的七種終端後端:換到沙箱等於關掉危險指令審批

2026年8月18日 1 分鐘
TL;DR Hermes 的指令可以跑在 local、ssh、docker、singularity、modal、daytona、vercel_sandbox 七種後端。關鍵取捨不是效能而是審批:local 與 ssh 會做危險指令檢查,其餘五種一律跳過,因為官方把容器/沙箱本身當成邊界。另外 Docker 預設是「一個長壽容器跨 session 共用」,不是每次對話一個乾淨環境。
目錄
  1. 七種後端與它們的隔離級別
  2. Docker 不是「每次對話一個乾淨容器」
  3. 遠端後端的真正陷阱:teardown 時只同步 Hermes 自己的狀態
  4. 三個雲端後端的差別
  5. 兩個容易漏的行為
  6. 出問題時的第一步
  7. 參考資料

系列第 5 篇。導讀在這裡

「agent 跑指令」這件事,真正該問的問題是跑在誰的機器上、壞掉會炸到誰。Hermes 把這一層抽成可換的終端後端,設定只有一行 terminal.backend,但換掉的東西比想像多。

七種後端與它們的隔離級別

後端指令在哪跑隔離危險指令審批
local你的機器✅ 有
ssh遠端主機網路邊界✅ 有
docker單一長壽容器完整(namespace、cap-drop、PID 限制)❌ 跳過
singularityApptainer 容器(--containallnamespace❌ 跳過
modalModal 雲端沙箱完整(雲端 VM)❌ 跳過
daytonaDaytona workspace完整(雲端容器)❌ 跳過
vercel_sandboxVercel Sandbox microVM完整(雲端 microVM)❌ 跳過

第三欄是這篇最重要的一格,官方文件在安全章節寫得明白:沙箱型後端一律跳過危險指令檢查,因為「容器就是邊界」

這條規則本身合理,但它的推論常被忽略:一旦你為了安全把後端從 local 換成 docker,你同時關掉了「刪 / 之前先問你一聲」這種人類審批。安全模型從「人看著」變成「炸了也只炸沙箱」。如果你的沙箱裡掛了主機目錄、或轉發了 GITHUB_TOKEN,那個假設就不成立了。

Docker 不是「每次對話一個乾淨容器」

這是最容易誤解的預設值。Hermes 預設只起一個長壽容器,並把所有 terminal、檔案、execute_code 呼叫都 docker exec 進同一個容器裡——跨 session、跨 /new、跨 /reset、跨 delegate_task 生出來的子 agent 都是它。你關掉 TUI、/quit、重開一個 hermes,容器還在,下一個行程用 label 找回來繼續用。

也就是說:工作目錄變更、裝過的套件、/workspace 裡的檔案、背景行程都會延續。這對開發體驗是好事(不用每次重裝依賴),對安全是壞事(上一段對話的殘留物會被下一段看到)。

要「每段對話一個新鮮沙箱」得明確設定:

terminal:
  backend: docker
  container_persistent: false   # 每個 session 一個容器,結束即銷毀

這個模式下 delegate_task 的子 agent 仍與父 session 共用容器。官方的建議判準很清楚:當沙箱是「對話之間的安全邊界」時用 false,想要長壽共用環境時留 true

其他值得知道的 Docker 旋鈕:

  • docker_mount_cwd_to_workspace(預設 false)——Hermes 預設不會把你的當前目錄丟進容器。開了才等於讓沙箱直接動你的主機檔案,官方直接把它標成 security tradeoff。
  • docker_run_as_host_user(預設 false)——不開的話容器裡是 root,寫到掛載目錄的檔案在主機上是 root 所有,你得 sudo chown 才能改。開了就不用,代價是容器內不能 apt install、不能寫 /root/.npm
  • docker_network: false——整個容器 --network=none 斷網。注意切換這個值會移除既有容器並重建,裡面的背景行程直接消失。
  • docker_env vs docker_forward_env——前者把字面值寫進 config.yaml,後者從 shell 或 .env 轉發。祕密一律用後者,才不會把 token 寫進設定檔。
  • docker_extra_args——任意 docker run 旗標。官方警告得很直白:跟沙箱加固衝突的旗標(cap drop、--user、workspace bind mount)會靜默削弱隔離

Podman 開箱支援,設 HERMES_DOCKER_BINARY=podman 即可。

遠端後端的真正陷阱:teardown 時只同步 Hermes 自己的狀態

SSH、Modal、Daytona 這三個後端,Hermes 會在 session 期間把你的 ~/.hermes/ 狀態(憑證檔、skills、cache)推進遠端沙箱,並在 teardown 時把變更過的狀態檔依內容雜湊比對後同步回主機;遠端新產生的檔案(例如 agent 在遠端寫的新 skill)也會對應回主機路徑。上傳專用的憑證檔永遠不會被反向覆寫。同步會重試三次,且拒絕解開超過 2 GiB 的遠端封存。

聽起來很周到,但官方緊接著寫了一句必須背下來的限制:

This covers Hermes state (~/.hermes/), not arbitrary working-tree files inside the sandbox — have the agent copy important artifacts out explicitly.

沙箱裡的工作檔不會自動回來。 agent 在 Modal 沙箱裡跑了三小時產出的報告,如果沒有明確 scpmodal volume put 出來,沙箱一銷毀就沒了。這是這一層最容易造成實際損失的行為。

Docker 與 Singularity 不受此限——它們用 bind mount 直接看主機檔案系統,不需要同步。

三個雲端後端的差別

ModalDaytonaVercel Sandbox
認證MODAL_TOKEN_ID + MODAL_TOKEN_SECRET~/.modal.tomlDAYTONA_API_KEYVERCEL_TOKEN + VERCEL_PROJECT_ID + VERCEL_TEAM_ID 三者齊全
持久化方式檔案系統快照,記在 ~/.hermes/modal_snapshots.json停止而非刪除,下次 resume快照/還原檔案系統
限制保留檔案系統,不保留活行程與背景工作磁碟上限 10 GiB,超過會被截斷並警告需要 pip install 'hermes-agent[vercel]';自訂磁碟大小不支援

Modal 與 Daytona 的賣點是閒置時幾乎零成本——沙箱休眠、收到訊息才醒。這對「gateway 常駐但一天只用幾次」的個人用法很划算,也是官方一直強調的「不綁在你的筆電上」。

Vercel Sandbox 是這半年新加的第七種,runtime 可選 node24 | node22 | python3.13。本機一次性開發也接受短期 OIDC token,但長跑的部署要用三件式 access token。

兩個容易漏的行為

persistent_shell:預設對 SSH 開啟、對 local 關閉。開啟時,一個 bash -l 長活著,cdexport、shell 變數都會跨指令延續。要在 local 也開就設 TERMINAL_LOCAL_PERSISTENT=true需要 stdin_data 或 sudo 的指令會自動退回一次性模式,因為持久 shell 的 stdin 已經被 IPC 協定佔住。

terminal.home_mode:預設 auto——主機安裝保留你真正的 OS 使用者 HOME,容器內則用 {HERMES_HOME}/home。這是為了讓 gitsshghaznpm、Claude Code、Codex 這些外部 CLI 找得到它們原本的憑證。代價是同一台機器上的多個 profile 共用同一份使用者級 CLI 憑證;需要一個 profile 用不同 git 身分或 SSH key,得改成 profile 模式並自己在 profile home 裡準備那些設定。

出問題時的第一步

官方的後端除錯清單很短,值得直接記:Docker 先 docker version;SSH 要 TERMINAL_SSH_HOSTTERMINAL_SSH_USER 都設;Modal 要 MODAL_TOKEN_ID~/.modal.toml;Daytona 要 DAYTONA_API_KEY;Singularity 要 apptainersingularity$PATH。而通則是——

When in doubt, set terminal.backend back to local and verify that commands run there first.

先退回 local 確認指令本身能跑,再往上加隔離。這跟供應商那篇講的「routing 先關掉」是同一個方法論:一次只加一層。

下一篇談記憶與技能——agent 會自己改自己的那部分。

參考資料