作者注:深度解析 Nano Banana 2 API 响应中 thoughtSignature 字段的本质:它不是图片而是加密的思考签名,详解 Thinking 模式响应结构、正确处理方式和常见踩坑
不少开发者在调用 Nano Banana 2 API 生成图片时,发现响应里除了图片数据,还有一个 thoughtSignature 字段——它也是一长串 base64 编码,看起来像图片数据。尝试解码后发现根本转不成图片,这到底是什么?本文将彻底讲清楚 thoughtSignature 的本质、为什么它不是图片、以及在多轮对话中如何正确处理它。
核心价值: 读完本文,你将理解 thoughtSignature 的技术原理,避免把它误当图片处理,并掌握多轮对话中正确传递签名的方法。

Nano Banana 2 API thoughtSignature 核心要点
先直接回答最常见的问题:thoughtSignature 不是图片,不能解码为图片,它是模型思考过程的加密签名。
| 要点 | 说明 | 开发者须知 |
|---|---|---|
| 本质 | 加密签名的 base64 编码二进制数据 | 不可解码、不可修改、不可伪造 |
| 内容 | 模型推理过程的内部状态快照 | 对开发者完全不透明 |
| 用途 | 在多轮对话中保持推理连续性 | 必须原样回传给下一轮请求 |
| 格式 | 看起来像 base64 图片,但不是 | 无 magic bytes,无法识别为任何图片格式 |
| 强制性 | 工具调用场景下必须传递(否则 400 错误) | 纯文本场景可省略但会降低质量 |
Nano Banana 2 API 响应中的 thoughtSignature 长什么样
当你调用 Nano Banana 2 生成图片时,API 响应中的 parts 数组可能包含多个元素。典型的响应结构是这样的:
{
"candidates": [{
"content": {
"role": "model",
"parts": [
{
"text": "让我思考一下如何生成这张图片...",
"thought": true
},
{
"text": "",
"thoughtSignature": "CpcHAdHtim9+q4rstcbvQC0ic4x1/vqQlCJ..."
},
{
"inlineData": {
"mime_type": "image/png",
"data": "iVBORw0KGgoAAAANSUhEUg..."
}
}
]
}
}]
}
这里有三个 part,分别是:
- 思考摘要(
thought: true):模型推理过程的文字概述 - 思考签名(
thoughtSignature):加密的推理状态快照 - 图片数据(
inlineData):真正的图片 base64 数据
关键问题就在于第 2 和第 3 个 part 都包含 base64 编码数据,如果你的代码没有正确区分,就会把 thoughtSignature 误当成图片数据去解码——然后发现怎么都转不成图片。

Nano Banana 2 API thoughtSignature 的技术原理
理解了 thoughtSignature 不是图片之后,再来看看它到底是什么。
thoughtSignature 的本质
根据 Google 官方文档的定义:
thoughtSignature(string,可选):"An opaque signature for the thought so it can be reused in subsequent requests. A base64-encoded string."
翻译成大白话:thoughtSignature 是模型思考过程的"记忆快照",经过加密签名后以 base64 编码形式返回。它的作用是让模型在多轮对话中能够"记住"之前的推理过程,从而保持思维连贯性。
几个关键特征:
- 不透明(Opaque): 开发者无法解读其内容,也无需关心内部结构
- 密码学签名: 由 Google 服务端签名,无法伪造——传一个随机 base64 字符串会返回"无效签名"错误
- 有状态: 包含模型在生成当前回答时的推理链和中间计算结果
thoughtSignature 与 thought 的区别
这两个字段经常搞混,但它们完全不同:
| 字段 | 类型 | 含义 | 可读性 | 用途 |
|---|---|---|---|---|
| thought | boolean | 标记当前 part 是否为思考摘要 | 可读(文本) | 展示模型推理过程 |
| thoughtSignature | string(base64) | 加密的推理状态快照 | 不可读(密文) | 多轮对话传递推理状态 |
thought 是给人看的推理摘要,thoughtSignature 是给模型"看"的推理记忆。
Nano Banana 2 API 为什么需要 thoughtSignature
Nano Banana 2 属于 Gemini 3.1 系列,支持 Thinking(思考)模式。模型在生成图片前会先进行内部推理——分析提示词意图、规划构图、选择色彩方案等。
这个推理过程的完整状态被压缩加密成 thoughtSignature。当你在多轮对话中进行图片编辑(比如"把背景改成蓝色"),模型需要恢复之前的推理状态才能准确理解你的修改意图。
如果不传回 thoughtSignature:
- 纯文本场景:不报错,但推理质量和连贯性会下降
- 工具调用/函数调用场景:直接返回 HTTP 400 错误
- 图片编辑多轮对话:可能丢失上下文,编辑结果不准确
🎯 开发建议: 在任何多轮对话场景中,都应该完整保留并回传
thoughtSignature。
通过 API易 apiyi.com 调用时,平台会自动处理签名的传递和格式兼容,开发者无需手动管理。
Nano Banana 2 API thoughtSignature 正确处理方式
极简示例:正确解析响应并区分图片和签名
以下代码展示如何正确从 Nano Banana 2 的响应中提取图片,同时保存 thoughtSignature 供后续使用:
from google import genai
from google.genai import types
client = genai.Client(api_key="YOUR_API_KEY")
response = client.models.generate_content(
model="gemini-3.1-flash-image-preview",
contents=["画一只在樱花树下的白猫"],
config=types.GenerateContentConfig(
response_modalities=["TEXT", "IMAGE"],
image_config=types.ImageConfig(image_size="2K"),
thinking_config=types.ThinkingConfig(
include_thoughts=True
),
)
)
saved_signature = None
for part in response.parts:
if hasattr(part, 'thought') and part.thought:
print(f"思考过程: {part.text[:100]}...")
elif hasattr(part, 'thought_signature') and part.thought_signature:
saved_signature = part.thought_signature # 保存,不解码!
print("已保存 thoughtSignature(非图片)")
elif image := part.as_image():
image.save("cat_sakura.png", format="PNG")
print("图片已保存")
查看多轮对话中回传 thoughtSignature 的完整代码
from google import genai
from google.genai import types
client = genai.Client(api_key="YOUR_API_KEY")
# 第一轮:生成图片
response1 = client.models.generate_content(
model="gemini-3.1-flash-image-preview",
contents=["画一只在樱花树下的白猫"],
config=types.GenerateContentConfig(
response_modalities=["TEXT", "IMAGE"],
image_config=types.ImageConfig(image_size="2K"),
thinking_config=types.ThinkingConfig(
include_thoughts=True
),
)
)
# 提取图片和签名
image_data = None
thought_signature = None
model_parts = []
for part in response1.parts:
model_parts.append(part) # 保留完整的 parts
if hasattr(part, 'thought_signature') and part.thought_signature:
thought_signature = part.thought_signature
elif image := part.as_image():
image.save("round1.png", format="PNG")
# 第二轮:基于上一轮结果进行编辑
# 关键:将上一轮的完整 parts(含 thoughtSignature)作为历史传入
history = [
{"role": "user", "parts": [{"text": "画一只在樱花树下的白猫"}]},
{"role": "model", "parts": model_parts}, # 包含 thoughtSignature
]
response2 = client.models.generate_content(
model="gemini-3.1-flash-image-preview",
contents=history + [
{"role": "user", "parts": [{"text": "把背景改成夜空,加上月亮"}]}
],
config=types.GenerateContentConfig(
response_modalities=["TEXT", "IMAGE"],
image_config=types.ImageConfig(image_size="2K"),
)
)
for part in response2.parts:
if image := part.as_image():
image.save("round2_edited.png", format="PNG")
print("编辑后的图片已保存")
建议: 通过 API易 apiyi.com 调用 Nano Banana 2 时,平台提供 OpenAI 兼容格式接口,自动处理 thoughtSignature 的传递,无需手动管理多轮对话的签名状态。
Nano Banana 2 API thoughtSignature 常见踩坑和解决方案
踩坑场景总结
| 场景 | 问题 | 原因 | 解决方案 |
|---|---|---|---|
| 把签名当图片解码 | base64 解码后不是有效图片 | thoughtSignature 是加密数据不是图片 | 检查是否有 inlineData 字段再解码 |
| 多轮对话丢失签名 | 后续回复质量下降或返回 400 | 没有回传 thoughtSignature | 保存完整 parts 含签名传入下一轮 |
| 伪造签名 | 返回"invalid signature"错误 | 签名有密码学校验 | 必须使用 API 原样返回的值 |
| 字段名不一致 | Python 和 REST 用不同名字 | REST 用 camelCase,SDK 用 snake_case | REST: thoughtSignature,Python: thought_signature |
| 流式响应遗漏 | 漏掉了签名数据 | 签名可能在最后一个 chunk 的空 text part 中 | 即使 text 为空也要检查签名字段 |
Nano Banana 2 API thoughtSignature 字段命名对照
不同调用方式下字段命名不同,这是另一个常见坑点:
| 调用方式 | 字段名 | 位置 |
|---|---|---|
| REST API(原始 JSON) | thoughtSignature |
parts[].thoughtSignature |
| Python SDK | thought_signature |
part.thought_signature |
| OpenAI 兼容格式(中转) | thought_signature |
provider_specific_fields.thought_signature |
Nano Banana 2 API 应急方案:dummy 签名
如果你在迁移旧对话历史、没有有效的 thoughtSignature,Google 提供了一个特殊的绕过值:
DUMMY_SIGNATURE = "context_engineering_is_the_way_to_go"
将这个字符串作为 thoughtSignature 的值传入,可以避免 400 错误。但这只是应急方案,模型的推理连贯性会受影响。
🎯 最佳实践: 从第一次调用开始就完整保存所有
thoughtSignature,建立正确的对话历史链。
如果觉得手动管理太复杂,通过 API易 apiyi.com 使用 OpenAI 兼容接口可以大幅降低复杂度。

常见问题
Q1: thoughtSignature 的 base64 数据能解码成什么?
什么有意义的内容都解码不出来。它是经过加密签名的二进制数据,设计上就是不透明的(opaque)。你可以 base64 解码得到一串二进制字节,但这些字节不是任何已知的文件格式——不是图片、不是文本、不是 JSON。唯一正确的处理方式就是原样保存、原样回传。
Q2: 不传回 thoughtSignature 会怎样?
两种情况:1)纯文本对话场景,不会报错但模型推理连贯性会下降,后续回答质量可能不如预期;2)工具调用(function calling)场景,Gemini 3 系列模型会直接返回 HTTP 400 错误。对于 Nano Banana 2 的图片编辑多轮对话,丢失签名会导致模型无法正确恢复上下文,编辑结果可能不准确。建议通过 API易 apiyi.com 使用 OpenAI 兼容接口,平台自动处理签名传递。
Q3: 如何区分响应中哪些是图片、哪些是签名?
检查字段类型即可:有 inlineData(含 mime_type 和 data)的 part 是图片数据;有 thoughtSignature / thought_signature 字段的 part 是签名;thought: true 的 part 是思考摘要文字。用代码判断时,优先检查 inlineData 是否存在,再检查其他字段。
Q4: 旧的对话历史没有 thoughtSignature,怎么补上?
Google 提供了一个特殊的 dummy 签名值 "context_engineering_is_the_way_to_go",可以作为 thoughtSignature 的临时值传入,避免 400 错误。但这只是兼容方案,不具备真正的推理恢复能力。长期建议是从新对话开始就完整保存所有签名。
总结
Nano Banana 2 API 中 thoughtSignature 的核心要点:
- 不是图片:
thoughtSignature是加密的思考过程签名,不是 base64 图片数据,不能解码为任何图片格式 - 必须原样回传: 在多轮对话中保存并原样传回
thoughtSignature,否则工具调用会 400 报错,文本对话质量会下降 - 正确区分三种 part: 有
inlineData的是图片,有thoughtSignature的是签名,thought: true的是思考摘要
理解这个字段的本质后,你在解析 Nano Banana 2 API 响应时就不会再踩"把签名当图片解码"的坑了。
推荐通过 API易 apiyi.com 快速验证 Nano Banana 2 的多轮对话图片编辑功能,平台自动处理 thoughtSignature 传递,提供免费额度和统一接口。
📚 参考资料
-
Thought Signatures 官方文档: Google 对 thoughtSignature 机制的完整说明
- 链接:
ai.google.dev/gemini-api/docs/thought-signatures - 说明: 包含字段定义、传递规则和多轮对话示例
- 链接:
-
Gemini Thinking 模式文档: Thinking 功能的开启方式和配置参数
- 链接:
ai.google.dev/gemini-api/docs/thinking - 说明: 了解 include_thoughts、thinking_level 等配置
- 链接:
-
Vertex AI 推理 API 参考: REST API 中 Part 对象的完整字段定义
- 链接:
docs.cloud.google.com/vertex-ai/generative-ai/docs/model-reference/inference - 说明: 包含 thoughtSignature 的类型定义和使用限制
- 链接:
-
API易文档中心: 通过 OpenAI 兼容接口调用 Nano Banana 2 的简化方案
- 链接:
docs.apiyi.com - 说明: 自动处理 thoughtSignature 传递,降低开发复杂度
- 链接:
作者: APIYI 技术团队
技术交流: 欢迎在评论区讨论,更多资料可访问 API易 docs.apiyi.com 文档中心
