iT邦幫忙

2026 iThome 鐵人賽

DAY 19
0

昨天 loop 把能自己消化的錯分好了類,今天講要見人的那一半。場景:agent 的工具呼叫外部 API,回了 404。照 backend 的直覺,exception 往上丟,HTTP 層接住回 500,於是使用者看到一整段對話死在「Internal Server Error」,只因為一個查詢工具沒查到東西。

Agent 系統的做法完全相反:把同一個失敗變成一句話回給模型 —「查無此 ID,請確認格式」。模型讀到,自己換個查法,查到了,使用者從頭到尾不知道中間失敗過。同一個錯誤,一種處理殺死對話,另一種被無聲消化。差別在於錯誤的讀者變了:過去錯誤是寫給 log 和 on-call 工程師的,agent 系統的錯誤有兩個新讀者 — 螢幕前的人,和 loop 裡的模型。

錯誤是資料,自癒是模型的工作

這個哲學有官方背書:Anthropic API 的 tool_result 本身就有 is_error 欄位,文件明確建議失敗時回傳錯誤內容讓模型繼續,Vercel AI SDK 和 MCP 也是同一個模式。Claude Code 就這樣運作:指令失敗、編譯報錯,錯誤輸出回到 loop,模型讀了自己修。LLM 本身就是系統的一層自癒迴路。

把「誰有能力恢復」當分類標準,錯誤自然分成三層:

例子 處理 使用者看到
對話內可恢復 工具失敗、輸出解析失敗 變成資料回給模型 最多是「換了個方式查」
Run 級可重試 API 429、暫時性網路錯誤 標記可重試 「暫時忙碌」加重試按鈕
Run 級不可恢復 額度用盡、認證失效 誠實告知 一句人話

兩條實務紀律跟著來。第一,錯誤訊息的品質決定自癒的成功率:模型讀不懂 ECONNREFUSED 10.0.3.42:5432,讀得懂「資料庫連線失敗,稍後重試或改用快取資料」。第二,第二、三層的 error message 是產品文案,它會直接顯示在畫面上,內部細節進 log,靠 trace id 關聯。

三條信任邊界:LLM 的輸出等同不可信輸入

傳統 backend 只有一條信任邊界:user input。Agent 系統有三條,而且新的兩條更難防:

邊界一:使用者到模型。 這條是傳統 backend 原有的那條,原則沒變:user input 永遠不可信,照舊做輸入驗證。新增的工作只有一件,把使用者輸入和系統指令的角色分開(user message 歸 user message,別拼進 system prompt),防的是最直接的 prompt injection。

邊界二:模型的輸出到你的系統。 模型會幻覺(編造不存在的 ID)、會給畸形結構(數字給成字串),而且如果使用者的輸入含注入攻擊,模型生成的工具參數就是攻擊者間接控制的。防線是確定性的 schema 驗證擋在工具入口,而且業務上限直接寫進去:轉帳工具的 amount 欄位上限一萬,就算模型被騙也轉不出十萬。驗證失敗也不會 crash,它會變成回給模型的修正訊號(接回上一節的自癒迴路)。

邊界三:工具抓回來的內容回流進窗口。 網頁裡藏一句「忽略先前指令」,模型可能照做。這就是 Day 8(窗口經濟學)講的污染的攻擊版:間接 prompt injection。誠實的結論是擋不完:模型在結構上分不清資料和指令,標記和聲明只能降低成功率。真正的底線是權限設計:假設誘導一定偶爾成功,讓工具本身做不到越權的事。

一句話收攏三條邊界:模型的智力不能當安全機制,防線放在確定性的程式碼裡。這正是 Day 7(Prompt 的極限)「文字約束 vs 架構約束」的答案篇:在 prompt 寫「不要亂刪檔案」是文字約束,讓刪檔工具碰不到系統目錄是架構約束,可靠性差一個量級。

真實系統的圍欄長什麼樣:Claude Code 的級聯防禦

Claude Code 的 permission 系統是一套多層級聯,從粗到細:session 級的授權模式(唯讀/工作區可寫/全開)先劃大框,可程式化的 hook 可以逐工具攔截,最危險的 bash 指令另外走一條八步驟的解析鏈,最後還有二十多個安全驗證器掃混淆手法(引號裡藏的 -rf、看起來像空格的 Unicode 字元)。

其中一個細節值得單獨看:deny 規則和 allow 規則對環境變數的處理是不對稱的。FOO=bar rm -rf /rm -rf / 在 shell 裡等價,所以 deny 規則激進剝離所有環境變數再比對(防繞過),allow 規則只認白名單裡的安全變數(防誤放)。同一個機制,兩個方向的錯誤代價不同,設計就跟著不對稱。這種細節是「權限當產品做」和「權限當 checkbox 做」的差距。

最後一道防線:Sandbox,假設前面全部失守

權限級聯攔的是「不該做的操作」,但邊界三留了一個沒回答完的問題:假設誘導一定偶爾成功,然後呢?答案是 sandbox:就算操作真的執行了,破壞也出不了那個箱子

DeerFlow 的做法是工具一律在沙盒環境執行,檔案操作走虛擬路徑映射,本機模式下連 host 的 bash 都不暴露給模型。NanoClaw(一個跑在通訊平台上的開源 agent 系統)更徹底:每個 agent 跑在 Docker 容器裡,只看得到被明確掛載的東西,而它最漂亮的一刀是憑證管理:API key 從頭到尾不進容器,由容器外的 proxy 在請求發出時才注入。就算 agent 被 prompt injection 完全劫持,翻遍容器也找不到可以偷的 key。

把今天的三層防線疊起來看就是縱深防禦:schema 驗證擋畸形輸入、權限系統擋越權操作、sandbox 保證前兩層都破了也傷不到外面。每一層都假設上一層會失敗,這正是「模型的智力不能當安全機制」推到底的樣子。

圍欄管住「不能做什麼」,能力還缺一塊

到今天,agent 有了時間軸(session)、手腳(工具)、圍欄(權限與錯誤設計)。還缺一種東西:把「怎麼做事」的方法知識打包成可以隨插隨用的模組。這就是 skills。為什麼它用文件而不是程式碼、為什麼 Day 8 的 progressive disclosure 在這裡又出現一次,明天講。


上一篇
Day 18|Agentic Loop:Agent 的心臟怎麼跳
下一篇
Day 20|Skills:把「怎麼做事」打包成模組
系列文
模型動不了,那你能動什麼?AI Engineering 四層工程觀:Prompt、Context、Harness、Loop20
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言