打開你的 Agent 紀錄,找一次工具呼叫,看最後那一欄的工具回傳值(tool result,工具執行後交回模型的內容):是一句 success: true,一長串原始錯誤堆疊,還是三千行檔案內容?這一欄提供的資訊,會影響模型下一步做什麼。在個人網站 jxnl.co 發表 RAG 與 context engineering 系列文章的 Jason Liu,2025 年 8 月 27 日把他的觀察寫成一句話:
"The metadata became prompt engineering itself." (Jason Liu, Beyond Chunks: Why Context Engineering is the Future of RAG, jxnl.co, 2025-08-27)
他的意思是,工具回傳的結構與附註,本身就在教 Agent 怎麼想。Arize 那篇 context 管理的整理站在另一邊:回傳值多附一段說明,就多佔一段 context window(模型一次能讀的內容上限),所以過大的結果要截斷。這篇把五個一手來源放在一起,看各自怎麼寫回傳值,又在哪裡互相拉扯。
快速回答 工具回傳值可從五處改善:錯誤位置(SQLGlot)、評分未過的原因(OpenAI Cookbook)、過大結果的續讀提示(Arize 整理的四套 Agent 駕馭層,harness)、搜尋漏掉的類別統計(Jason Liu)、第二個模型的意見(Amp oracle)。這五個來源沒有提供做法之間的對照實驗,無法排名。能寫成規則的檢查先用程式,語意品質才交給模型;新增的內容也佔 context window,要能改變 Agent 的下一步才值得。
圖 1 的五條結論各來自一個一手來源。下一節先把它們攤成一張表,再逐一看兩邊的說法在哪裡對不上。
五種做法放在一起:什麼時候回、回什麼、給誰用?
五種做法的差別在回傳的時機、內容與適用的工具類型,各自插在工具呼叫的不同位置。表 1 先給全貌,圖 2 標出每一種的位置。
「回傳時機」指回傳值在工具呼叫的哪一刻產生:執行前攔下、結果回來時加工,或是另一條線上的回饋。「回傳內容」指最後落進模型視野的文字長什麼樣子。五個來源裡,SQLGlot 是函式庫,文件沒有談 agent;Arize 與 Jason Liu 寫的是設計觀察;OpenAI Cookbook 與 Amp 各是一套可以對照的實作。讀表時要留意,這五個來源的證據類型不同,彼此不能當作同一種對照實驗的五個組別。
- 執行前,解析失敗時
- 錯誤描述、行、欄、前後文與反白片段
- 輸入有語法可驗證,例如 SQL
- 每輪產出之後,評分失敗時
- 程式評分器回預寫句;模型評審回評分理由
- 規格能寫成規則,或需語意判斷
- 結果超過上限時
- 預覽加續讀提示,或完整結果存磁碟
- 檔案讀取、grep 這類大輸出
- 每次搜尋回傳時
- 結果加來源、分類統計(facets)與系統指示
- 檢索、搜尋類工具
- Agent 主動呼叫時
- 唯讀子代理的分析(格式文件未寫明)
- review、debug、規劃卡關時
表 1 五種做法對照。「適用場景」一欄是本站歸納,五方各自沒有這樣分類。來源見各節與參考資料,查閱於 2026-10-23。
圖 2 的線 A 是多數人想到的工具回傳值:模型發出呼叫,工具執行,結果回到模型。SQLGlot 的檢查插在執行之前,Arize 描述的截斷與 Jason Liu 的 facets 插在結果回來之後。線 B 與線 C 的回傳值不走這條路,後面兩節各用一段說明它們把文字送到誰手上。
回饋文字該由程式寫,還是由模型寫?
能寫成規則的檢查由程式回傳固定文字,寫不成規則的語意判斷才由模型生成理由;OpenAI Cookbook 的範例把兩種放在同一條流程裡。
這份範例是〈Self-Evolving Agents: A Cookbook for Autonomous Agent Retraining〉,頁面署名 Calvin Maguranis 等五位貢獻者。第一版在 2025 年 11 月 7 日進入 cookbook 儲存庫(依 GitHub 提交紀錄),頁面沒有標發表日。任務是草擬藥品法規文件的摘要,系統裡有四個評分器(grader,判斷結果有沒有達標的角色):
- 化學名稱:摘要有沒有保留原文的化學名稱,通過門檻 0.8。
- 摘要長度:與預期 100 字的偏離程度,門檻 0.85。
- 餘弦相似度:用分數衡量摘要與原文有多相近,分數越高越相近,門檻 0.85。
- LLM 評審(用大型語言模型當評審):以 gpt-4.1 依評分標準打分,門檻 0.85。
前三個是程式。它們失敗時,範例程式回傳事先寫好的句子,例如長度失敗就回:
"The summary length deviates too much from the expected length." (OpenAI Cookbook, Self-Evolving Agents,
collect_grader_feedback函式)
只有 LLM 評審的回饋是當次生成的:評審的推理文字原樣接進回饋。函式的說明寫著要把評分器的推理整理成「給 metaprompt agent 的可行動回饋」(原文:actionable feedback for the metaprompt agent)。收到回饋的是負責改寫提示的代理,它只在摘要沒通過寬鬆門檻時才執行,範例裡最多重試 3 次。頁面對 LLM 評審的定位是備援:
"The LLM judge provides a holistic failsafe when edge cases slip past deterministic checks." (同上)
SQLGlot 站在程式那一側。它是開源的 SQL 解析與轉譯函式庫,文件沒有談 agent;它的錯誤物件本來就帶了位置資訊。我在 2026 年 10 月 23 日用 30.24.0 版(PyPI 上 2026-10-20 發布的最新版)跑了一次:
from sqlglot import parse_one
from sqlglot.errors import ParseError
try:
parse_one("SELECT id FROM users WHERE")
except ParseError as e:
print(repr(str(e)))
print(e.errors[0])
第一行輸出是 "Required keyword: 'this' missing for <class 'sqlglot.expressions.query.Where'>. Line 1, Col: 26.\n SELECT id FROM users \x1b[4mWHERE\x1b[0m",第二行是同一個錯誤的欄位字典:description、line 為 1、col 為 26、start_context 為 SELECT id FROM users 、highlight 為 WHERE。
兩件事要注意。字串版本裡的 \x1b[4m 是終端機的底線控制碼,直接丟給模型只會多出雜訊;欄位版本沒有這個問題。另外,SQLGlot 的 qualify 會依 schema(資料表與欄位的定義)檢查欄位是否存在。我給的 schema 是 users 表有 id、name、tenant_id 三欄,檢查 SELECT nme FROM users 時,錯誤是 Column 'nme' could not be resolved. Line: 1, Col: 10,只說哪個欄位找不到,沒有列出有哪些欄位可用。
工程上的意思: 這個回傳值寫在工具外面那層包裝:先攔下 ParseError,只取 description、line、col、highlight 這幾個欄位組成回傳。要列出可用欄位,得由包裝層自己從 schema 查出來補上,這是本站的建議,SQLGlot 的文件沒有這樣做。
兩邊的取捨在成本與穩定度。程式版本不需要再呼叫一次模型,同樣的輸入每次回同樣的句子,但 Cookbook 的固定句子不含實際數字,長度失敗時模型讀不到是偏長還是偏短(本站觀察,函式裡的三個字串確實沒有數值)。模型版本能說出具體哪裡不好,每次的措辭不同,也多一次呼叫。
回傳值該多附一點,還是砍短一點?
Jason Liu 主張在搜尋結果旁多附 facets 與指示,Arize 整理的四套 harness 則各自限制過大的輸出,例如 Pi 保留開頭並提示續讀,Claude Code 存磁碟、回傳預覽;兩邊的一手依據都成立,差別在回傳值要回答的問題。
多附的一邊:Jason Liu。 他在那篇文章裡把搜尋工具的回傳分成四級,第四級加入 facets(對整批結果做的分類統計,例如各狀態各有幾筆)。他的示範是一個工單搜尋:回傳的 3 筆全是 Done,facets 卻顯示另有 5 筆 Open。回傳內容旁附了一段提示,建議再用 status="Open" 查一次。他的解釋是已解決的工單文件較完整,在相似度排序裡排得比較前面(這是他的說法,文中沒有量測)。第二級的範例則在結果後面加一段 <system-instruction>,告訴 Agent:同一份文件有多個片段時,改用 load_pages() 載入整頁。
他自己也畫了界線:
"Metadata that doesn't change agent behavior is just expensive noise." (同上)
砍短的一邊:Arize。 Aparna Dhinakaran 在 Arize AI 的部落格(2026 年 4 月,文章先發表於 X)比較了 Pi、OpenClaw、Claude Code 與 Letta 四套 harness 的 context 管理。以下數字都是該文的描述,我沒有逐一對照原始碼:
- Pi 的檔案讀取上限是 2,000 行或 50KB,先到先停,保留開頭、截掉後面,並在輸出尾端附上續讀提示:
[Showing lines 1-2000 of 50000. Use offset=2001 to continue.] - OpenClaw 沿用 Pi 的讀取限制,另外給工具結果 16,000 字元或 context window 的 30%(取較小者)。結尾看起來重要時(錯誤、JSON 的結尾括號、摘要關鍵字)保留頭尾,否則只留開頭。
- Claude Code 把過大的工具結果存到磁碟,換成 2KB 的預覽;單一工具上限 50,000 字元,單則訊息合計上限 200,000 字元。文中的例子是 60KB 的 grep 結果,在新 session 的第一輪就會被搬到磁碟。檔案超過 256KB 時,讀取會被拒絕,錯誤訊息指向 offset/limit 或 grep。
這篇文章同時說明,Claude Code 的兩道讀取限制可由 Anthropic 遠端調整,所以上面的數字是 2026 年 4 月的快照。Arize 自己的產品 Alyx 也這樣做:工具結果上限 10,000 個 token,大型 JSON 拆成壓縮預覽加伺服器端完整副本,模型再用 jq(篩選 JSON 資料的工具)取出需要的部分。文章開頭描述好的系統怎麼做,其中一項是:
"truncating content in a way that hints at what else can be accessed." (Aparna Dhinakaran, Context management in agent harnesses, arize.com, 2026-04)
工程上的意思: 上限與預覽要在工具包裝層設定。上限寫死在包裝層,模型就算沒要求,也不會一次收到五萬字元;續讀提示寫在回傳值裡,模型才知道下一步可以怎麼拿剩下的部分。
兩邊的差別可以這樣歸納:Liu 的回傳值回答「還有什麼沒被看到」,Arize 描述的回傳值回答「剩下的怎麼拿」。一個加內容,一個減內容,共同點是都把下一步需要的線索留在回傳值裡。
要不要把第二個模型包成工具?
Amp 把第二個模型包成名為 oracle 的工具,回傳值是它的分析文字,並且刻意不在 system prompt 裡鼓勵主 Agent 常呼叫它。
Amp 是一款 coding agent。官方 Chronicle 在 2025 年 7 月 4 日公告 oracle:背後是一個唯讀子代理,當時用 OpenAI 的 o3,主 Agent 是 Sonnet 4;公告說它比主 Agent 的模型慢一些、貴一些,但擅長 review、debug、分析與決定下一步。關於呼叫頻率,公告這樣寫:
"We consciously haven't pushed the oracle too hard in the system prompt, to avoid unnecessarily increasing costs for you or slowing you down." (Amp, Oracle, ampcode.com, 2025-07-04)
呼叫靠明講:公告列的範例提示包含請 oracle 檢查上一個 commit 的改動,以及遇到 bug 時要求 Amp 盡量多用 oracle(原文給的理由是它很聰明)。2025 年 10 月 1 日的公告說 GPT-5 取代 o3 成為 oracle 的模型,理由包含它不同的訓練來源,適合當 Sonnet 的搭檔。
比這兩則公告更新的是 Amp 文件(我於 2026 年 10 月 23 日查閱):Task 子代理使用與主執行緒相同的模型與推理強度,在自己的 context window 裡工作;文件說要求「ask the oracle」或「use the librarian」時,系統派出的是負責 review 或調查的子代理。依這份文件,oracle 的請求會交給與主執行緒同模型的子代理,oracle 目前用哪個模型,我查閱的文件頁沒有寫。「第二個模型來自不同公司」這個前提,在 Amp 現況可能已經不成立。
oracle 回傳的是另一個模型對 review、debug 或規劃的分析意見;Cookbook 的 LLM 評審則是檢查摘要,把評分理由交給改寫提示的代理。Amp 的公告沒有說明回傳的格式,也沒有說主 Agent 該如何處理與自己判斷衝突的意見。
我的建議是:想試這一種,把呼叫條件寫成可檢查的規則,例如同一個測試連續失敗兩次就呼叫;Amp 的公告則是靠人在提示裡明講。這個規則版本我沒有實測,成立的前提是你的任務卡關時,額外一次呼叫的延遲與費用付得起。
五種寫法看完,先改哪一欄?
先看自己工具的回傳值屬於哪一格:只回 success: true 的,補上狀態;可能回很大輸出的,先加上限;能寫成規則的檢查,先用程式回傳。
五種做法有一個共通處:每一種都在結果之外多放了一樣東西,位置、續讀提示、被漏掉的類別、失敗的理由、第二個意見。這是本站的歸納,五方各自沒有這樣講。
我的做法會照成本由低到高加,因為前面幾步不用多呼叫模型。第一步,包裝層攔下錯誤,只回位置與原因。第二步,替輸出可能很大的工具設上限,並在回傳尾端寫明怎麼續讀。第三步,檢索類工具再考慮附 facets,附之前先問一句:這段 metadata 會讓 Agent 多做哪一個動作?答不出來就別附,這是用 Liu 自己的界線來檢查他的做法。LLM 評審與 oracle 放最後,兩者都多一次模型呼叫,語意判斷無法寫成規則時才值得。
這個順序的前提是你的 Agent 已經會因為回傳值而走錯路。工具輸出一直很短、也沒有失敗紀錄的系統,不需要為了對齊這張表而改。
回到開頭那一欄。Liu 說 metadata 成了 prompt engineering,Arize 的作者說截斷要留下線索,Cookbook 的固定句子與 Amp 的公告也都在做同一件事:把工具回傳值當成寫給模型的文字來設計。下次打開紀錄時,先看那一欄寫了什麼,再回頭調 system prompt。
回傳值寫好之後,使用者在 Agent 執行到一半想插話,話要從哪個時機進去?下一篇接著談。
常見問題
工具失敗時,可以直接把原始錯誤堆疊丟給模型嗎?
可以,但建議先整理。SQLGlot 是開源的 SQL 解析函式庫,它的 ParseError 同時有字串與欄位兩種形式,字串裡有終端機的底線控制碼,欄位則有 line、col 與 highlight。取欄位組成回傳,就能保留錯誤位置,並去掉終端機控制碼。
回傳值太長要截斷時,該留開頭還是結尾?
視輸出類型而定。依 Arize 2026 年 4 月的整理,Pi 的檔案讀取保留開頭並附續讀提示;OpenClaw 在結尾出現錯誤、JSON 結尾括號或摘要關鍵字等重要內容時,改留頭尾。這些是該文描述的處理方式。
LLM 評審的回饋可以取代程式檢查嗎?
OpenAI Cookbook 的〈Self-Evolving Agents〉範例沒有這樣做:四個評分器裡三個是程式,LLM 評審被描述為備援。程式檢查不必多呼叫一次模型,同樣輸入得到相同回饋;Cookbook 這份範例的固定回饋句沒有附實際數字。LLM 評審能說出具體問題,但每次措辭不同,也多一次模型呼叫。兩者的取捨取決於規格能不能寫成規則。
Amp 的 oracle 一定要用另一家公司的模型嗎?
從我讀到的文件無法確認有這項要求。Amp 2025 年的公告把不同訓練來源當成優點;2026 年 10 月 23 日查閱時,文件寫明 Task 子代理(接手子任務的代理)與主執行緒使用相同模型,但沒有說明 oracle 當時用哪個模型。
延伸閱讀
- Agent 駕馭工程懶人包:Deep Agent 有哪些內建能力?三家說法對成六項
- 為什麼 AI 越聊越笨、一直犯同樣的錯?Anthropic 揭密 Context Engineering 實戰(2026 懶人包)
- AI 寫的測試全過,為什麼功能還是錯的?驗證閉環完整懶人包(2026)
參考資料
- Jason Liu, Beyond Chunks: Why Context Engineering is the Future of RAG(2025-08-27) https://jxnl.co/writing/2025/08/27/facets-context-engineering/
- Aparna Dhinakaran, Arize AI, Context management in agent harnesses: memory, files, and subagents(2026-04,查閱於 2026-10-23) https://arize.com/blog/context-management-in-agent-harnesses/
- OpenAI Cookbook, Self-Evolving Agents: A Cookbook for Autonomous Agent Retraining(頁面未標發表日;2025-11-07 進入儲存庫,2026-07-20 有修改紀錄;頁面標示為已封存,查閱於 2026-10-23) https://developers.openai.com/cookbook/examples/partners/self_evolving_agents/autonomous_agent_retraining
- OpenAI Cookbook,
autonomous_agent_retraining.ipynb(評分器與collect_grader_feedback原始碼) https://github.com/openai/openai-cookbook/blob/main/examples/partners/self_evolving_agents/autonomous_agent_retraining.ipynb - SQLGlot,
sqlglot/errors.py與 API 文件(本站以 30.24.0 版實測,2026-10-23) https://github.com/tobymao/sqlglot/blob/main/sqlglot/errors.py - SQLGlot, sqlglot.errors(API 文件,查閱於 2026-10-23) https://sqlglot.com/sqlglot/errors.html
- Amp, Oracle(2025-07-04) https://ampcode.com/news/oracle
- Amp, GPT-5 Oracle(2025-10-01) https://ampcode.com/news/gpt-5-oracle
- Amp, Tools(文件頁,查閱於 2026-10-23) https://ampcode.com/docs/tools
留言0
登入後就能留言。
登入