流式传输
官方来源:https://ai.google.dev/gemini-api/docs/streaming?hl=zh-cn
来源:Google AI for Developers Gemini API 文档。除非另有说明,页面内容采用 CC BY 4.0,代码示例采用 Apache 2.0。
整理时间:2026-07-01 18:50
· Gemini API
流式传输互动
创建 Interaction 时,您可以将 stream: true 设置为使用 服务器发送的事件 (SSE) 逐步流式传输回答。
Python
- from google import genai
- client = genai.Client()
- stream = client.interactions.create(
- model="gemini-3-flash-preview",
- input="Count to from 1 to 25.",
- stream=True,
- )
- for event in stream:
- if event.event_type == "step.delta":
- if event.delta.type == "text":
- print(event.delta.text, end="", flush=True)
JavaScript
- import { GoogleGenAI } from "@google/genai";
- const client = new GoogleGenAI({});
- const stream = await client.interactions.create({
- model: "gemini-3-flash-preview",
- input: "Count to from 1 to 25.",
- stream: true,
- });
- for await (const event of stream) {
- if (event.event_type === "step.delta") {
- if (event.delta.type === "text") {
- process.stdout.write(event.delta.text);
- }
- }
- }
REST
- curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
- -H "x-goog-api-key: $GEMINI_API_KEY" \
- -H "Content-Type: application/json" \
- --no-buffer \
- -d '{
- "model": "gemini-3-flash-preview",
- "input": "Count to from 1 to 25.",
- "stream": true
- }'
- event: interaction.created
- data: {"interaction":{"id":"v1_...","status":"in_progress","object":"interaction","model":"gemini-3-flash-preview"},"event_type":"interaction.created"}
- event: interaction.status_update
- data: {"interaction_id":"v1_...","status":"in_progress","event_type":"interaction.status_update"}
- event: step.start
- data: {"index":0,"step":{"type":"thought"},"event_type":"step.start"}
- event: step.delta
- data: {"index":0,"delta":{"signature":"...","type":"thought_signature"},"event_type":"step.delta"}
- event: step.stop
- data: {"index":0,"event_type":"step.stop"}
- event: step.start
- data: {"index":1,"step":{"type":"model_output"},"event_type":"step.start"}
- event: step.delta
- data: {"index":1,"delta":{"text":"1, 2, 3, 4, 5, 6, ","type":"text"},"event_type":"step.delta"}
- event: step.delta
- data: {"index":1,"delta":{"text":"7, 8, 9, 10, 11, 12, 13,","type":"text"},"event_type":"step.delta"}
- ...
- event: step.stop
- data: {"index":1,"event_type":"step.stop"}
- event: interaction.completed
- data: {"interaction":{"id":"v1_...","status":"completed","usage":{"total_tokens":346,"total_input_tokens":11,"input_tokens_by_modality":[{"modality":"text","tokens":11}],"total_cached_tokens":0,"total_output_tokens":90,"total_tool_use_tokens":0,"total_thought_tokens":245},"created":"2026-05-12T18:44:51Z","updated":"2026-05-12T18:44:51Z","service_tier":"standard","object":"interaction","model":"gemini-3-flash-preview"},"event_type":"interaction.completed"}
- event: done
- data: [DONE]
事件类型
每个服务器发送的事件都包含一个名为 event_type 的名称和关联的 JSON 数据。Interactions API 使用对称的流式传输模型,其中所有内容(文本、工具调用、思考)都通过一致的 基于步骤 的事件进行传输。
每个数据流都遵循以下事件流:
· interaction.created :创建互动,包括元数据(ID、模型、状态)。
· 一系列 步骤 ,每个步骤都包含: step.start 事件,用于指示步骤类型(例如 model_output 、 thought 、 function_call )。 一个或多个 step.delta 事件,其中包含相应步骤的增量数据。 用于将步骤标记为已完成的 step.stop 事件。
· step.start 事件,用于指示步骤类型(例如 model_output 、 thought 、 function_call )。
· 一个或多个 step.delta 事件,其中包含相应步骤的增量数据。
· 用于将步骤标记为已完成的 step.stop 事件。
· 具有最终 usage 统计信息的 interaction.completed 事件。
设置 stream: false 后,API 会返回一个包含 steps 数组的 interaction 对象。 steps 中的每个元素都是一个 step.start → step.delta (s) → step.stop 周期的完全组装版本。
interaction.created
在首次创建互动时发送。包含互动 ID、模型和初始状态。
- event: interaction.created
- data: {"interaction": {"id": "...", "model": "gemini-3-flash-preview", "status": "in_progress", "object": "interaction"}, "event_type": "interaction.created"}
interaction.status_update
表示互动级状态转换。可能会显示在步骤之间。
- event: interaction.status_update
- data: {"interaction_id": "...", "status": "in_progress", "event_type": "interaction.status_update"}
step.start
标记新步骤的开始。包含步骤 type 和 index 。步数类型决定了要预期哪些增量类型,以及步数在非流式响应中的显示方式:
表格内容:
步骤类型 | 预期增量类型 | 说明
model_output | text 、 image 、 audio | 模型的最终回答内容。
thought | thought_signature 、 thought_summary | 思维链推理。仅当 thinking_summaries 处于启用状态时,才会显示 summary 。
function_call | arguments_delta | 客户端执行函数的请求。将互动状态设置为 requires_action 。
服务器端工具 | 因工具而异 | 由 API 执行的工具(例如 google_search_call 、 google_search_result 、 code_execution_call 、 code_execution_result )。
如需查看完整列表,请参阅 Interactions API 参考文档 。
- event: step.start
- data: {"index": 0, "step": {"type": "model_output"}, "event_type": "step.start"}
对于函数调用,该步骤包括函数名称、ID 和空实参 {}
- event: step.start
- data: {"index": 0, "step": {"type": "function_call", "id":"un6k8t18", "name": "get_weather", "arguments":{}}, "event_type": "step.start"}
step.delta
当前步的增量数据。 delta 对象包含一个用于确定其形状的 type 字段。
text :来自 model_output 步骤的增量文本令牌:
- event: step.delta
- data: {"index": 0, "delta": {"type": "text", "text": "Hello, my name is Phil"}, "event_type": "step.delta"}
- event: step.delta
- data: {"index": 0, "delta": {"type": "text", "text": ", and I live in Germany." }, "event_type": "step.delta"}
image :来自 model_output 步骤的 Base64 编码图片数据:
- event: step.delta
- data: {"index": 0, "delta": {"type": "image", "mime_type": "image/jpeg", "data": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAoHBwgHBgoICAgLCg..."}, "event_type": "step.delta"}
thought_summary :来自 thought 步骤的思考总结内容:
- event: step.delta
- data: {"index": 0, "delta": {"type": "thought_summary", "content": {"type": "text", "text": "I need to find the GCD..."}}, "event_type": "step.delta"}
arguments_delta :函数调用实参的(部分)JSON 字符串。必须在多个增量中累积:
- event: step.delta
- data: {"index": 0, "delta": {"type": "arguments_delta", "arguments": "{\"location\": \"San Francisco, CA\"}"}, "event_type": "step.delta"}
以下是一些最常见的增量类型。如需查看所有增量类型的完整列表,请参阅 Interactions API 参考文档 。
step.stop
标记步骤的结束。包含步骤 index 。
- event: step.stop
- data: {"index": 0, "event_type": "step.stop"}
interaction.completed
互动结束时发送。包含具有 usage 统计信息的最终互动对象。在非流式模式下,这是顶级响应对象本身。不在响应中包含 steps 。
- event: interaction.completed
- data: {"interaction": {"id": "v1_abc123", "status": "completed", "usage": {"total_input_tokens": 7, "total_output_tokens": 12, "total_tokens": 19}}, "event_type": "interaction.completed"}
error
在互动期间发生错误时发送。包含一个带有消息和代码的错误对象。
- event: error
- data: {"error":{"message":"Deadline expired before operation could complete.","code":"gateway_timeout"},"event_type":"error"}
使用工具进行流式传输
Interactions API 支持在单个请求中通过客户端工具(函数调用)和服务器端工具(Google 搜索、代码执行等)进行流式传输。在流式传输期间,工具调用会以输入步骤的形式显示在事件流中。对于函数调用, step.start 事件会传递函数名称,而 step.delta 事件会以 JSON 字符串 ( arguments_delta ) 的形式流式传输实参。您必须累积这些增量才能获得完整的实参。Google 搜索等服务器端工具由 API 自动执行,从而生成 google_search_call 和 google_search_result 步骤。
使用函数调用进行流式传输
如需使用流式处理执行函数调用,客户端必须处理多轮对话:
· 第 1 轮(函数请求) :使用 stream: true 和您定义的 tools 调用 interactions.create 。该 API 将以流式传输 function_call 步。您必须从 step.delta 事件中累积增量实参 JSON 字符串 ( arguments_delta ),直到互动以状态 requires_action 完成。
· 第 2 轮(发送结果) :再次调用 interactions.create ,传递 previous_interaction_id (与第一次互动的 ID 匹配),并在 input 数组中发送 function_result 块。这会恢复流,使模型能够生成最终回答。
- from google import genai
- client = genai.Client()
- weather_tool = {
- "type": "function",
- "name": "get_weather",
- "description": "Get the current weather in a given location",
- "parameters": {
- "type": "object",
- "properties": {
- "location": {
- "type": "string",
- "description": "The city and state, e.g. San Francisco, CA"
- }
- },
- "required": ["location"]
- }
- }
- # Turn 1: Request function call
- stream = client.interactions.create(
- model="gemini-3-flash-preview",
- tools=[weather_tool],
- input="What is the weather in Paris right now?",
- stream=True,
- )
- first_interaction_id = None
- func_call_id = None
- func_call_name = None
- func_args_accumulated = ""
- for event in stream:
- if event.event_type == "interaction.created":
- first_interaction_id = event.interaction.id
- elif event.event_type == "step.start":
- step = event.step
- if step.type == "function_call":
- func_call_id = step.id
- func_call_name = step.name
- elif event.event_type == "step.delta":
- if event.delta.type == "arguments_delta":
- func_args_accumulated += event.delta.arguments
- # Turn 2: Execute tool and send the result back to resume stream
- if func_call_id:
- # Execute weather_tool using accumulated arguments
- # args = json.loads(func_args_accumulated)
- dummy_result = {
- "content": [{"type": "text", "text": '{"weather": "Sunny and 22°C"}'}]
- }
- stream2 = client.interactions.create(
- model="gemini-3-flash-preview",
- previous_interaction_id=first_interaction_id,
- input=[{
- "type": "function_result",
- "name": func_call_name,
- "call_id": func_call_id,
- "result": dummy_result
- }],
- stream=True,
- )
- for event in stream2:
- if event.event_type == "step.delta":
- if event.delta.type == "text":
- print(event.delta.text, end="", flush=True)
- import { GoogleGenAI } from "@google/genai";
- const client = new GoogleGenAI({});
- const weatherTool = {
- type: "function",
- name: "get_weather",
- description: "Get the current weather in a given location",
- parameters: {
- type: "object",
- properties: {
- location: {
- type: "string",
- description: "The city and state, e.g. San Francisco, CA"
- }
- },
- required: ["location"]
- }
- };
- // Turn 1: Request function call
- const stream = await client.interactions.create({
- model: "gemini-3-flash-preview",
- tools: [weatherTool],
- input: "What is the weather in Paris right now?",
- stream: true,
- });
- let firstInteractionId = null;
- let funcCallId = null;
- let funcCallName = null;
- let funcArgsAccumulated = "";
- for await (const event of stream) {
- if (event.event_type === "interaction.created") {
- firstInteractionId = event.interaction.id;
- } else if (event.event_type === "step.start") {
- const step = event.step;
- if (step.type === "function_call") {
- funcCallId = step.id;
- funcCallName = step.name;
- }
- } else if (event.event_type === "step.delta") {
- if (event.delta.type === "arguments_delta") {
- funcArgsAccumulated += event.delta.arguments;
- }
- }
- }
- // Turn 2: Execute tool and send the result back to resume stream
- if (funcCallId && firstInteractionId && funcCallName) {
- // const args = JSON.parse(funcArgsAccumulated);
- const dummyResult = {
- content: [{ type: "text", text: '{"weather": "Sunny and 22°C"}' }]
- };
- const stream2 = await client.interactions.create({
- model: "gemini-3-flash-preview",
- previous_interaction_id: firstInteractionId,
- input: [{
- type: "function_result",
- name: funcCallName,
- call_id: funcCallId,
- result: dummyResult
- }],
- stream: true,
- });
- for await (const event of stream2) {
- if (event.event_type === "step.delta") {
- if (event.delta.type === "text") {
- process.stdout.write(event.delta.text);
- }
- }
- }
- }
第 1 轮 :请求函数调用
- curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
- -H "x-goog-api-key: $GEMINI_API_KEY" \
- -H "Content-Type: application/json" \
- --no-buffer \
- -d '{
- "model": "gemini-3-flash-preview",
- "input": "What is the weather in Paris right now?",
- "stream": true,
- "tools": [
- {
- "type": "function",
- "name": "get_weather",
- "description": "Get the current weather in a given location",
- "parameters": {
- "type": "object",
- "properties": {
- "location": {
- "type": "string",
- "description": "The city and state, e.g. San Francisco, CA"
- }
- },
- "required": ["location"]
- }
- }
- ]
- }'
第 2 轮 :使用第 1 轮中的 previous_interaction_id 和 call_id 发送函数结果
- curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
- -H "x-goog-api-key: $GEMINI_API_KEY" \
- -H "Content-Type: application/json" \
- --no-buffer \
- -d '{
- "model": "gemini-3-flash-preview",
- "previous_interaction_id": "v1_ChdGUVFJYXBXVUdLVEF4TjhQ...",
- "stream": true,
- "input": [
- {
- "type": "function_result",
- "name": "get_weather",
- "call_id": "CALL_ID",
- "result": {
- "content": [
- {
- "type": "text",
- "text": "{\"weather\": \"Sunny and 22°C\"}"
- }
- ]
- }
- }
- ]
- }'
使用多种工具进行直播
以下示例在一个请求中同时使用了 function 工具和 google_search :
- from google import genai
- client = genai.Client()
- tools = [
- {"type": "google_search"},
- {
- "type": "function",
- "name": "get_weather",
- "description": "Get the current weather in a given location",
- "parameters": {
- "type": "object",
- "properties": {
- "location": {
- "type": "string",
- "description": "The city and state, e.g. San Francisco, CA"
- }
- },
- "required": ["location"]
- }
- }
- ]
- stream = client.interactions.create(
- model="gemini-3-flash-preview",
- tools=tools,
- input="Search what it the largest mountain in Europe and what the weather is there right now?",
- stream=True,
- )
- for event in stream:
- if event.event_type == "step.start":
- step = event.step
- print(f"\n--- Step {event.index}: {step.type} ---")
- # Show details for tool steps
- if step.type == "google_search_call":
- print(f" Search ID: {step.id}")
- elif step.type == "google_search_result":
- print(f" Result for: {step.call_id}")
- elif step.type == "function_call":
- print(f" Function: {step.name}({step.arguments})")
- elif event.event_type == "step.delta":
- if event.delta.type == "text":
- print(event.delta.text, end="", flush=True)
- elif event.delta.type == "google_search_call":
- print(f" Queries: {event.delta.arguments}")
- elif event.delta.type == "arguments_delta":
- print(f" Args chunk: {event.delta.arguments}", end="", flush=True)
- elif event.event_type == "interaction.completed":
- print(f"\n\nStatus: {event.interaction.status}")
- if event.interaction.status == "requires_action":
- print("Action required: provide function call results to continue.")
- import { GoogleGenAI } from "@google/genai";
- const client = new GoogleGenAI({});
- const tools = [
- { type: "google_search" },
- {
- type: "function",
- name: "get_weather",
- description: "Get the current weather in a given location",
- parameters: {
- type: "object",
- properties: {
- location: {
- type: "string",
- description: "The city and state, e.g. San Francisco, CA"
- }
- },
- required: ["location"]
- }
- }
- ];
- const stream = await client.interactions.create({
- model: "gemini-3-flash-preview",
- tools: tools,
- input: "Search what it the largest mountain in Europe and what the weather is there right now?",
- stream: true,
- });
- for await (const event of stream) {
- if (event.event_type === "step.start") {
- const step = event.step;
- console.log(`\n--- Step ${event.index}: ${step.type} ---`);
- // Show details for tool steps
- if (step.type === "google_search_call") {
- console.log(` Search ID: ${step.id}`);
- } else if (step.type === "google_search_result") {
- console.log(` Result for: ${step.call_id}`);
- } else if (step.type === "function_call") {
- console.log(` Function: ${step.name}(${JSON.stringify(step.arguments)})`);
- }
- } else if (event.event_type === "step.delta") {
- if (event.delta.type === "text") {
- process.stdout.write(event.delta.text);
- } else if (event.delta.type === "google_search_call") {
- console.log(` Queries: ${JSON.stringify(event.delta.arguments?.queries)}`);
- } else if (event.step.type === "google_search_result") {
- console.log(` Result for: ${event.step.call_id}`);
- } else if (event.delta.type === "arguments_delta") {
- process.stdout.write(` Args chunk: ${event.delta.arguments}`);
- }
- } else if (event.event_type === "interaction.completed") {
- console.log(`\n\nStatus: ${event.interaction.status}`);
- if (event.interaction.status === "requires_action") {
- console.log("Action required: provide function call results to continue.");
- }
- }
- }
- curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
- -H "x-goog-api-key: $GEMINI_API_KEY" \
- -H "Content-Type: application/json" \
- --no-buffer \
- -d '{
- "model": "gemini-3-flash-preview",
- "input": "Search what it the largest mountain in Europe and what the weather is there right now?",
- "stream": true,
- "tools": [
- { "type": "google_search" },
- {
- "type": "function",
- "name": "get_weather",
- "description": "Get the current weather in a given location",
- "parameters": {
- "type": "object",
- "properties": {
- "location": {
- "type": "string",
- "description": "The city and state, e.g. San Francisco, CA"
- }
- },
- "required": ["location"]
- }
- }
- ]
- }'
包含思考的流式传输
当模型使用思考功能时,您会收到 thought 步,其中包含两种不同的增量类型: thought_summary (增量文本或图片摘要内容)和 thought_signature (模型内部推理的加密表示形式,在 step.stop 之前作为最后一个增量发送)。如果启用 thinking_summaries , thought_summary 增量会流式传输模型推理的摘要。如需详细了解思考,请参阅 思考指南 。
- from google import genai
- client = genai.Client()
- stream = client.interactions.create(
- model="gemini-3-flash-preview",
- input="What is the greatest common divisor of 1071 and 462?",
- generation_config={
- "thinking_summaries": "auto"
- },
- stream=True,
- )
- for event in stream:
- if event.event_type == "step.start":
- print(f"\n--- Step: {event.step.type} ---")
- elif event.event_type == "step.delta":
- if event.delta.type == "thought_summary":
- if event.delta.content.type == "text":
- print(event.delta.content.text, end="", flush=True)
- elif event.delta.type == "text":
- print(event.delta.text, end="", flush=True)
- import { GoogleGenAI } from "@google/genai";
- const client = new GoogleGenAI({});
- const stream = await client.interactions.create({
- model: "gemini-3-flash-preview",
- input: "What is the greatest common divisor of 1071 and 462?",
- generation_config: {
- thinking_summaries: "auto",
- },
- stream: true,
- });
- for await (const event of stream) {
- if (event.event_type === "step.start") {
- console.log(`\n--- Step: ${event.step.type} ---`);
- } else if (event.event_type === "step.delta") {
- if (event.delta.type === "thought_summary") {
- if (event.delta.content.type === "text") {
- process.stdout.write(event.delta.content.text);
- }
- } else if (event.delta.type === "text") {
- process.stdout.write(event.delta.text);
- }
- }
- }
- curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
- -H "x-goog-api-key: $GEMINI_API_KEY" \
- -H "Content-Type: application/json" \
- --no-buffer \
- -d '{
- "model": "gemini-3-flash-preview",
- "input": "What is the greatest common divisor of 1071 and 462?",
- "stream": true,
- "generation_config": {
- "thinking_summaries": "auto"
- }
- }'
使用代理进行流式传输
Interactions API 支持 Deep Research 等智能体。代理使用 background=True 并异步返回结果,但您也可以流式传输代理互动,以便在互动发生时接收进度更新和中间步骤。如需了解详情,请参阅 后台执行指南 和 Deep Research 指南 。
- from google import genai
- client = genai.Client()
- stream = client.interactions.create(
- agent="deep-research-preview-04-2026",
- input="Research the latest advances in quantum computing.",
- stream=True,
- background=True,
- agent_config={
- "type": "deep-research",
- "thinking_summaries": "auto"
- }
- )
- for event in stream:
- if event.event_type == "step.start":
- print(f"\n--- Step: {event.step.type} ---")
- elif event.event_type == "step.delta":
- if event.delta.type == "text":
- print(event.delta.text, end="", flush=True)
- elif event.delta.type == "thought_summary":
- if event.delta.content.type == "text":
- print(event.delta.content.text, end="", flush=True)
- elif event.event_type == "interaction.completed":
- print(f"\n\nTotal Tokens: {event.interaction.usage.total_tokens}")
- import { GoogleGenAI } from "@google/genai";
- const client = new GoogleGenAI({});
- const stream = await client.interactions.create({
- agent: "deep-research-preview-04-2026",
- input: "Research the latest advances in quantum computing.",
- stream: true,
- background: true,
- agent_config: {
- type: "deep-research",
- thinking_summaries: "auto"
- }
- });
- for await (const event of stream) {
- if (event.event_type === "step.start") {
- console.log(`\n--- Step: ${event.step.type} ---`);
- } else if (event.event_type === "step.delta") {
- if (event.delta.type === "text") {
- process.stdout.write(event.delta.text);
- } else if (event.delta.type === "thought_summary") {
- if (event.delta.content.type === "text") {
- process.stdout.write(event.delta.content.text);
- }
- }
- } else if (event.event_type === "interaction.completed") {
- console.log(`\n\nTotal Tokens: ${event.interaction.usage.total_tokens}`);
- }
- }
- curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
- -H "x-goog-api-key: $GEMINI_API_KEY" \
- -H "Content-Type: application/json" \
- --no-buffer \
- -d '{
- "agent": "deep-research-preview-04-2026",
- "input": "Research the latest advances in quantum computing.",
- "stream": true,
- "background": true,
- "agent_config": {
- "type": "deep-research",
- "thinking_summaries": "auto"
- }
- }'
- event: interaction.created
- data: {"interaction":{"id":"v1_...","status":"in_progress","object":"interaction","agent":"deep-research-preview-04-2026"},"event_type":"interaction.created"}
- event: interaction.status_update
- data: {"interaction_id":"v1_...","status":"in_progress","event_type":"interaction.status_update"}
- event: step.start
- data: {"index":0,"step":{"type":"thought"},"event_type":"step.start"}
- event: step.delta
- data: {"index":0,"delta":{"content":{"text":"***Generating research plan***\n\nTo best answer your request, I'm starting by constructing a comprehensive research plan. This will outline the key areas I need to investigate and the strategy I'll use to connect them."},"type":"thought_summary"},"event_type":"step.delta"}
- ... (additional thought steps) ...
- event: step.stop
- data: {"index":0,"event_type":"step.stop"}
- event: step.start
- data: {"index":1,"step":{"type":"model_output"},"event_type":"step.start"}
- event: step.delta
- data: {"index":1,"delta":{"text":"# The Quantum Inflection Point: Exhaustive Analysis of Hardware, Algorithms, and Market Dynamics in 2026\n\n## Executive Summary\n\n..."},"event_type":"step.delta"}
- event: step.stop
- data: {"index":1,"event_type":"step.stop"}
- event: interaction.completed
- data: {"interaction":{"id":"v1_...","status":"completed","usage":{"total_tokens":1117031,"total_input_tokens":428865,"total_output_tokens":22294,"total_thought_tokens":26213},"created":"2026-05-12T17:24:27Z","updated":"2026-05-12T17:24:27Z","object":"interaction","agent":"deep-research-preview-04-2026"},"event_type":"interaction.completed"}
- event: done
- data: [DONE]
流式图片生成
Interactions API 支持同时以流式传输多种输出模态。通过在 response_format 中同时请求 text 和 image ,您可以在同一数据流中接收交织的文本和生成的图片。
以下示例使用 gemini-3.1-flash-image-preview (Nano Banana 2) 搜索信息并生成包含插图的故事。
- from google import genai
- client = genai.Client()
- stream = client.interactions.create(
- model="gemini-3.1-flash-image-preview",
- tools=[{"type": "google_search", "search_types": ["web_search", "image_search"]}],
- input="Search for the history of the Colosseum and write a short illustrated story about a gladiator named Marcus. Interleave text and generated images.",
- response_format=[
- {"type": "text"},
- {"type": "image"}
- ],
- stream=True,
- )
- for event in stream:
- if event.event_type == "step.delta":
- if event.delta.type == "text":
- print(event.delta.text, end="", flush=True)
- elif event.delta.type == "image":
- print(f"\n[Image chunk: {len(event.delta.data)} bytes]", end="", flush=True)
- import { GoogleGenAI } from "@google/genai";
- const client = new GoogleGenAI({});
- const stream = await client.interactions.create({
- model: "gemini-3.1-flash-image-preview",
- tools: [{ type: "google_search", search_types: ["web_search", "image_search"] }],
- input: "Search for the history of the Colosseum and write a short illustrated story about a gladiator named Marcus. Interleave text and generated images.",
- response_format: [
- { type: "text" },
- { type: "image" }
- ],
- stream: true,
- });
- for await (const event of stream) {
- if (event.event_type === "step.delta") {
- if (event.delta.type === "text") {
- process.stdout.write(event.delta.text);
- } else if (event.delta.type === "image") {
- console.log(`\n[Image chunk: ${event.delta.data.length} bytes]`);
- }
- }
- }
- curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
- -H "x-goog-api-key: $GEMINI_API_KEY" \
- -H "Content-Type: application/json" \
- --no-buffer \
- -d '{
- "model": "gemini-3.1-flash-image-preview",
- "input": "Search for the history of the Colosseum and write a short illustrated story about a gladiator named Marcus. Interleave text and generated images.",
- "stream": true,
- "tools": [
- { "type": "google_search",
- "search_types": ["web_search", "image_search"]
- }
- ],
- "generation_config": {
- "thinking_summaries": "auto"
- },
- "response_format": [
- { "type": "text" }, { "type": "image"}
- ]
- }'
- event: interaction.created
- data: {"interaction":{"id":"v1_...","status":"in_progress","object":"interaction","model":"gemini-3.1-flash-image-preview"},"event_type":"interaction.created"}
- event: interaction.status_update
- data: {"interaction_id":"v1_...","status":"in_progress","event_type":"interaction.status_update"}
- event: step.start
- data: {"index":0,"step":{"type":"model_output"},"event_type":"step.start"}
- event: step.delta
- data: {"index":0,"delta":{"text":"Here is a short illustrated story about the Colosseum...\n\n### Part 1: The New Flavian Amphitheater\n\n...","type":"text"},"event_type":"step.delta"}
- ...
- event: step.stop
- data: {"index":0,"event_type":"step.stop"}
- event: step.start
- data: {"index":1,"step":{"type":"thought"},"event_type":"step.start"}
- event: step.delta
- data: {"index":1,"delta":{"signature":"...","type":"thought_signature"},"event_type":"step.delta"}
- event: step.stop
- data: {"index":1,"event_type":"step.stop"}
- event: step.start
- data: {"index":2,"step":{"type":"model_output"},"event_type":"step.start"}
- event: step.delta
- data: {"index":2,"delta":{"mime_type":"image/jpeg","data":"/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAoHBwgHBgoICAgLCg...","type":"image"},"event_type":"step.delta"}
- event: step.delta
- data: {"index":2,"delta":{"text":"### Part 2: The Hypogeum and the Wait\n\n...","type":"text"},"event_type":"step.delta"}
- ...
- event: step.stop
- data: {"index":2,"event_type":"step.stop"}
- event: step.start
- data: {"index":3,"step":{"type":"thought"},"event_type":"step.start"}
- event: step.delta
- data: {"index":3,"delta":{"signature":"...","type":"thought_signature"},"event_type":"step.delta"}
- event: step.stop
- data: {"index":3,"event_type":"step.stop"}
- event: step.start
- data: {"index":4,"step":{"type":"model_output"},"event_type":"step.start"}
- event: step.delta
- data: {"index":4,"delta":{"mime_type":"image/jpeg","data":"/9j/4AAQSkZJRgABAQAAAQABAAD/...","type":"image"},"event_type":"step.delta"}
- event: step.delta
- data: {"index":4,"delta":{"text":"### Part 3: The Moment of Spectacle\n\n...","type":"text"},"event_type":"step.delta"}
- ...
- event: step.stop
- data: {"index":4,"event_type":"step.stop"}
- event: interaction.completed
- data: {"interaction":{"id":"v1_...","status":"completed","usage":{"total_tokens":6128,"total_input_tokens":29,"total_output_tokens":6099,"output_tokens_by_modality":[{"modality":"image","tokens":4480}]}},"event_type":"interaction.completed"}
- event: done
- data: [DONE]
处理未知事件
根据 API 的版本控制政策,随着时间的推移,可能会添加新的事件类型和增量类型。您的代码应妥善处理未知事件类型,记录并跳过任何无法识别的事件,而不是抛出错误。
后续步骤
· 详细了解 Interactions API 。
· 探索使用工具进行 函数调用 。
· 了解如何通过 思考 来增强推理能力。
· 对于长时间运行的任务,请尝试使用 Deep Research 代理 。
· 如需查看所有事件类型和增量类型,请参阅 Interactions API 参考文档 。