終於可以只開一個資料夾了
最近在跑一個 multi-tenant 的 agent 設定,踩了很久一個問題:只要 agent 需要讀 host filesystem,你只有兩個選擇,要嘛開 tools.fs.workspaceOnly: true,要嘛幾乎整台機器都開放。中間根本沒有第三條路。
這在 shared gateway 的場景下超尷尬。我有一個 knowledge base 掛在 /data/shared/context/,希望 agent 可以讀,但不想讓它亂摸其他地方。以前的做法是寫一堆 workaround,或直接把東西搬進 workspace。很麻煩,而且 workspace 一直堆垃圾。
後來升上去之後,這個問題變得乾淨很多。tools.fs.roots 現在可以設 allowlist,每個 root 可以獨立指定:
tools:
fs:
roots:
- path: /data/shared/context
kind: dir
access: ro
- path: /workspace/agent-output
kind: dir
access: rw
kind 可以是 dir 或 file,access 是 ro 或 rw。設好之後,read/write/edit/apply_patch 全部都走這套限制,local media 載入和 prompt image auto-load 也一起被管控,不用個別設定。
有個細節我比較在意的是安全性。之前擔心的一個問題是 TOCTOU(time-of-check to time-of-use)gap,就是 path validation 和實際 file open 之間如果有人動手腳,可能會有安全漏洞。現在改用 pinned file-descriptor 的做法,root-scoped read,這個 gap 基本上就關掉了。alias-safe,canonical root precedence 也有做。
另外有一個行為要注意:如果你把 roots 設成空 array([]),效果是 deny-all,不是 unrestricted。這跟沒設不一樣。我一開始設錯,debug 了一段時間才發現。
sandbox mode 那邊沒有動,還是靠 Docker isolation,所以如果你跑的是 sandbox,這套 roots 設定不會吃進去。這個設計我覺得是對的,避免 host 和 container path 之間的混淆。
對我來說,這個改動最大的價值是終於可以把「mounted knowledge directory」的 pattern 做乾淨了。以前這種場景要嘛縮手不做,要嘛開太大。現在可以直接:
tools:
fs:
roots:
- path: /data/knowledge/product-docs
kind: dir
access: ro
agent 只讀得到這個資料夾,其他地方完全碰不到。skill 裡面的邏輯也不用改,讓 infra 層做控制就好。
如果你有在跑 shared gateway、多個 agent 共用一台機器、或是有 external knowledge base 需要掛進去,這個功能值得認真設一下。workspaceOnly 那個 binary 開關終於不是唯一選項了。⚡
作者:Jesse