第 2 课
多轮对话与工具:previous_interaction_id + google_search
用 previous_interaction_id 做服务端多轮;挂 Google Search 工具并读 citations;附官方 function calling 最小循环骨架。
课程目录第 2 / 2 课
学习位置仅保存在当前浏览器,有效期 180 天。
图文讲义
来源:Google AI · Getting started — Multi-turn / Tools / Function calling、Interactions overview。本讲义为中文跟做整理,非原文搬运。
你将得到什么
- 用
previous_interaction_id完成一轮「服务端记历史」的多轮对话(官方推荐的 stateful 方式) - 给 Interaction 挂上
tools=[{"type": "google_search"}],读出带 URL citation 的回答 - 看懂官方 function calling 最小循环骨架(声明函数 → 模型
function_call→ 本地执行 →function_result回传)
本课默认你已完成上一课:环境里有 GEMINI_API_KEY,且 from google import genai 可用。
步骤 1:服务端多轮(stateful,推荐)
官方说明:Interactions API 支持两种多轮方式——
| 方式 | 做法 | 适用 |
|---|---|---|
| Stateful(推荐) | 下一请求带 previous_interaction_id | 聊天、Agent;服务端管历史与缓存 |
| Stateless | 每次自带完整 history,并设 store=False | 你要自己管存储 / 合规落盘时 |
先跑官方推荐的 stateful 示例。新建 multi_turn.py:
from google import genai
client = genai.Client()
interaction1 = client.interactions.create(
model="gemini-3.8-flash",
input="I have 2 dogs in my house.",
)
print("Response 1:", interaction1.output_text)
print("id1=", interaction1.id)
interaction2 = client.interactions.create(
model="gemini-3.8-flash",
input="How many paws are in my house?",
previous_interaction_id=interaction1.id,
)
print("Response 2:", interaction2.output_text)
print("status2=", interaction2.status)
运行:
python multi_turn.py
对照结果:
| 项 | 期望 |
|---|---|
| Response 1 | 确认或复述「家里有 2 只狗」类回复(措辞可变) |
id1 | 非空;复制给第二请求 |
| Response 2 | 应推出 8 只爪子(2×4);若答成「不知道」或无关数字,检查是否漏传 previous_interaction_id |
status2 | completed |
等价 curl(与官方 REST 一致;需 jq):
RESPONSE1=$(curl -sS -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gemini-3.8-flash",
"input": "I have 2 dogs in my house."
}')
INTERACTION_ID=$(echo "$RESPONSE1" | jq -r '.id')
echo "Interaction 1 ID: $INTERACTION_ID"
curl -sS -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-d "{
\"model\": \"gemini-3.8-flash\",
\"input\": \"How many paws are in my house?\",
\"previous_interaction_id\": \"$INTERACTION_ID\"
}" | jq -r '.status, (.steps[] | select(.type=="model_output") | .content[]? | select(.type=="text") | .text)'
对照结果:先打印非空 Interaction 1 ID;第二段应出现 completed 与包含 8 的文本。
何时用 Stateless?
若你必须在客户端持有完整历史:设 store=False,并把上一轮返回的 全部 steps(含 thought、function_call 等)原样塞回下一轮 input。官方警告:漏步骤或改写模型步骤会导致上下文错误。本课验收以 stateful 为准即可;完整 Stateless 示例见官方 Getting Started「Stateless」小节。
步骤 2:Google Search 工具(grounding)
官方:把 Google Search 作为内置工具传入,API 会自行搜索、合成答案,并在文本上带 url_citation 注解。
新建 search_tool.py:
from google import genai
client = genai.Client()
interaction = client.interactions.create(
model="gemini-3.8-flash",
input="Who won the euro 2024?",
tools=[{"type": "google_search"}],
)
print(interaction.output_text)
print("\nCitations:")
for step in interaction.steps:
if step.type == "model_output":
for content_block in step.content:
if getattr(content_block, "type", None) == "text" and getattr(
content_block, "annotations", None
):
for annotation in content_block.annotations:
if getattr(annotation, "type", None) == "url_citation":
title = getattr(annotation, "title", "")
url = getattr(annotation, "url", "")
print(f" [{title}]({url})")
运行:
python search_tool.py
对照结果:
| 项 | 期望 |
|---|---|
| 正文 | 应提到 Spain / 西班牙 夺冠(Euro 2024;措辞可变) |
steps | REST/SDK 中可能出现 google_search_call / google_search_result 等中间步(有则属正常) |
| Citations | 至少 0~多条 URL;有则打印为 [title](url)。若暂时无 annotation,只要正文事实正确也算本步通过;可换更时效的问题再试 |
curl 版:
curl -sS -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gemini-3.8-flash",
"input": "Who won the euro 2024?",
"tools": [{"type": "google_search"}]
}' | tee /tmp/gemini-search.json | jq -r '.status, (.steps[]? | select(.type=="model_output") | .content[]? | select(.type=="text") | .text)'
对照结果:status 为 completed,正文含西班牙夺冠信息。
其它官方内置工具(本课不逐一跟做,入口在同一 Getting Started):Code execution、URL context、File search、Google Maps 等。
步骤 3:Function calling 最小循环(跟做骨架)
目标:让模型决定调用你声明的本地函数,你执行后再把结果送回,拿到最终自然语言答案。官方示例函数名:get_current_temperature。
新建 function_call_loop.py:
import json
from google import genai
client = genai.Client()
weather_tool = {
"type": "function",
"name": "get_current_temperature",
"description": "Gets the current temperature for a given location.",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The city name, e.g. San Francisco",
},
},
"required": ["location"],
},
}
available_functions = {
"get_current_temperature": lambda location: {
"location": location,
"temperature": "22",
"unit": "celsius",
},
}
user_input = "What is the temperature in London?"
previous_id = None
while True:
interaction = client.interactions.create(
model="gemini-3.8-flash",
input=user_input,
tools=[weather_tool],
previous_interaction_id=previous_id,
)
function_results = []
for step in interaction.steps:
if step.type == "function_call":
result = available_functions[step.name](**step.arguments)
print(f"Called {step.name}({step.arguments}) → {result}")
function_results.append(
{
"type": "function_result",
"name": step.name,
"call_id": step.id,
"result": [{"type": "text", "text": json.dumps(result)}],
}
)
if not function_results:
break
user_input = function_results
previous_id = interaction.id
print(interaction.output_text)
print("final_status=", interaction.status)
运行:
python function_call_loop.py
对照结果:
- 第一轮循环通常打印类似:
Called get_current_temperature({'location': 'London'}) → {...}(此时 interaction 在 REST 语义上可能是requires_action)。 - 回传
function_result后循环结束,最终output_text应提到 22°C / 22 摄氏度 与 London。 final_status为completed。
若模型没有发出 function_call:检查 tools 是否传入、描述是否清晰;可把问句改成更明确的 “Call the tool to get London temperature”。
步骤 4(了解即可):后台任务与托管 Agent
官方同一页还提供:
background=True:立即返回in_progress,再用client.interactions.get(id)轮询到completed/failed。- Managed agent:传
agent=...与environment="remote"(示例 agent 名以官方页当前值为准,如文档中的 preview agent),在远端沙箱跑代码与文件任务。
本课不强制跑通这两项;需要长任务或远端沙箱时,回到 Getting started 第 10–11 节按官方示例复制即可。
本课检查清单
- stateful 多轮第二问能推出「8 只爪子」
-
google_search对 Euro 2024 问句返回合理正文(最好带 citations) - function calling 循环至少完成一次本地函数调用并打印最终温度回答
延伸阅读(官方)
- Interactions overview
- Gemini API docs 首页(Interactions 已为默认推荐)
- 旧版对照:generateContent quickstart(legacy,新项目勿优先)
恭喜:你已用官方当前默认接口跑通 首调 → 多轮 → 搜索工具 → 函数调用骨架。把 GEMINI_API_KEY 继续留在环境变量或密钥管理里,不要写进代码仓库。
