简短回答
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 侧的同类问题
多轮对话实现指南
各家模型的历史回传方式