「自己託管」coding agent,先問你控制的是哪一層

Ryan Vale
·
·
IPFS
·
自己託管 coding agent 不代表模型也在本機。文章用四份契約拆開推論、執行、資料外流、憑證與 worker 生命週期的控制邊界。

一個小型 SaaS 團隊想讓 coding agent 修改 private repository、安裝內部 package,再連到 staging API 跑整合測試。為了不把完整工作環境放在工具供應商的雲端,他們把 worker 搬進自己選擇的 Sandbox。

Repository checkout 留在這台機器,build cache 也在,內部服務終於連得上。會議裡很容易出現一句話:「現在是 self-hosted,程式碼都留在我們這裡。」

這句話只有一半是真的。

以 Cursor Cloud Agents 接上 Vercel Sandbox 的架構為例,Sandbox 負責 clone repository、改檔、執行命令與測試;agent loop、planning 和 inference 仍由 Cursor 管理。為了決定下一步,遠端服務仍可能需要檔案內容、terminal output、diff、screenshots 或 local MCP 的結果。部分執行產物也可能上傳,供 PR 或操作介面顯示。

團隊確實控制了 agent 工作的房間,但沒有因此取得整棟建築的控制權。

Self-hosted 描述的是部署位置,不是完整責任

討論 coding agent 時,我們常把選項切成 local 與 cloud。實際架構已經沒那麼整齊。規劃可以在供應商端,命令在客戶選擇的 worker 執行,任務佇列由另一個控制面協調,產物又回到代管服務保存。

因此,「agent 跑在哪裡」不是單一答案。至少要把這幾個位置分開:

  • agent loop 與模型推論在哪裡

  • 誰建立任務、claim queued work 並處理 retry

  • 誰提供 worker image、repository checkout 與網路

  • screenshots、logs、diff 和最後產物存在哪裡

  • 誰做最終 review,誰有權把結果送進 production

同一個 request 可以跨過多個控制方。產品介面上的一個按鈕,不會讓這些責任自動合併。

自管 worker 的價值仍然很具體。團隊可以使用自己的 image、硬體與網路路徑,讓 agent 存取 private package 或受限服務,也能決定 worker 如何擴縮。但這代表團隊接手的是 tool execution 與 compute 的一部分,不是整個 agent 系統。

不要只問資料存在哪裡,要追它怎麼流動

完整 checkout 留在自管環境,是一條有用的邊界。它能避免為了執行每個任務,都把整份 repository 複製到另一個遠端 worker。然而,agent 若要閱讀程式、判斷錯誤並產生下一個動作,必要內容仍可能跨出這條邊界。

真正可 review 的問題應該逐項列出:

  • 哪些檔案路徑允許送作模型 context

  • terminal output 與 MCP result 是否會夾帶 token、連線字串或客戶資料

  • diff、screenshots、videos 和 log references 會送到哪裡

  • 每一類資料為什麼需要送出,會保留多久,誰能讀取

  • 任務完成後,哪些衍生產物仍留在供應商管理的儲存空間

這比一句「資料留在自己的機器」麻煩,卻也準確得多。Repository 沒有整份離開,不代表從 repository 取出的內容從未離開;staging credential 沒有寫進 prompt,也不代表它不會出現在 terminal 的錯誤訊息裡。

資料治理在這裡不是勾選 data residency 選項,而是沿著一次任務,把每個輸入與輸出的路徑畫出來。

長期鑰匙不該跟著每次任務進 worker

Worker 需要權限才能做事,但它不該因此拿到整套長期憑證。

Vercel 公開的參考架構把 Cursor service-account key 留在 Functions/Workflow 控制面,再為單次 microVM 產生一小時、user-scoped 的 worker token。這個做法值得抽象成一般原則:控制面負責保存長期身分、mint 與 revoke;單次 worker 只拿完成當前任務所需的短期權限。

同一個 worker 裡的權限還要繼續拆。讀 repository、下載 private package、呼叫 staging API 與上傳 artifact,不必共用一把無限制的鑰匙。網路也不該因為是自管機器就預設全部開放,而應限制到任務真正需要的目的地。

短期 token 不是萬靈丹。若 terminal output 沒有遮罩、worker image 長期不更新,或 retry 會重用已失效的 task state,憑證壽命再短也補不了流程缺口。權限設計必須跟 worker lifecycle 一起看。

Ephemeral worker 仍需要一份生命週期契約

One request/one Sandbox、固定 timeout、idle cleanup 與 scale-to-zero,都能降低任務互相污染和閒置資源長期暴露的機會。這些特性很吸引小團隊,因為不必維護一批永遠開著的 runner。

但「每次建立一台 microVM」只回答隔離單位,沒有回答整個生命週期。團隊仍要知道:

  • queued request 被誰 claim,重試時如何避免同一工作執行兩次

  • snapshot 內的 CLI 與 system packages 由誰更新

  • timeout 後要保留哪些除錯資料,哪些資料必須刪除

  • worker 銷毀前,commit、tests、logs 與 artifacts 是否已完整交回

  • cleanup 失敗時由誰發現,未回收權限如何撤銷

Reference architecture 提供的是可採用的組件,不是替部署結果簽發安全證明。客戶接手 worker image、secrets、scaling 與 production validation,也接手 patching、egress policy 和額外 compute cost。模型使用費通常也不會因為 compute 自管就消失。

用一個真實任務做邊界 review

回到那個需要修改前端並呼叫 staging API 的 SaaS 團隊。與其問「這套 agent 是否 self-hosted」,更有效的做法是拿一個 request 走完四份契約。

第一份是 plane ownership。列出 task queue、agent loop、inference、worker provisioning、repository checkout、artifact storage 與 final review 分別由誰持有。

第二份是 data egress。指定 agent 可讀的路徑,確認 terminal 與 MCP output 的遮罩方式,記錄必要的對外目的地與 artifact upload policy。

第三份是 credential scope。長期 service key 留在控制面;worker 取得短期、單次任務所需的 repository、package 與 staging 權限。每個 token 都要有 owner、用途與失效時間。

第四份是 worker lifecycle。任務開始時記下 request ID、sandbox ID、image version 與起始 commit;結束時交回 current commit、測試結果、已上傳產物、cleanup 狀態,以及仍未回收的權限。

這四份資料不必先做成龐大的治理平台。一張架構圖、一份欄位固定的 task receipt,加上可查詢的 cleanup event,已經比模糊的部署標籤有用。它們也讓安全、開發與財務能討論同一件事:哪些控制真的移回團隊,哪些服務仍由供應商持有,新增的責任需要多少人力與成本。

自管不是終點,而是重新分配責任

近期開發者社群對 agent 的討論,已經不只在比較模型能力。Agent management、configuration、reliability、authentication 與 billing,都是日常運轉的一部分。這很合理:當 agent 開始改檔、跑測試、接觸內部服務,部署邊界本身就是產品行為。

Self-hosted worker 可以解決 custom image、硬體、網路與資料位置上的實際限制。它也可能是團隊採用 cloud agent 的必要條件。問題在於,這個詞太容易讓人把「某一層由我託管」聽成「所有層都由我控制」。

成熟的採用決策,不需要先替 self-hosted 貼上安全或不安全的標籤。沿著一次任務,寫清楚控制面與計算面的持有人,追蹤跨界資料,縮小憑證,再驗證 worker 如何離場,就能看出這個架構解了哪個問題,又把哪些工作交回團隊。

你控制 agent 工作的機器,並不等於控制整個 agent。真正能被驗證的,是每一道門由誰打開、什麼東西穿過去,以及任務結束後是否真的關上。

Source notes

CC BY-NC-ND 4.0 授权
已推荐到频道:时事・趋势

喜欢我的作品吗?别忘了给予支持与赞赏,让我知道在创作的路上有你陪伴,一起延续这份热忱!