系列: 與 AI 一起學寫程式

今天,每個 LLM 呼叫端都裝上了提示長度防護

一次成本暴增、一場稽核,以及裝在每個 LLM 呼叫端上的提示長度防護。

每個 LLM 呼叫端,一道防護 逐呼叫端 token 預算、截斷層級、遙測、CI 強制執行 無上限 5 個呼叫端,沒有長度上限 已封頂 有預算、有記錄、有邊界 LLMCallGuard 截斷並記錄 粗粒度後備 大聲失敗 CI 回歸閘門
一道共用防護,把無聲的成本放大變成一次大聲、有邊界的失敗。

一個無上限的提示,就是一場等著發生的成本放大攻擊。RakuAI 把提示長度紀律當成安全基礎設施——在建置時強制執行,而不是靠記性。

執行期呼叫 LLM 的地方比我原本掌握的還多。有最明顯的那個(驅動語音式 AR 體驗的 XRAssistantService)。有比較不明顯的那個(NPC 行為層,世界裡代理的大腦有一部分就是一次 LLM 呼叫)。還有最不明顯的那個(開始悄悄滲入執行期建置的開發期工具:結構描述驗證器、除錯分析器、自動化遊戲測試摘要器)。

這些地方在過去六個月裡各自獨立寫成。每一個在 PR 階段都審查過。但在這個週末之前,沒有任何一個對提示長度有統一的紀律。

這篇文章要談的是:這為什麼變成了問題、稽核發現了什麼,以及新的護欄長什麼樣。

問題是怎麼浮現的

導火線是一次例行的成本監控檢查。看每日的 LLM API 支出時,有一個特定的開發環境花的錢是其他環境的十五倍。相同的代理數量、相同的測試工作負載、相同的模型。十五倍的成本。

追查這次暴增,最後指向遊戲測試摘要器的程式路徑。摘要器會拿一場結束的遊戲測試工作階段,把相關的場景狀態打包進提示,送給雲端 LLM,然後拿回一份該工作階段的結構化分析。這個函式是在場景還很小的時候寫的。「相關的場景狀態」是一份事件經過的結構化摘要。隨著時間推移,摘要愈長愈大。某個開發環境一直在跑很長的遊戲測試,產出了巨大的摘要。摘要器把這些摘要不加檢查地送給模型。而模型是按 token 計費的。

那單一呼叫端的修法很明顯。給摘要長度設上限。必要時截斷。截斷發生時記錄下來。

更深的問題是我接著問的那一個:執行期裡還有多少其他呼叫端有同樣的弱點?我去找了。稽核才是真正的工作。

稽核發現了什麼

執行期裡有十一個呼叫 LLM 的地方。這十一個之中:

  • 兩個有明確的長度檢查,溢出時的行為也合理(截斷、記錄、用較小的脈絡重試)。這些沒問題。
  • 五個完全沒有長度檢查。呼叫者遞什麼它們就送什麼。
  • 三個有長度檢查,但寬鬆到沒有用(十萬個 token,遠高於任何合理用量,但又遠低於災難等級)。
  • 一個是根本不該出現在正式版二進位檔裡的除錯路徑;它有長度檢查,但透過一個除錯旗標就能輕易繞過。

沒有長度檢查的那五個是最緊急的。它們涵蓋:遊戲測試摘要器(已經找到的那個)、NPC 行為大腦(如果 NPC 能觀察到複雜場景,可能會非常巨大)、結構描述驗證器(可能被遞入任意檔案)、世界狀態描述器(可能描述任意大的世界區塊),以及一個面向開發者的診斷工具。

這些每一個都是在各自的 PR 裡落地的。每個 PR 單獨看都合理。「每個 LLM 呼叫端都有長度上限」這種整體紀律不曾是任何人的職責。所以沒有人做。

防護長什麼樣

一小塊基礎設施在星期六早上落地,並在一天之內套用到每個呼叫端。

一個共用的 LLMCallGuard 工具。現在每個和 LLM 對話的地方都改走這個工具,而不是直接組建請求。這個工具接收一個提示範本、一個脈絡酬載和一個目標模型。它強制執行長度上限(可依模型設定,預設值依據模型文件上的脈絡視窗合理給定)。它會記錄實際使用的提示長度:在預算內時以 INFO 層級記錄,必須截斷時以 WARNING 層級記錄,截斷後仍塞不進上限時以 ERROR 層級記錄。

逐呼叫端預算。執行期裡每個 LLM 呼叫端現在都有明確的逐呼叫 token 預算。預算低於模型的脈絡視窗,因為我們要為回應留餘裕,也因為我們寧可在模型無聲失敗之前先大聲失敗。預算從幾千個 token(結構描述驗證器)到兩萬個 token(遊戲測試摘要器,這個真實上限能防止當初那次事故)不等。

遙測。每次 LLM 呼叫現在都會記錄提示大小、回應大小、模型、消耗的預算和延遲。遙測是讓我能在帳單寄來之前就注意到下一次事故的東西。

一套失敗模式層級。當呼叫端的酬載超出預算時,工具會依序嘗試一連串補救。第一步,嘗試智慧截斷(保留最近的脈絡,丟掉最舊的,讓系統提示保持完整)。第二步,如果智慧截斷仍然塞不下,嘗試更粗的截斷(整段整段地丟)。第三步,如果怎麼截都塞不下,就帶著清楚的錯誤大聲失敗,而不是送出一個模型終將拒絕的超大請求。這套層級意味著大多數情況能優雅恢復、極端情況以可觀察的方式失敗,而且沒有任何呼叫端會送出無上限的酬載。

一道防止回歸的 CI 檢查。新的與 LLM 對話的程式碼必須走 LLMCallGuard。CI 掃描會找出任何繞過這個工具的新增直接 LLM 呼叫並標記該 PR。這個模式和幾個週末前安全稽核對管理端點用的是同一套:在建置時強制執行紀律,而不是靠審查。

我學到了什麼

三件事。

不是任何人職責的紀律,就是不會發生的紀律。那十一個 LLM 呼叫端在各自的 PR 階段都合理。整體行為沒被審查,因為沒有人擁有這個橫切關注點。修法是把這個橫切關注點做成一塊每個呼叫端都必須經過的基礎設施,讓這條紀律不可能被遺忘。

成本是一種安全議題。我原本把「無上限的提示」當成正確性或穩健性的議題。開發環境的成本暴增教會我把它當成安全議題。一個能影響執行期送出的 LLM 呼叫內容的攻擊者,就能讓營運者承擔任意的成本。同一套防禦(長度上限、預算強制、遙測)同時防護穩健性失效和成本放大攻擊。

按節奏稽核。今天的稽核找到了五個 PR 審查漏掉的弱點。下一次稽核會找到別的。針對特定橫切關注點跑排程稽核的紀律,是我找到的唯一可靠方法,能把審查漏掉的東西挖出來。

合作夥伴和開發者該從中學到什麼

如果你正在營運任何從正式程式碼呼叫 LLM 的東西,而你還沒有針對提示長度紀律稽核過每個呼叫端,去做吧。稽核不大。很可能有發現。今天做的成本,遠小於出事之後才做的成本。

如果你是打造「會呼叫其他 LLM 的代理」的 AI 實驗室,該優化的指標是「代理在組建無上限提示時會不會發出警示」。大多數代理不會。會的那些,才是我敢託付重要工作的。

如果你正在評估一個引擎作為合作對象,而這個引擎整合了雲端 LLM,去問問提示長度紀律。正確答案是「每個呼叫端都走同一個共用工具,有逐呼叫端預算、有遙測、有 CI 防護」。錯誤答案是「我們還沒遇過那個問題」。

星期六下午。執行期裡的每個 LLM 呼叫端現在都走同一道防護。下一次稽核的節奏已經排上行事曆。

回去繼續打造。

在一個守住每次 LLM 呼叫的執行期上打造

RakuAI 是你的模型能在正式環境中駕馭的 AI 原生空間執行期——提示長度預算、遙測和 CI 強制執行都內建在邊界上。看看有紀律的基礎設施能為你的技術堆疊帶來什麼。

← 所有文章