Module 02 · API Mechanics
模組 2 · API 機制
2.1 tool_choice 2.2 平行與 tool_result 2.3 依賴編排 2.4 結構化輸出 2.5 Tool 分配 討論題
🧱
還沒讀過 API 地基? 下面 2.1 一開頭就預設你知道 agentic loop、stateless、request/response 結構、快取三層。沒把握先花 5 分鐘讀
地基 · 一次 API 呼叫長什麼樣 ,回來會順很多。
2.1 tool_choice — 四個值背死
值 行為 備註
{"type":"auto"}模型自己決定要不要用工具 有給 tools 時的預設
{"type":"any"}必須 用某個工具(哪個它挑)強制型
{"type":"tool","name":"x"}強制 用指定工具強制型
{"type":"none"}禁用工具 沒給 tools 時的預設
三個高頻事實:① disable_parallel_tool_use: true 寫在 tool_choice 物件裡面 (不是 top-level 參數)——auto 時「最多一個」、any/tool 時「恰好一個」;② extended thinking 開啟時只能 auto / none ,any/tool 直接報錯;③ 強制型(any/tool)副作用:模型不會 在 tool_use 前輸出自然語言前言——要解釋文字就改用 auto + prompt,或在 schema 裡加 reasoning 欄位。
加碼事實 :切換 tool_choice 會使 message 段的 prompt cache 失效(tool 定義與 system prompt 不受影響)——「每個 request 換 tool_choice 之後成本暴增」的題目答這個。
2.2 平行 tool use 與 tool_result 格式
assistant turn(一次回應)
├─ tool_use #1 (id: A)
├─ tool_use #2 (id: B) ← 同回合多個 = 平行
└─ tool_use #3 (id: C)
↓ 你執行(順序自選:並行/序列)
下一則 user message(一則、且 tool_result 全在文字之前)
├─ tool_result (id: A)
├─ tool_result (id: B, is_error: true ← 沒跑到也要回)
└─ tool_result (id: C)
鐵律一 :所有 tool_result 裝同一則 user message ;一題一則分開回 = 教壞模型以後不 batch (官方 troubleshooting 第一名)
鐵律二 :tool_result 必須在該訊息任何文字之前 ,否則 400 error
用 tool_use_id 對應;沒執行的呼叫回 is_error: true + 簡短說明,模型下回合會重發
鼓勵平行:system prompt 加「independent operations 就同時呼叫」;健康度指標 = 平均每則 assistant 訊息的 tool calls 數 > 1.0
2.3 依賴工具的順序編排
官方鐵律原句:"if some tool calls depend on previous calls... do NOT call these tools in parallel... Never use placeholders or guess missing parameters in tool calls."
機制靠 agentic loop 天然實現:step N 的 tool_result 回到 context → 才生得出 step N+1 的正確參數(先 get_customer → 才 process_refund)
降低「依賴呼叫被誤 batch」:system prompt 加 "Only batch tool calls that are independent of each other."
要「保證叫工具 + 參數合 schema」→ tool_choice: any + tool 定義 strict: true
工具失敗時別讓 agent 亂 retry:結構化錯誤設計(isError/錯誤分類/可否重試)→ 詳見 模組 5 §5.5
辨識訊號 :log 裡下游工具的參數是編出來的 / placeholder (order_id: "TBD")→ 依賴呼叫被錯誤平行化。正解永遠是「序列化依賴呼叫」,不是加 orchestration layer、不是 retry。
2.4 結構化輸出 — 方法比較表(那條 0% 就是這張表)
方法 保證強度 機制 用在
Structured Outputs (output_config + JSON schema)確定性 (constrained decoding,語法永遠合法)解碼層約束 抽取/分類的「回應本體」
Strict tool use (strict: true)保證 tool input 合 schema 同上 「動作參數」(建單、退款)
Tool use + JSON schema (經典法)強(schema 約束 tool_use block) 逼輸出走 tool call exam guide 語境的標準答案
Prompt-based(「請輸出 JSON」) 無保證 純指令 低關鍵度
Prefill(預填 {) 無正式保證 assistant 續寫 舊模型的遺留技巧
Prefill 機制 :messages 最後放 assistant turn 開頭文字、模型續寫(跳前言/逼 JSON/角色維持)。限制:歷史上與 extended thinking 不相容;Claude 4.6 起 ,最後一則 assistant turn 的 prefill 不再支援(400) ——僅限最後一則,歷史中段的 assistant 訊息不受影響;官方遷移路徑 = Structured Outputs
Schema 消語法 錯不消語意 錯(line items 加總 ≠ total 還是要 validation)
Schema 設計兩招(防捏造):source 可能沒有的欄位 optional/nullable ;會演化的類別 enum + "other" + detail 欄
Truncation 處理(stop_reason: "max_tokens")
第一步 :輸出真的比上限長 → 官方第一線建議是合理調高 max_tokens 重試 。
任務大到調不動 (整個 PR review 要一次輸出)→ 拆小 scope 分次呼叫 (per-file / per-section),程式端 merge 各次的資料結構 ——這是考綱正解。
反模式 :「一直加 max_tokens 直到不再失敗」= 無上限軍備競賽——cost/latency 齊飛,且超大單次輸出的品質本身會退化。
2.5 Tool 分配 — Least Privilege
Tool 太多直接降可靠度 (18 個 vs 4–5 個)——每個 agent/subagent 只給角色所需
拿到超出專長工具的 agent 容易誤用(summarizer 亂按 refund)→ scoped access 是結構性修法,prompt「請只用你該用的」不是
高頻小需求給窄 scope 專用工具 (synthesis 要查單一數據 → 給一支 verify_fact),複雜需求仍走 coordinator——不要全開權限、也不要全都繞 coordinator(round-trip 爆炸)
討論題(讀書會 session 用)
tool_choice 四個值 + thinking 相容性,先默背一遍。然後:「必須回結構化 triage 但不限定哪個工具」用哪個值?
為什麼 tool_result 分開多則訊息回,會讓模型「以後不 batch」?從模型視角解釋。
「保證輸出合 schema」有三個不同層的機制(回應本體/工具參數/經典 tool use)——各自的參數名和適用場景?
Prefill 是什麼、為什麼被淘汰、考題問「最可靠」時它為什麼永遠不是答案?
挑一個你們內部系統想像做成 MCP server:哪些操作該給哪個 agent、哪些絕不給?用 least privilege 講一遍。