🎁 新用戶 免費註冊,送 10 次呼叫,最高 $1,免綁卡。
Agent 迴圈中的 GLM 5.2 工具呼叫:「OpenAI 相容」沒說清楚的事

Agent 迴圈中的 GLM 5.2 工具呼叫:「OpenAI 相容」沒說清楚的事

目錄
  1. 同一輪,三種做法
  2. 文字會跟著工具呼叫一起回來
  3. 它會把推理過程直接送出來
  4. GLM 5.2 工具呼叫輪次的成本
  5. 何時該使用 GLM 5.2,以及如何正確使用
  6. 免責聲明
  7. 資料來源

把既有的 OpenAI 風格 agent 迴圈接到 GLM 5.2,大多數功能都能直接運作:送出 tools、收到 tool_calls、執行工具,再把結果送回去。但接著會出現 SDK 範例從未展示的情況。assistant 會在工具呼叫的同一輪回傳一段文字:

{
  "choices": [{
    "finish_reason": "tool_calls",
    "message": {
      "role": "assistant",
      "content": "I'll look up both pieces of information for you at the same time!",
      "tool_calls": [
        {"id": "call_…", "type": "function",
         "function": {"name": "get_weather", "arguments": "{\"city\":\"Paris\"}"}},
        {"id": "call_…", "type": "function",
         "function": {"name": "get_time", "arguments": "{\"city\":\"Tokyo\"}"}}
      ]
    }
  }]
}

TL;DR

  • GLM 5.2 每個暖快取工具呼叫輪次的成本為 $0.0009,gpt-5.5 為 $0.0042,claude-opus-4-8 則為 $0.0051(測量日期:2026-06-30)。
  • GLM 5.2 暖快取輪次的延遲中位數為 6.6s,gpt-5.5 為 1.9s,opus-4-8 為 3.1s:成本較低,但速度也較慢。
  • GLM 5.2 會在 tool_calls 的同一輪回傳可見文字,同時維持 finish_reason: "tool_calls";OpenAI 的契約則規定此時 content 為 null。
  • GLM 5.2 每個暖快取輪次約有 27 個推理 token;在同一項任務中,gpt-5.5 與 claude-opus-4-8 都是 0。

目前主要有兩套慣例,需要同時掌握。OpenAI 的做法是送出函式 schema、取得 tool_calls,再針對每個呼叫回傳一則 tool 訊息,並以 tool_call_id 對應:

resp = openai.chat.completions.create(model="…", tools=tools, tool_choice="auto", messages=messages)
# assistant.tool_calls → [{"id": "call_…", "function": {"name": "get_weather", "arguments": "{\"city\":\"Paris\"}"}}]
messages.append(resp.choices[0].message)
messages.append({"role": "tool", "tool_call_id": "call_…", "content": "18C, clear"})

Anthropic 的格式不同:工具使用 input_schema,模型產生 tool_use 區塊,然後由你回傳 tool_result 區塊:

resp = anthropic.messages.create(model="…", tools=tools, messages=messages)
# resp.content → [{"type": "tool_use", "id": "toolu_…", "name": "get_weather", "input": {"city": "Paris"}}]
messages.append({"role": "assistant", "content": resp.content})
messages.append({"role": "user", "content": [
    {"type": "tool_result", "tool_use_id": "toolu_…", "content": "18C, clear"}]})

GLM 5.2 採用 OpenAI 這套格式。

依照 OpenAI 的契約,當 finish_reasontool_calls 時,message.content 會是 null。許多 agent 迴圈都依賴這項特性:用「content 或工具呼叫」分支處理、把 content 當成最終答案寫入 log,或直接斷言它是空值。GLM 會同時回傳兩者,因此最先出問題的就是這項假設。

本文行為來自對 glm-5.2 的實際工具呼叫請求,並以執行相同任務的 gpt-5.5claude-opus-4-8 作為比較基準。簡單來說,GLM 5.2 使用 OpenAI API 介面,但在幾個面向上更像 Claude,而不是 GPT。原本針對 OpenAI 設計的迴圈反而容易出錯。

同一輪,三種做法

相同 prompt、相同的兩個工具,分別交給三個模型:

GLM (glm-5.2)OpenAI (gpt-5.5)Anthropic (claude-opus-4-8)
API 介面OpenAI chat-completionsOpenAI chat-completionsAnthropic messages
工具呼叫輪次中的文字content 開場文字(非 null)contentnulltool_use 前有一個 text 區塊
該輪次的推理公開:reasoning_content + reasoning_tokens隱藏;只有 usage 中的 reasoning_tokens僅在啟用時以 thinking 區塊呈現
平行工具呼叫支援,並附有 index支援支援,以多個 tool_use 區塊呈現
完成訊號finish_reason: "tool_calls"finish_reason: "tool_calls"stop_reason: "tool_use"
工具呼叫 ID 前綴call_…call_…toolu_…

真正容易讓迴圈出錯的是兩列:工具呼叫輪次中的文字,以及該輪次出現的推理內容。其餘部分都很單純。

文字會跟著工具呼叫一起回來

GLM 5.2 經常在回傳 tool_calls 時,一併透過 assistant 的 content 回傳簡短開場文字,同時將 finish_reason 設為 tool_calls。這不是錯誤,也不是偶發行為。

以下是三個模型在同一輪的回應,只保留彼此不同的部分:

// OpenAI gpt-5.5: content is null on a tool-call turn
"message": { "content": null,
             "tool_calls": [ {/* get_weather */}, {/* get_time */} ] }

// GLM glm-5.2: content carries a preamble
"message": { "content": "I'll look up both pieces of information for you at the same time!",
             "tool_calls": [ {/* get_weather */}, {/* get_time */} ] }

// Anthropic claude-opus-4-8: a text block sits before the tool_use blocks
"content": [ { "type": "text", "text": "I'll get both pieces of information for you." },
             { "type": "tool_use", /* get_weather */ },
             { "type": "tool_use", /* get_time */ } ]

OpenAI 讓 content 保持 null;GLM 會填入文字;Anthropic 則一直都會在這裡放置 text 區塊。GLM 使用 OpenAI 的傳輸格式,卻沿用 Anthropic 在執行動作前先加一段說明的習慣。因此,按照 OpenAI 行為撰寫的迴圈反而會措手不及。修正方式不複雜,但必須明確處理。不要再假設工具呼叫輪次沒有文字內容:

resp = client.chat.completions.create(model="glm-5.2", messages=msgs, tools=tools)
msg = resp.choices[0].message

# GLM may return assistant text in the same turn as the tool calls.
if msg.content:
    log.debug("preamble: %s", msg.content)   # keep or drop, but don't assume it's empty

msgs.append(msg)
for call in msg.tool_calls:
    result = dispatch(call.function.name, json.loads(call.function.arguments))
    msgs.append({"role": "tool", "tool_call_id": call.id, "content": result})

如果迴圈會把 content 當作 assistant 回覆顯示給使用者,那麼每次工具呼叫前都會多出一句「我來查一下」。你可以決定要保留還是捨棄。重點是這必須由你決定,不能再靠模型不回傳文字來替你決定。

它會把推理過程直接送出來

GLM 5.2 是推理模型,使用工具時也不會停止推理。工具呼叫輪次會夾帶推理內容,而且 GLM 5.2 會以文字形式公開。非串流回應中的 token 計數清楚顯示這一點:

"usage": {
  "prompt_tokens": 224,
  "completion_tokens": 68,
  "completion_tokens_details": { "reasoning_tokens": 30 },
  "total_tokens": 292
}

這個請求的可見輸出只有兩個簡短的函式呼叫,但將近一半的 completion 都用在推理上。三個模型在這方面各不相同。GLM 5.2 會透過 reasoning_content 提供推理文字,並附上 token 數量。OpenAI 會針對 usage 中的 reasoning_tokens 計費,但不會公開文字內容。Anthropic 只有在啟用 extended thinking 時,才會透過 thinking 區塊顯示。預設情況下,GLM 5.2 公開的推理資訊最多。

這會帶來兩項影響。第一是成本:工具呼叫輪次中的推理 token 也會計費,而 agent 迴圈通常有很多輪。reasoning effort 是調整這項成本的主要控制項,詳情請參閱 GLM 5.2:Reasoning Effort 才是成本調節鈕。每一輪都要計入推理 token,不要只計算最終答案。

第二是串流順序。使用串流請求時,GLM 會先送出推理內容,再送開場文字,最後才是工具呼叫:

reasoning_content  (many deltas)
content            (a few deltas)
tool_calls         (id + name, then arguments)

針對標準 OpenAI chat completions 寫的 parser 不認得 reasoning_content 欄位,通常會直接忽略最前面的資料。多數情況下不成問題。但如果 UI 的「思考中……」狀態是由第一個 content delta 觸發,就會出錯。線上最先抵達的是推理內容,而不是 content,因此指示器永遠不會切換。

GLM 5.2 工具呼叫輪次的成本

行為只說明了一半,另一半是費用,而 agent 迴圈會重複執行相同輪次。固定前綴包含約 2,000 個 token 的 system prompt 與工具定義,並在每次呼叫時變更 user 訊息。以下是十個暖快取輪次的測量結果:

每個暖快取工具呼叫輪次GLM glm-5.2OpenAI gpt-5.5Anthropic claude-opus-4-8
成本$0.0009$0.0042$0.0051
延遲(中位數)6.6s1.9s3.1s
Prompt 快取比例≈96%≈81%≈97%
推理 token≈2700
冷快取 → 暖快取成本3.4×2.8×4.9×

GLM 5.2 成本最低:每個暖快取輪次約比 GPT-5.5 便宜 4.5×,比 Opus 便宜 5.4×。但它也是最慢的模型,延遲約為另外兩者的兩倍到三倍半,因為它每一輪都會消耗推理 token,而另外兩個模型在這項任務中都沒有。這就是取捨:GLM 用延遲換取低成本,而 reasoning effort 是調整兩者的控制項。

要讓這些模型在迴圈中維持合理成本,關鍵是快取。system prompt 與工具定義占每個 prompt 的大部分,而且每輪完全相同。前綴進入快取後,每輪成本可降低 2.8× 到 4.9×。能否取得這項效果取決於兩件事。GLM 與 OpenAI 會自動快取前綴;Anthropic 只會快取以 cache_control 標記的內容。此外,GLM 的快取需要多一點時間才會暖起來,因此三步驟任務可能全程支付完整費用,但三十步驟任務則能使用快取。運作方式請參閱開放權重 LLM 的快取機制

何時該使用 GLM 5.2,以及如何正確使用

綜合來看,GLM 5.2 是表格中成本最低、速度最慢的模型,而且每一輪都會推理。這些特性決定了它適合的使用情境。

適合的場景是長時間、多步驟的 agent 迴圈,主要考量為成本,且每輪多等幾秒可以接受。例如背景 coding agent、CI 與批次自動化,以及無人值守的工作。讓它變慢的推理能力,也讓它能處理真正的程式開發與規劃工作,而不只適合簡單路由。暖機之後,快取會進一步放大優勢:三十步驟任務可以攤平前綴成本並以低成本執行;三步驟任務卻可能全程支付完整費用,還白白承受延遲。因此,長時間任務可以選擇 GLM 5.2;對於互動式、單次呼叫等能明顯感受到每輪六秒延遲的情境,則保留速度更快的模型。

要把 GLM 5.2 跑好,只需養成五個習慣,而且不必離開 OpenAI API 介面:

  • 工具呼叫輪次可能同時帶有 content,不要斷言它一定為空。
  • 預期線上資料會出現 reasoning_contentusage 中也會有 reasoning_tokens;兩者都要納入預算,並使用 reasoning-effort 控制項在品質與成本之間取捨。
  • 在串流模式下,不要用第一個 content delta 觸發 UI 狀態,因為推理內容會先抵達。
  • 原樣回傳 tool_call_id;將它視為不透明值,不要解析或重新產生。
  • 依照 index 累積串流中的 arguments,直到該呼叫結束;不要假設 chunk 數量。

有兩件事不需要額外防範:GLM 與其他模型一樣,會用 index 產生平行工具呼叫,而且往返流程能正常結束。附加 assistant 輪次,再針對每個呼叫附加一則包含結果的 tool 訊息,最後就會以 finish_reason: "stop" 完成。同時也要讓可快取的前綴在各輪之間維持 byte 級一致;system prompt 與工具定義占每個 prompt 的大部分,只有穩定前綴才能在 GLM 快取暖起來後持續降低成本。

這些都不是特殊機制,而是「請求成功」與「agent 迴圈正確運作」之間的差距。在 GLM 上,這個差距主要來自兩個假設:工具呼叫輪次不會有文字,以及工具呼叫時模型不會推理。移除這兩個假設並保持前綴穩定,同一套迴圈就能同時支援 GLM、GPT 與 Claude。在不以延遲為主要最佳化目標的場景中,GLM 只需一小部分成本即可完成工作。

免責聲明

上述成本、延遲與快取數據測量於 2026-06-30,每個模型各執行十個暖快取工具呼叫輪次,使用的模型為 glm-5.2gpt-5.5claude-opus-4-8。成本取自回報的 usage;延遲是實際經過時間的中位數,會隨負載與 reasoning effort 改變。模型行為與價格都會變動,因此這些數字僅供參考。實際採用前,請用自己的流量重新測量。

資料來源

← 返回部落格