Gemini Interactions API 迁移指南:outputs 改为 steps 后怎么排错

Gemini Interactions API 的旧 outputs schema 已移除。本文说明如何改用 steps、output_text、新 SSE 事件、工具调用和会话历史,并快速定位迁移后的常见报错。

Gemini Interactions API 已成为新项目推荐的统一接口。它把一次生成、工具调用、思考过程、工具结果和最终回复都表示为可观察的执行步骤,适合 Agent、长任务和需要显示中间状态的应用。

这也意味着旧代码不能再假定响应中有 outputs。从 2026 年 5 月起,新 schema 开始成为默认;旧 schema 已在 6 月 8 日移除。若迁移后出现空回复、工具调用丢失、SSE 事件不触发或历史上下文断裂,通常不是模型问题,而是仍按旧结构读取数据。

先确认你迁移的是哪一层

排错前先把问题归类,避免只改一个字段:

层级 旧做法 新做法
最终文本 遍历 outputs 找文本 简单场景读 interaction.output_text
完整响应 outputs 中找内容、工具或搜索结果 遍历 interaction.steps,按 type 处理
工具调用 从旧 content 类型中解析 处理 function_callfunction_result 等步骤
流式事件 content.startcontent.deltacontent.stop step.startstep.deltastep.stop
多轮历史 回传旧 outputs 服务器端用 previous_interaction_id,或客户端回传 steps

如果 SDK 仍是 Python 1.x 或 JavaScript 1.x,先确认版本。官方迁移说明要求使用 Python ≥2.0.0 或 JavaScript ≥2.0.0 来自动采用新 schema;但升级 SDK 不会自动修复你自己写的 outputs 解析器、SSE 处理器和前端状态机。

最简单的修复:用 output_text 读取最终文本

只处理纯文本问答时,不必手动从 steps 中找最后一段文字。新版 SDK 提供 output_text,会提取并拼接响应末尾连续的文本块:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
from google import genai

client = genai.Client()

interaction = client.interactions.create(
    model="gemini-3.5-flash",
    input="用三句话解释什么是 prompt caching。",
)

print(interaction.output_text)

如果你迁移后把 interaction.outputs[-1].text 原样保留,常见结果是属性不存在、索引失败,或错误地把对象序列化成空字符串。先替换成 interaction.output_text,再补充复杂场景的步骤解析。

output_text 不适合所有响应:当文本被 thought、图片、音频或工具调用隔开时,它不会替你还原所有交错内容。需要展示完整执行过程时,应遍历 steps

如何正确遍历 steps

新 schema 将过程表示为有类型的步骤。至少要识别 user_inputmodel_outputfunction_callfunction_result;如果使用服务端工具,还会看到 google_search_callgoogle_search_result 或其他工具特定步骤。

下面示例只收集最终模型输出中的文本:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
def collect_model_text(interaction):
    chunks = []

    for step in interaction.steps:
        if step.type != "model_output":
            continue

        for item in step.content or []:
            if item.type == "text":
                chunks.append(item.text)

    return "".join(chunks)


print(collect_model_text(interaction))

真实项目中不要假设每个步骤都有 content,也不要把 thought 当成最终答案。先根据 step.type 分支,再读取该类型允许的字段。把未知步骤记录为类型、ID 和状态,保留向前兼容空间;不要因为出现新的工具步骤就让整个请求失败。

工具调用为什么“消失”了

旧 schema 常把服务端工具操作包在 outputs 的特定内容类型里。新 schema 将它们拆为独立步骤,因此只扫描 model_output 会看不到搜索、函数调用和函数结果。

例如,函数调用应这样读取:

1
2
3
4
5
6
for (const step of interaction.steps) {
  if (step.type === 'function_call') {
    console.log(`Calling ${step.name}`);
    console.log(step.arguments);
  }
}

服务端 Google Search 也应分别处理调用和结果步骤,而不是从最终文本中猜测有没有执行搜索。对于客户端函数工具,收到 requires_action 后,提交对应 function_result,并继续使用该 interaction 的状态完成后续流程。

流式 SSE 事件要一起迁移

只改 REST 响应解析、不改流式处理器,前端通常会表现为“请求成功但页面不更新”。新版事件名称如下:

旧事件 新事件
interaction.start interaction.created
interaction.complete interaction.completed
content.start step.start
content.delta step.delta
content.stop step.stop
interaction.status_update interaction.in_progressinteraction.requires_action 等状态事件

函数调用的参数也不再保证一次性完整到达。流中 step.start 会先给出函数名,后续多个 step.delta 事件以部分 JSON 参数逐段传递。客户端必须累积参数,在 step.stop 或需要动作的状态后再解析完整 JSON;不要对每一个 delta 都直接 JSON.parse()

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
let rawArguments = '';

for await (const event of stream) {
  if (event.event_type === 'step.delta' && event.delta?.type === 'arguments') {
    rawArguments += event.delta.partial_arguments;
  }

  if (event.event_type === 'step.stop') {
    // 只在对应 function_call 步骤完成后解析 rawArguments。
  }
}

多轮对话别再回传 outputs

旧的无状态实现常把上一轮的 outputs 收集后塞回下一轮 input。迁移后有两种更清晰的选择:

  • 使用默认服务器端状态,通过 previous_interaction_id 延续同一会话;
  • 必须自行管理历史时,回传上一轮的 steps,再追加新的 user_input 步骤。

服务器端状态更适合普通多轮对话;需要严格控制保存内容、跨系统迁移或离线回放时,再使用客户端状态。无论选择哪种,都不要同时拼接旧 outputs 和新 steps,否则容易产生重复上下文、工具结果不匹配或 token 激增。

response_format 也可能是报错来源

这次迁移不只改了输出数组。结构化输出和多模态配置也统一到顶层 response_format

  • 原先的 response_mime_type 已移除;在 response_format 条目中指定 mime_type
  • JSON schema 需要放入带有 type: "text" 的格式对象。
  • 图片配置从 generation_config 移到 response_format 中的 type: "image" 条目。
  • 多模态输出需要使用格式条目数组。

如果接口返回 400,除了检查 steps,也搜索代码中的 response_mime_typegeneration_config.image_config 和旧版单对象 response_format。这些旧字段与 outputs 问题常在同一次升级后一起出现。

一份实用排错顺序

  1. 升级 Google GenAI SDK,并记录实际版本。
  2. 用一个无工具、非流式的最小请求验证 interaction.output_text
  3. 打印 interaction.steps 的类型和状态,确认程序收到的是新 schema。
  4. 分别迁移函数调用、服务端搜索和工具结果的解析逻辑。
  5. 修改 SSE 事件订阅和参数累积逻辑。
  6. 检查多轮历史是否改为 previous_interaction_idsteps
  7. 搜索并替换旧的 response_format 相关字段。
  8. 用文本、工具调用、流式输出和失败重试各跑一次回归测试。

不要为了临时恢复旧代码去依赖过去的 Api-Revision 头。旧 schema 的过渡期已经结束;现在应把迁移作为正式兼容性修复,而不是继续保留两套不一致的解析器。

总结

outputs 改为 steps 的本质是:Interactions API 不再把所有过程塞进一个输出列表,而是显式暴露输入、思考、工具、结果和最终输出。纯文本场景优先使用 interaction.output_text;Agent、工具、流式和多模态场景按 step.type 建立明确分支;多轮会话改用 previous_interaction_idsteps。按这三个原则迁移,绝大多数“无输出”“工具丢失”和“SSE 不刷新”问题都能定位。

官方资料:

记录并分享
使用 Hugo 构建
主题 StackJimmy 设计