簡短回答
Gemini 3 及以上模型(gemini-4-argon、gemini-3.8-flash、gemini-3.1-pro-preview 等)做多輪工具呼叫時,與思維簽名(thoughtSignature)有關的 400 有兩種,處理方式不同:
走 OpenAI 相容格式
/v1/chat/completions 的使用者不用管這件事:簽名由閘道代管,按標準 tool_calls / tool 訊息回傳即可。
兩種報錯怎麼區分
缺失簽名
parts 陣列的第幾個位置。這是原廠對 Gemini 3 系列的硬規則:當前輪的 functionCall part 必須帶回簽名,缺了直接 400,在所有線路上表現一致,重試沒有用。
簽名無效或損壞
為什麼會這樣
開啟工具呼叫後,Gemini 3 系列模型在返回functionCall 的同時,會在同一個 part 裡附一個加密的 thoughtSignature,記錄這一步的推理狀態。下一輪請求時,模型要靠它接上推理鏈,所以原廠要求把它原樣帶回。
缺失:客戶端重建了 part
最常見的原因。自研框架或中間層在拼歷史時只保留了
functionCall 的 name 和 args,把同級的 thoughtSignature 丟了;或者流式接收時逐塊拼裝,沒把簽名塊合進去。缺失:歷史被壓縮或改寫
客戶端對上下文做了裁剪、摘要,或把多個 part 合併成一個,簽名隨之丟失。
無效:會話中途換線路
同一個會話前幾輪由線路 A 處理、後幾輪落到線路 B,B 不認 A 簽出來的串。線路切換可能來自你換了分組或 Key,也可能來自故障自動切換。
無效:會話中途換模型
前幾輪用 gemini-3.8-flash,中途改成 gemini-4-argon 繼續同一個會話,簽名不通用。
並行呼叫時模型只在第一個
functionCall part 上附簽名,後面幾個沒有簽名是正常的,不要自己補。順序呼叫(一輪裡連續多步)每一步都有簽名,每一步都要帶回。修法一:缺失簽名,改客戶端回傳方式
1
把整個模型回覆原樣放回歷史
用官方
google-genai SDK 時直接 contents.append(response.candidates[0].content),不要只取 function_call 欄位。手寫 REST 時,第二輪的 contents 裡模型那一輪要長這樣:thoughtSignature 與 functionCall 是同一個 part 的兩個欄位,不是兩個 part。2
檢查框架和中間層有沒有裁欄位
用 LangChain、自研 Agent 框架、OpenAI 轉 Gemini 的轉換層時,列印第二輪實際發出的請求體,確認
thoughtSignature 還在。報錯裡的 position N 就是 parts[N],直接對著看。3
不要依賴「有的模型能過」
不同模型和線路對缺失簽名的容忍度不同,有的會放過、有的直接 400。同一套程式碼在 gemini-3.8-flash 上一直好好的,換到 gemini-4-argon 就報錯,大機率就是簽名一直沒帶、之前只是被放過了。按官方要求回傳簽名,在所有模型上都穩。
修法二:簽名無效,重發或新開會話
1
原樣重發一次
API易 閘道收到簽名 400 會自動換線路重試,很多時候重發一次就過了,不需要改請求。
2
仍然 400:去掉歷史輪裡的簽名重發
把歷史裡
role: "model" 各輪 part 中的 thoughtSignature 欄位刪掉再發。這會丟掉那幾輪的推理上下文,模型回答品質可能略降,但對話可以繼續。只刪歷史輪的簽名,不要動當前輪。3
或者新開會話
最省事、最確定的辦法。新會話從第一輪起簽名就由同一條線路生成,後續都能認。
4
一個會話只用一個模型、一個 Key
要換模型、換 Key 或換分組,新開會話再換,不要在已有工具呼叫歷史的會話裡切。
走 OpenAI 相容格式不用處理簽名
通過/v1/chat/completions 呼叫 Gemini 時,tool_calls 訊息裡沒有簽名欄位,閘道會在轉換時自動儲存並回填。我們實測 gemini-4-argon 單次呼叫、並行雙呼叫、文本加呼叫三種形態的兩輪對話全部通過,客戶端按 OpenAI 標準寫法回傳 tool_calls 和 tool 訊息即可。
Codex 等預設走
/v1/responses 的客戶端,Gemini 系列暫不支援該端點,請切到 chat 協議。詳見 Gemini 4 Argon 文本生成。常見問題
只有 argon 報這個錯,flash 一直正常,是 argon 的問題嗎?
只有 argon 報這個錯,flash 一直正常,是 argon 的問題嗎?
不是。簽名回傳是原廠對 Gemini 3 全系列的要求,只是部分模型的線路對缺失簽名比較寬鬆。換到校驗嚴格的模型才暴露出來,根因仍是客戶端沒帶簽名。
簽名可以快取後跨會話複用嗎?
簽名可以快取後跨會話複用嗎?
不行。簽名只在生成它的那條線路、那個會話上下文裡有效,複製到別的會話會報 Invalid。
流式呼叫拿到的簽名在哪?
流式呼叫拿到的簽名在哪?
在包含
functionCall 的那個 chunk 的同一個 part 裡。流式拼裝時要把這個欄位連同 functionCall 一起合進最終的模型回覆,再放回歷史。純文本回復的輪次也要帶簽名嗎?
純文本回復的輪次也要帶簽名嗎?
不強制。原廠只對
functionCall part 的簽名做硬校驗,文本輪的簽名缺了不會 400,但帶上有助於保持推理連貫,建議整個回覆原樣回傳。相關文件
Gemini Function Calling 函式呼叫指南
完整的兩輪呼叫示例,含簽名回傳寫法
Gemini 4 Argon 文本生成
多輪工具呼叫注意事項與客戶端接入
Claude 多輪對話報「思考簽名無效」怎麼辦?
Claude 側的同類問題
多輪對話實現指南
各家模型的歷史回傳方式