從文字預測器到行動主體
孤立的大型語言模型只做一件事:給定一段前綴 token,預測下一個 token。這裡蘊含的潛在能力驚人,但本質上是被動的——模型沒辦法查資料、沒辦法執行它沒背下來的計算、也改變不了世界。當你把這個預測器包進一個能讓它採取行動並讀回後果的迴圈裡,你得到的就是代理。模型不再是一次給出答案的神諭,而成為一個朝目標、跨多步運作的控制器。
自回归生成示意图:每个预测出的词元被追加并回送以预测下一个词元。
概念上的跳躍不大,後果卻深遠。第一卷把工具使用介紹為一種附加在模型上的能力;在這裡,我們把它當成整個系統的組織原則。本軌道後面所有東西——在推理上搜尋、規劃、記憶、執行程式碼、多代理團隊——都只是一個樸素想法的展開:把生成與來自模型外部的回饋交織在一起。
推理—行動迴圈
標準範式是推理—行動迴圈,由ReAct 模式發揚光大。每一步,模型先產生一段自由文字的思考(Thought)(它私下的思路),接著產生一個結構化的行動(Action)(一次工具呼叫),環境回傳一個觀察(Observation),迴圈持續到模型不再輸出行動、而是給出最終答案為止。推理與行動不是分開的兩個階段,而是交織在一起:每個新觀察都立刻重塑下一個思考。
一个大语言模型智能体循环,在推理、行动、观察三个阶段间往复。
state = [system_prompt, user_goal]
for step in range(max_steps):
out = model.generate(state) # "Thought: ... Action: search(q)"
if out.is_final_answer:
return out.answer
obs = tools[out.action.name](**out.action.args)
state += [out, format_observation(obs)]
return give_up()函式呼叫:有綱要的行動
如果行動只是自由文字,解析它簡直是惡夢。函式呼叫代理的做法是給模型一組有型別的工具綱要——名稱、描述,以及一個 JSON 形狀的參數簽章——並要求它輸出一個符合其中之一的結構化呼叫。實際上,模型是在對一套合法 API 呼叫的文法做受限生成。現代的服務堆疊會用引導式解碼來強制這點,讓輸出永遠是可解析的 JSON,而不會是半成品的呼叫。
正是在這裡,工具使用變得穩固到足以拿來蓋東西。一份好的綱要不只是替函式取名:它的描述其實是偽裝過的提示,教模型何時該用這個工具。把它們寫得像你寫系統提示一樣用心,因為對模型而言它們本就屬於同一段脈絡。
- 把每個工具定義成 `{name, description, parameters}`,其中 `parameters` 是一份標明型別、以及哪些欄位為必填的 JSON 綱要。
- 把工具清單連同提示一起傳入;模型會回傳一次工具呼叫,或一則最終訊息。
- 在執行之前,先用綱要驗證回傳的參數——不符就拒絕並重新詢問。
- 執行工具,把結果精簡地序列化,再作為下一個觀察餵回去。
工具是從哪來的?
在研究層次上,有兩個互補的答案很重要。第一個是學會去呼叫工具這件事本身:Toolformer 證明模型能以自監督的方式自學在哪裡插入 API 呼叫——做法是在它自己的訓練文字中取樣候選呼叫、執行它們,只保留那些能降低後續 token 損失的插入。完全不需要人工標註的工具示範;一次呼叫的有用性本身就是它的監督訊號。
第二個答案是把接線標準化。如果每個代理都對每個資料來源重寫自己的黏合程式,那就是 2000 年代整合惡夢的重演。模型脈絡協定(MCP)是一套開放協定,標準化了模型端的用戶端要如何發現並呼叫由伺服器所暴露的工具、資源與提示。它的好處在於可組合性:工具伺服器只寫一次,任何會說 MCP 的代理都能用它,不必量身打造程式碼。函式呼叫決定的是單一行動如何表達;MCP 決定的是行動目錄如何被遞送給代理。
失效模式與控制迴圈
代理迴圈是一支指令指標帶有隨機性的程式,所以它會以一般程式不會有的方式出錯。它會發明不存在的工具、無限重發同一個失敗的呼叫、或過早宣告勝利。讓系統可靠的地方,在於圍繞模型的那層控制迴圈——而非模型本身:限制步數上限、偵測重複的相同行動、把工具錯誤當成觀察呈現好讓模型能復原,並要求一個最終答案綱要,讓「完成」成為一個明確、可解析的事件。
形式上,该循环是一个递归:思考与行动从历史中采样,历史再以观察到的三元组扩展。