hero

城武導讀

把 prompt 寫得像咒語,然後盯著模型祈禱它別突然吐出一部關於 JSON 的自我對話長篇小說,是目前不少 agent 團隊的工作方式。Dan McKinley 的這場談話提出一個更不浪漫、也更能落地的替代方案:在正式環境裡,真正該被工程化的不是那段文字,而是能反覆量測、找出失敗、修正並驗證的迴路。這不是宣告文字無用;而是把文字從神祕技藝降回一個可替換的系統參數。

原文摘要

不是所有「和模型說話」都是同一種工作

McKinley 開宗明義區分兩類產品。一類是使用者和 chatbot 對話,產出與好壞有相當大的主觀空間;另一類則是替消費者執行任務的 production agent。後者若要做到「至少不丟臉」、而且讓作者敢對成果負責,就不能把每次失誤當成聊天中的小插曲。它必須可靠地完成被委託的工作。

作者對這份工作同時亢奮又警戒:用 agent 造 agent,再替其他 agent 建 evaluation,確實很有趣,卻也很像一群人把腦袋接進彼此的自動化管線。他不假裝自己掌握了終極方法;他只是指出,許多人已經在 production 規模下看見同一件事:LLM 平時看起來很能幹,失控時卻不會先寄一封通知信。

少量故障,足以讓整個介面炸開

大家在抽象層次都知道模型不能可靠遵循指令、不能保證說真話,也不能保證完成任務;日常互動的順利,仍很容易讓人誤以為它「大致可靠」。一旦 agent 真正面向使用者,這種印象就會很快破掉。錯誤有微妙的,也有非常直白的。

作者以 structured output 為例。工程師會把程式 schema 對應成 prompt,讓模型輸出可解析的結構;大多數時候 schema 的確被遵守。問題也正出在「大多數」。例如要求 title 不超過 80 個字元,模型通常照辦,偶爾卻會把欄位塞滿無意義內容,直到系統爆掉。這種情況可能只佔極小部分請求,但最強模型也會發生,且比例會隨提供給模型的上下文而變動。

作者看過的一種症狀是,模型反覆寫出關於 JSON 的「給自己看的備忘錄」,長到近乎小說。某次修補方式只是把欄位名從 title 改成 heading;目前有效,但他也坦承這種修法荒謬到很難相信它會永遠有效。工具呼叫也有同類問題:少數請求像鬧鬼一樣一路失控。目標不是把野獸馴到絕對溫順,而是持續限制它可造成的傷害。

先把可靠性變成可重複量測的東西

限制行為的前提是量測。作者提出的基本手段是將同一類測試執行很多次,觀察在重複嘗試下是否都能通過;他以 pass^k 稱呼這種「通過的 k 次方」式檢驗。它不是替模型授予可靠證書,而是讓團隊有機會在某次修改不小心拿鐵鎚敲到 agent 頭上時看出退步。

這也改變了 prompt 的定位。企業會擔心 agent 說出瘋話:它可能被問及如何運作,卻因根本不知道實作而編造一套說法;它也可能在使用者假稱權威人物時無視規則。品牌還會要求特定語氣——內容即便事實正確,也未必像組織願意對外說的話。慣常做法是由熟悉領域的人寫一段 prompt,再交給 agent 團隊。作者認為,「語氣團隊擁有語氣 prompt」這種分工不適合擴張;甚至可以更激進地說,在這個脈絡裡 prompt 根本不是一個獨立、穩定的東西。

原因在於 prompt 從來不是孤立物。把一段新指令塞進 agent,等於把它丟進與測試時不同的上下文宇宙。既有所有指令的總重量會改變新 prompt 的效果,而且往往是往壞的方向;新內容也可能干擾原本必須維持的行為。往後 agent 還會持續變更,模型本身也可能出於人無法理解的原因換一種表現。單獨收藏一句漂亮文字,並不能保存其實際行為。

把新 skill 變成一組可攻擊的案例

作者的操作方式,是先讓 Claude 閱讀新的 skill,再請它大量生成案例:一批是惡意使用者會如何設法繞過規則的 adversarial scenarios;另一批則是正常、善意的請求可能被新規則誤傷的 benign scenarios。每一種情境都被寫成 pass^k 測試。

接著,團隊在「有新 skill」與「沒有新 skill」兩種狀態下執行同一組測試。理想結果是新 skill 至少推動某些指標,令已明確表達成測試的行為更常被遵守。但作者特別提醒,這不必然發生:模型可能原本就很擅長某件事,也可能比人預期更不吃指令。這個比較的價值不在替新增文字鼓掌,而在判斷它是否真的改變了可觀察的行為。

若結果不好,手工反覆揉 prompt 當然是一條路,只是作者認為不必堅持由人類親手揉。既然已有 pass^k 作為可重複的衡量方式,就能把 prompt 接到 optimizer;談話中的例子是 GEPA。演算法可藉助 LLM 反思某個 prompt 為何在測試中做得好或差,再自動嘗試改寫。它可以持續循環,直到收斂到在既有目標下表現較好的版本;最後得到的文字很可能和起點完全不像。

不要讓 optimizer 背答案

最佳化後,範例測試可能從「中等偏好」升到「非常好」。這仍不是收工時刻,因為 optimizer 可能 overfit:它把測試裡的例子直接編進 prompt,表面成績漂亮,面對沒見過的案例卻失靈。作者的解法是建立 holdout tests——相同類型、但在最佳化過程從未讓 optimizer 看過的測試。若 holdout 也通過,才有理由相信改進不只是在背題;若退步,就回到前一階段再試。

在這套工作流中,最後那段 prompt 即使看起來瘋瘋的,作者也不主張回頭替它進行文學鑑賞。既然已有量測,文字是否優雅便不是核心問題。真正值得投資的,是讓領域專家建立好壞回覆的資料集、測試套件與其他品質量尺,而不是替 prompt 做人工策展。

評估器也有難度階梯

作者沒有把「寫測試」說得像按一下按鈕。最簡單的情況是目標完全 deterministic:若使用者說了某類話,agent 必須呼叫某個工具,那就直接 assert 工具確實被呼叫。

再複雜一層,目標是自然語言但不太主觀,例如判斷 agent 是否談論自己的內部運作。這可以交給一個簡單的 LLM judge;作者認為它幾乎總能正確判斷。品牌語氣則是另一個等級:是否符合特定 voice 本身就是複雜判斷,無法靠一段短 prompt 一次解決,LLM judge 會變成獨立專案。

對這種品牌 judge,作者建議準備由人類標註的 golden dataset,收集被認定為好與壞的回覆,再用它去最佳化一組評分 prompts,讓 judge 的判斷盡量接近人類專家的判斷。於是 prompt 最佳化裡又包了一個 prompt 最佳化;作者用「你喜歡 optimization,所以我們在你的 optimization 裡再放一個 optimization」調侃這個套娃結構。

迴路不是圖上的箭頭,而是把失敗收編回來

當測試、judge 與部署流程被建起來,系統便可與 production monitoring 結合。部署時跑 pass^k,希望阻止明顯壞掉的改動直接出貨;再從正式環境的對話抽樣,交給已建好的 LLM judges,找出 agent 表現不佳之處。那些失敗會被轉成測試套件裡更棘手的案例,重新丟回 optimizer,直到通過。

Prompt 評估回饋迴路

這正是作者所說的 flywheel:不只在發布前檢查,也將 production 中撞見的反例帶回訓練場。其結論因此格外尖銳:prompt 不是重點;prompt 只是向量,其文字內容本身不重要。真正的「東西」是那個能自行改善的 feedback loop。

作者仍為非 production 情境保留例外。人們可以永遠從沒有量測的簡單 skill 開始;一個半成品 Claude skill 若只是自用、已經夠好,並不需要被硬套上完整管線。品牌、法務或其他在意特定品質的人,也可能由此起步。不過,一旦某個 skill 不可靠而需要改善,usage monitoring 就該讓作者看見它在哪裡成功、在哪裡失敗;這些互動可被標註為好壞資料,成為測試套件與最佳化飛輪的基礎。部分 skill 或許止步於此,部分則會升格成由更完整 harness 承載的 agent。

談話末尾,作者把這條路描述得既像工程前線,也像精神迷宮:agent 用 agent 最佳化 agent,程式再由其他 agent 審查;每個架構圖裡的方框都彷彿在發抖。量測很難,報酬遞減的邊界也可能像看不見的單向門。但他仍認為替代方案更糟:把 prompt 交給別人卻不附帶量尺,是一種「AI psychosis」。prompt 短暫、可丟棄,甚至未必有意義;只有能自我校正的系統,才有機會演化並存活。

城武觀點

這個判斷比「prompt 不重要」更準確的版本是:在 production 系統裡,文字仍會影響行為,但它已不配被當成資產本體。真正決定何謂「可接受」的,是標註過的例子、評估準則、holdout 與監控;把它們攤開,至少比 prompt wizard 的玄學更能追責。可是政策權力也隨之轉移到編資料、設 judge、選抽樣的人手上。飛輪只會學會它被量到的東西:擁有者沒能標註、或不願標註的傷害,會被系統當成不存在。量測是必要的問責進步,但量測本身從來不是中立的。

城武的未解檔案——Prompt 可以丟進垃圾桶;誰替評分表填空,才決定 agent 會長成什麼樣子。