# 策展 · X (Twitter) 🔥

> 📖 本站完整內容索引（documentation index）：[llms.txt](/llms.txt)

> 作者：Gabriel Chua (@gabrielchua) · 平台：X (Twitter) · 日期：2026-07-14

> 原始來源：https://x.com/gabrielchua/status/2076694715777642523

## 中文摘要

# Agent 工具：呼叫、搜尋與程式碼

隨著 GPT-5.6 的發布，我們推出了「程式化工具呼叫」（Programmatic Tool Calling），現在正是回顧 Agent 工具以及如何在工具使用量增加時保持模型專注度的好時機。

試想你詢問客服 Agent 為什麼訂單 A-104 延遲，它可能會讀取訂單資訊、致電物流商，並解釋延遲原因。這段互動背後隱藏著一個迴圈：模型請求執行動作，執行環境（runtime）執行該動作，最後回傳結果。內建工具、MCP、skill、工具搜尋（Tool Search）以及程式化工具呼叫，改變了模型所見的內容以及回傳的資訊。

## 1. 工具呼叫入門：模型請求，應用程式執行

使用客戶端擁有的函式時，模型並不會直接執行你的程式碼。它會回傳工具名稱、JSON 參數以及呼叫 ID（call ID）。你的應用程式會檢查該請求、執行函式，並以相同的 ID 回傳 `function_call_output`。

![此圖展示了「客戶端擁有的函式迴圈」（Client-Owned Function Loop）運作流程示意圖。](https://pub-75d4fe1e4e80421b9ecb1245a7ae0d1a.r2.dev/curated/8534f85414a6cc8d.jpg)

<details class="chart-data"><summary>展開畫面重點</summary><div class="me-note">該圖表以像素風格呈現，描述了應用程式（APPLICATION）與模型（MODEL）之間的互動循環，包含五個步驟：
1. PROMPT + TOOL SCHEMA：應用程式將提示詞與工具架構發送給模型。
2. TOOL REQUEST：模型向應用程式發出工具請求。
3. VALIDATE + EXECUTE：應用程式進行驗證並執行相關操作。
4. TOOL OUTPUT：應用程式將工具執行結果輸出回模型。
5. FINAL RESPONSE：模型根據輸出產生最終回應。</div></details>

在 Python 中，回傳 `function_call_output` 會將控制權交還給模型：

```python
import json
from openai import OpenAI

client = OpenAI()

def get_order(order_id): return {"order_id": order_id, "promised_date": "2026-07-13"}

order_tool = {
    "type": "function", "name": "get_order", "strict": True,
    "description": "Return the promised delivery date for an order.",
    "parameters": {
        "type": "object",
        "properties": {"order_id": {"type": "string"}},
        "required": ["order_id"], "additionalProperties": False,
    },
    "output_schema": {
        "type": "object",
        "properties": {
            "order_id": {"type": "string"}, "promised_date": {"type": "string"},
        },
        "required": ["order_id", "promised_date"], "additionalProperties": False,
    },
}

first = client.responses.create(
    model="gpt-5.6", tools=[order_tool], input="Why is order A-104 late?",
    tool_choice={"type": "function", "name": "get_order"},
)
call = next(item for item in first.output if item.type == "function_call")
result = get_order(**json.loads(call.arguments))

final = client.responses.create(
    model="gpt-5.6",
    tools=[order_tool],
    input=[*first.output, {
        "type": "function_call_output",
        "call_id": call.call_id,
        "output": json.dumps(result),
    }],
)
print(final.output_text)
```

harness 會重複此迴圈，直到模型回傳最終訊息為止。嚴格的 schema（Strict schemas）能確保參數格式正確；而執行者（executor）仍會負責檢查權限。

## 2. 工具執行可以在不同地方進行

內建工具（包含網頁搜尋、檔案搜尋以及託管 shell）可以在 OpenAI 的基礎架構中執行。遠端的 MCP 伺服器則能遠端公開並執行工具；Responses 支援這些伺服器以及 OpenAI 維護的連接器，並預設在分享資料前要求使用者核准。

一個 skill 會將指令與檔案打包在一起。將其附加到託管 shell 後，模型便能遵循其程序或執行其中的腳本。模型會先看到該 skill 的名稱、描述與路徑，選定後再讀取 `SKILL.md`。

```python
carrier_mcp = {
    "type": "mcp",
    "server_label": "carrier",
    "server_url": "https://example.com/mcp",
    "allowed_tools": ["track_package"],
    "require_approval": "always",
}
incident_shell = {
    "type": "shell",
    "environment": {
        "type": "container_auto",
        "skills": [{"type": "skill_reference", "skill_id": "skill_..."}],
    },
}

response = client.responses.create(
    model="gpt-5.6",
    tools=[carrier_mcp, incident_shell],
    input="Investigate why order A-104 is late using the incident skill.",
)
```

harness 統一了這些介面：MCP 公開遠端工具，skill 提供程序與檔案，而 harness 則控制呼叫執行的位置。

## 3. 工具搜尋：當 context 成為限制時

每個可見的工具定義都會佔用 context。名稱、描述與 schema 都會消耗 input token，相似的工具會變得難以區分，而龐大的 MCP 目錄則會變成一個巨大的 prompt。

工具搜尋讓相容的 GPT-5.4 或更高版本模型，僅在需要時才載入延遲定義（deferred definitions）：

```python
shipping = {
    "type": "namespace", "name": "shipping",
    "description": "Order tracking and delivery tools.",
    "tools": [{
        "type": "function", "name": "get_delivery_eta",
        "description": "Return the ETA for an order.",
        "defer_loading": True,
        "parameters": {
            "type": "object", "required": ["order_id"],
            "properties": {"order_id": {"type": "string"}},
            "additionalProperties": False,
        },
    }],
}

response = client.responses.create(
    model="gpt-5.6",
    input="When will order A-104 arrive?",
    tools=[shipping, {"type": "tool_search"}],
)
```

託管的工具搜尋會從請求中宣告的工具進行選擇；客戶端執行的搜尋則可以回傳針對當前租戶（tenant）或專案的工具。搜尋會增加一個步驟，因此小型目錄可能獲益有限。延遲載入的函式仍會公開其名稱與描述，而 namespace 或 MCP 伺服器則可以從一個簡短的描述開始。已載入的工具會被附加在後，以保留快取前綴。skill 會延遲載入指令與檔案；而工具搜尋則會延遲載入可呼叫的 schema。

## 4. 程式化工具呼叫：用於可預測的多工具作業

直接呼叫會將每個結果回傳給模型。當結果會改變下一個決策時，這很有用；但簡單的合併（join）、篩選（filter）與平行查詢（parallel lookup）可能會用程式碼就能簡化的資料填滿 context。

程式化工具呼叫讓 GPT-5.6 能夠撰寫在乾淨、隔離的 V8 環境中執行的 JavaScript。V8 在 Chrome 內部執行 JavaScript，但這並非瀏覽器或 Node.js。它支援頂層 await、迴圈、條件判斷與平行呼叫，但不支援套件安裝、直接網路存取、通用檔案系統、子程序、console 或持久化狀態。

![此圖表比較了「DIRECT」與「PROGRAMMATIC」兩種工具呼叫方式的流程差異。](https://pub-75d4fe1e4e80421b9ecb1245a7ae0d1a.r2.dev/curated/ea8ce9ee926336cc.jpg)

<details class="chart-data"><summary>展開畫面重點</summary><div class="me-note">圖片展示了兩種程式化工具呼叫（PROGRAMMATIC TOOL CALLING）的架構比較：

1. **DIRECT（直接呼叫）**：顯示一個線性流程，模型（MODEL）依序呼叫工具 1、工具 2 與工具 3，每次呼叫後皆需回到模型進行處理。
2. **PROGRAMMATIC（程式化呼叫）**：顯示一個更高效的流程，模型將請求發送至「ISOLATED V8」環境，該環境可同時處理工具 1、工具 2 與工具 3，並與「YOUR APP」進行雙向互動，最後將結果整合為「COMPACT RESULT」回傳給模型。

畫面中出現的文字標籤：
- PROGRAMMATIC TOOL CALLING
- DIRECT
- MODEL
- TOOL 1
- TOOL 2
- TOOL 3
- PROGRAMMATIC
- ISOLATED V8
- COMPACT RESULT
- YOUR APP</div></details>

當程式執行到客戶端擁有的函式時，它會暫停，直到你的應用程式執行該呼叫；回傳其 `call_id` 與呼叫者（caller）後，程式便會恢復執行。`carrier_mcp` 也可以為了等待核准而暫停，而 `output_schema` 會告訴 JavaScript 它可以檢查哪些欄位。

```python
for tool in (order_tool, carrier_mcp):
    tool["allowed_callers"] = ["programmatic"]

response = client.responses.create(
    model="gpt-5.6",
    tools=[
        order_tool,
        carrier_mcp,
        {"type": "programmatic_tool_calling"},
    ],
    input="Compare order A-104 with carrier status and return delay evidence.",
)
```

程式可以呼叫函式與自訂工具、MCP、`apply_patch`、shell 與程式碼解釋器，但不能呼叫網頁搜尋或檔案搜尋。頂層的工具搜尋必須在程式開始前載入延遲工具；執行中的程式無法搜尋工具。

當下一步需要模型判斷、核准、引用或產生副作用時，請保持直接呼叫。當明確的規則能讓程式碼回傳較小的結果且不遺失證據時，請使用程式。託管執行改變了工作執行的位置，工具搜尋改變了哪些定義進入 context，而程式化呼叫則改變了回傳的結果。當評估顯示在保持正確性的同時，能改善 token 使用量、延遲或成本時，請將它們結合使用。

## 加碼：將長工具迴圈保持在同一個連線中

如果 Agent 在模型與客戶端擁有的工具之間反覆切換，Responses 的 WebSocket 模式可以減少持續呼叫的開銷。該 socket 將你的 harness 連接到 Responses；它不會讓工具執行得更快。它接受與函式、MCP、工具搜尋與程式化工具呼叫相同的 `response.create` 欄位，儘管文件並未對每種組合進行基準測試。OpenAI 在 20 次或更多呼叫的部署中觀察到執行速度提升了高達 40%，因此請務必測量你的工作流程。

## 在你的 Agent 上試試看

將這篇文章截圖（Appshot），在 Codex 中開啟你的 Agent 專案並貼上：

> 使用這篇文章與當前的程式庫來升級此 Agent 的工具路徑。將大型或不常用的工具分組，並啟用工具搜尋來延遲載入它們。找出可以透過程式化工具呼叫進行平行呼叫並回傳精簡結果的邊界階段。將語意決策、核准、引用與副作用保留為直接呼叫。在變更生產環境路由之前，請比較兩條路徑在正確性、證據覆蓋率、工具成功率、token 使用量、延遲、重試次數與成本方面的表現。

## 標籤

Agent, MCP, Skills, 功能更新, OpenAI
