Sonnet 4.6 發佈的那天,所有人的目光都被 Gemini 3.1 Pro 搶走了。但有一個功能安靜地從 Beta 畢業、正式 GA——Programmatic Tool Calling(程式化工具呼叫)。
這不是一個華麗的新功能。它沒有讓模型變聰明,沒有擴大 context window,也沒有新的多模態能力。它做的事情更根本:把不該讓 GPU 做的工作,還給 CPU。
傳統 Tool Use 的經濟學困境
要理解這個突破,得先看清現行 Tool Use 的成本結構。
當你的 AI Agent 需要搜尋網頁,流程是這樣的:LLM 生成一段 JSON(工具名稱、參數),外部 Orchestrator 接收後執行工具,把結果全部塞回 Context Window。搜尋 10 個網頁?10 份原始 HTML 全部灌進去。LLM 必須用 GPU 算力去「閱讀」這些資料,才能從中提取你要的答案。
問題在於:排序、過濾、字串比對、資料聚合——這些是 O(n log n) 或 O(n) 的 CPU 操作。讓 LLM 用 GPU 做這些事,就像用顯微鏡看路牌:精度過剩,成本爆表。
1 | 傳統 Tool Use 的資料流: |
你在 Linux 下要排序一千萬行資料,會直接下 sort 指令,還是把一千萬行貼給 Claude 處理?答案不言自明。但傳統的 Tool Use 架構,本質上就是在做後者。
Programmatic Tool Calling:讓 LLM 寫程式而不是寫 JSON
Anthropic 的解法很工程師:既然 LLM 最擅長寫程式,為什麼只讓它寫 JSON?
Programmatic Tool Calling 的架構翻轉了資料流。LLM 不再逐一生成 JSON 工具呼叫,而是直接寫出一段 Python 腳本,在沙盒容器中執行。腳本內部呼叫工具、處理資料、過濾雜訊,最後只把 print() 輸出的精華結果送回 Context Window。
1 | Programmatic Tool Calling 的資料流: |
關鍵差異:Tool results 不進入 LLM 的 Context Window。 只有最終的 stdout 才會被 LLM 看到。
技術實作細節
API 層面的實作意外地簡潔。開發者只需要做兩件事:
1. 啟用 code_execution 工具:
1 | { |
2. 在工具定義中加上 allowed_callers:
1 | { |
設定完成後,LLM 就會自動決定是否要用程式化的方式呼叫工具。當它判斷需要處理大量資料或串聯多個工具時,它會寫出類似這樣的程式碼:
1 | regions = ["West", "East", "Central", "North", "South"] |
這段程式碼在沙盒中執行。五次資料庫查詢的結果都在沙盒內被 CPU 處理完畢,LLM 只看到最後一行 print() 的輸出。
沙盒容器的生命週期
- 每個 session 建立一個容器,閒置約 4.5 分鐘後過期
- 容器 ID 可跨請求重用,維持狀態
- 工具呼叫時容器暫停,等待外部回傳結果後繼續執行
- 如果工具回應超時,Claude 的程式碼會收到
TimeoutError
回應格式中的 caller 欄位
每個 tool_use block 都帶有 caller 欄位,明確標示這次呼叫是傳統的 direct 還是程式化的 code_execution:
1 | { |
這讓 Orchestrator 可以區分處理,也方便除錯和成本追蹤。
實測數據:省了多少?
Anthropic 公開的基準測試結果:
| 指標 | 改善幅度 | 說明 |
|---|---|---|
| BrowserComp 準確率 | 33% → 46.6% | 網頁隱藏資訊搜尋測試 |
| Input Token | -24% | 雜訊資料在沙盒階段被 CPU 過濾 |
| Multi-tool Token | -37% | 複雜研究任務,平均 43,588 → 27,297 tokens |
| GIA 基準 | 46.5% → 51.2% | 內部知識檢索測試 |
| 模型推理次數 | -19+ passes | 20+ 工具呼叫合併為一次程式碼區塊 |
Opus 4.6 在同一基準上的表現更強:BrowserComp 從 45% 升至 61%。但 Anthropic 也坦承,Opus 有時會寫出「非常複雜的程式碼」,導致生成階段的 output token 反而增加。
這裡有一個重要的經濟學直覺:就算 output token 增加了,整體成本依然下降,因為你省下的是大量 input token——而 input token 的定價通常是 output token 的 1/3 到 1/5。用少量的 output(寫程式碼)換取大量的 input 節省(不用把原始資料灌進 context),這筆帳怎麼算都划算。
適用與不適用的場景
Anthropic 的官方文件很務實地列出了使用建議:
適合程式化呼叫的場景:
- 大資料集處理,只需要聚合結果或摘要
- 三步以上的多工具串聯工作流
- 需要對結果進行過濾、排序、轉換
- 中間資料不需要影響 LLM 推理
- 批量操作(例如檢查 50 個 endpoint 的健康狀態)
不適合的場景:
- 單一工具呼叫
- 需要即時用戶回饋的操作
- 執行速度極快、程式碼執行的 overhead 反而更高
目前的限制
- 不支援
strict: true的結構化輸出 - 不能用
tool_choice強制程式化呼叫 - MCP Connector 提供的工具暫時不能被程式化呼叫
- 不被 Zero Data Retention (ZDR) 覆蓋
對我們專案的啟示
我在維護一個 Telegram Bot + AI Agent 系統,裡面有大量的 Tool Use 場景。看到 Programmatic Tool Calling 的設計,幾個想法立刻跳出來:
1. Comment Monitor 的搜尋過濾
我們的部落格留言監控 Agent 每小時查詢一次最新留言,然後把所有未回覆的留言丟給 Haiku 分析。如果留言量大,這些原始留言內容全部進入 Context Window。用程式化呼叫的思維,應該在呼叫 API 之前就讓程式碼過濾掉垃圾留言(重複內容、純符號、過短的留言),只把真正需要 AI 判斷的留言送進去。
2. Multi-Agent Pipeline 的中間結果
我們的 DAG Pipeline 引擎讓多個 Agent 串聯執行任務。目前每個 Agent 的完整輸出都會被送進下一個 Agent 的 context。如果引入「CPU 預處理層」——在 Agent 之間加一個 Python 過濾步驟,只傳遞摘要而不是原始報告——Token 消耗可以大幅降低。
3. Deep Researcher 的網頁擷取
Deep Researcher Agent 經常搜尋多個網頁然後彙整。這正是 Programmatic Tool Calling 最閃亮的場景:讓程式碼去爬 10 個網頁,在沙盒內用 Python 提取關鍵段落,最後只把精華送回 LLM。
但也有不適用的地方
我們的日常對話、問候、反思系統——這些需要 LLM 全程參與語意推理的任務,就不適合用程式化呼叫。不是所有工作都能拆成「CPU 做的」和「GPU 做的」,有些任務天生就是語意密集型的。
從 JSON 到 Code:一場靜悄悄的典範轉移
回顧 AI Agent 的工具使用歷史,我們經歷了幾個階段:
- 純文字解析時代:LLM 吐出特定格式的文字,外部程式用 regex 解析
- JSON 標準化時代:OpenAI 的 Function Calling 確立了 JSON 作為工具呼叫的標準格式
- MCP 協定時代:Anthropic 推出 Model Context Protocol,統一了工具的發現和呼叫介面
- 程式化呼叫時代:現在——LLM 直接寫程式來編排工具,JSON 退居為內部通訊格式
每一次轉移都在回答同一個問題:如何讓 LLM 更有效率地與外部世界互動?
Programmatic Tool Calling 的深層意義不只是省 Token。它重新定義了 LLM 和 CPU 的分工:
CPU 負責資料的苦力活(爬取、過濾、排序、聚合),GPU 專注語意推理的精華決策。
這像極了作業系統的設計哲學——kernel 處理 I/O 和排程,application 處理業務邏輯。Anthropic 給了 LLM 一個「kernel」(沙盒容器),讓它可以把 I/O 密集的工作交給 CPU,自己只處理需要「思考」的部分。
結語
燒 CPU 真的比燒 GPU 省。不是因為 CPU 便宜(雖然確實便宜),而是因為正確的工作交給正確的硬體本來就是工程的第一原則。
Programmatic Tool Calling 不是什麼革命性的新發明——它就是「讓程式碼做程式碼該做的事」。但在 AI 開發的狂熱中,我們太容易忘記這個最基本的道理。
下次你發現自己把一萬行資料丟進 Context Window 讓 LLM 去「閱讀」時,想想:這真的需要語意推理嗎?還是一行 sort 就能搞定?
一見生財,寫於 2026-02-22
參考資料:
載入留言中...