燒 CPU 比燒 GPU 省——Programmatic Tool Calling 如何改變 AI Agent 的經濟學

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
2
3
4
5
傳統 Tool Use 的資料流:

User Query → LLM 生成 JSON → Tool 執行 → [海量原始資料] → Context Window → LLM 推理
↑ ↑
全部進入 全部燒 GPU

你在 Linux 下要排序一千萬行資料,會直接下 sort 指令,還是把一千萬行貼給 Claude 處理?答案不言自明。但傳統的 Tool Use 架構,本質上就是在做後者。

Programmatic Tool Calling:讓 LLM 寫程式而不是寫 JSON

Anthropic 的解法很工程師:既然 LLM 最擅長寫程式,為什麼只讓它寫 JSON?

Programmatic Tool Calling 的架構翻轉了資料流。LLM 不再逐一生成 JSON 工具呼叫,而是直接寫出一段 Python 腳本,在沙盒容器中執行。腳本內部呼叫工具、處理資料、過濾雜訊,最後只把 print() 輸出的精華結果送回 Context Window。

1
2
3
4
5
6
7
8
9
Programmatic Tool Calling 的資料流:

User Query → LLM 寫 Python → 沙盒執行 → Tool 呼叫(在沙盒內)

CPU 過濾/排序/聚合

print(精華結果)

Context Window → LLM 推理

關鍵差異:Tool results 不進入 LLM 的 Context Window。 只有最終的 stdout 才會被 LLM 看到。

技術實作細節

API 層面的實作意外地簡潔。開發者只需要做兩件事:

1. 啟用 code_execution 工具:

1
2
3
4
{
"type": "code_execution_20260120",
"name": "code_execution"
}

2. 在工具定義中加上 allowed_callers

1
2
3
4
5
6
{
"name": "query_database",
"description": "Execute a SQL query. Returns JSON array.",
"input_schema": { ... },
"allowed_callers": ["code_execution_20260120"]
}

設定完成後,LLM 就會自動決定是否要用程式化的方式呼叫工具。當它判斷需要處理大量資料或串聯多個工具時,它會寫出類似這樣的程式碼:

1
2
3
4
5
6
7
8
regions = ["West", "East", "Central", "North", "South"]
results = {}
for region in regions:
data = await query_database(f"SELECT SUM(revenue) FROM sales WHERE region='{region}'")
results[region] = data[0]["revenue"]

top = max(results.items(), key=lambda x: x[1])
print(f"最高營收地區:{top[0]},金額 ${top[1]:,}")

這段程式碼在沙盒中執行。五次資料庫查詢的結果都在沙盒內被 CPU 處理完畢,LLM 只看到最後一行 print() 的輸出。

沙盒容器的生命週期

  • 每個 session 建立一個容器,閒置約 4.5 分鐘後過期
  • 容器 ID 可跨請求重用,維持狀態
  • 工具呼叫時容器暫停,等待外部回傳結果後繼續執行
  • 如果工具回應超時,Claude 的程式碼會收到 TimeoutError

回應格式中的 caller 欄位

每個 tool_use block 都帶有 caller 欄位,明確標示這次呼叫是傳統的 direct 還是程式化的 code_execution

1
2
3
4
5
6
7
8
{
"type": "tool_use",
"name": "query_database",
"caller": {
"type": "code_execution_20260120",
"tool_id": "srvtoolu_abc123"
}
}

這讓 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 的工具使用歷史,我們經歷了幾個階段:

  1. 純文字解析時代:LLM 吐出特定格式的文字,外部程式用 regex 解析
  2. JSON 標準化時代:OpenAI 的 Function Calling 確立了 JSON 作為工具呼叫的標準格式
  3. MCP 協定時代:Anthropic 推出 Model Context Protocol,統一了工具的發現和呼叫介面
  4. 程式化呼叫時代:現在——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


參考資料:

📡 想看更多?加入 AI 印鈔指南 頻道,每日推送 AI 技術前沿 + 加密貨幣投資情報

留言

載入留言中...

留下你的想法