Search Grounding 教程:使用 Gemini API 进行搜索接地

本教程面向有编程基础的开发者,深入讲解如何使用 Gemini API 的 Google 搜索工具实现搜索接地。通过一元 API 和多模态实时 API 的示例,展示如何获取实时信息、进行多轮对话、结合代码生成与绘图,以及将搜索工具与自定义函数调用结合。教程涵盖环境配置、核心原理、架构设计、常见错误排查及生产环境优化建议,帮助开发者构建可靠、高效的 AI 应用。

技术背景

大型语言模型(LLM)的知识截止日期导致其无法提供实时或最新信息,这在处理新闻、体育赛事、股票价格等动态数据时成为严重缺陷。搜索接地(Search Grounding)通过将模型与 Google 搜索集成,使模型能够访问近乎实时的外部信息,从而生成更准确、更权威的响应。该技术适用于需要最新信息的场景,如问答、新闻摘要、市场分析等。主要限制包括依赖外部搜索服务、可能引入延迟、以及需要处理搜索结果的可靠性和相关性。

核心原理

搜索接地的核心原理是在模型生成响应时,将用户查询作为搜索查询发送到 Google 搜索,获取相关网页内容,并将这些内容作为上下文提供给模型。模型基于这些上下文生成最终响应,并可能引用来源。在 Gemini API 中,通过 tools 参数指定 google_search 工具,模型会在需要时自动触发搜索。数据流为:用户输入 -> 模型判断是否需要搜索 -> 调用搜索工具 -> 获取搜索结果 -> 模型结合搜索结果生成响应。关键设计决策包括:模型自主决定是否搜索,以及如何整合搜索结果。

架构分析

系统架构涉及多个组件:客户端(如 Python SDK)、Gemini 模型、Google 搜索服务。在代码中,client.interactions.create 是核心入口,通过 tools 参数启用搜索。响应包含 steps 列表,其中 model_output 步骤包含最终文本。对于多模态实时 API,使用 client.aio.live.connect 建立双向流,支持音频和工具调用。设计思想是模块化:搜索工具作为可插拔组件,可与自定义函数调用结合,实现复杂任务。

完整实战教程

##### 版权所有 2026 Google LLC.

#@title Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

使用搜索作为工具进行接地

在本笔记本中,你将学习如何使用 Gemini 模型中新增的 Google 搜索工具,既可以使用一元 API,也可以使用多模态实时 API。请查阅文档,了解有关将搜索作为工具的更多信息。

请注意,本指南的先前版本(使用 Gemini 2.0 之前的模型和旧版 SDK)仍可在此处找到。

注意: 本笔记本使用 Interactions API,这是与 Gemini 模型交互的最新方式。正在寻找 generateContent 版本?请查看 存档分支。

设置 SDK 和客户端

安装 SDK

本指南使用 google-genai Python SDK 连接到 Gemini 模型。

你可以在文档或入门笔记本中找到有关 SDK 的更多详细信息。

%pip install -U -q "google-genai>=2.9.0"  # 2.0 for Interactions API

设置你的 API 密钥

要运行以下单元格,你的 API 密钥必须存储在名为 GEMINI_API_KEY 的 Colab 密钥中。如果你还没有 API 密钥,或者不确定如何创建 Colab 密钥,请参阅 身份验证 获取详细步骤。

import os
from google.colab import userdata

os.environ['GEMINI_API_KEY'] = userdata.get('GEMINI_API_KEY')

选择您在本指南中要使用的模型:

from google import genai

client = genai.Client() # the API key is automatically loaded from the environment variable

MODEL_ID = "gemini-3.7-flash" # @param ["gemini-3.1-pro-preview", "gemini-3.7-flash", "gemini-3.5-flash-lite", "gemini-2.5-pro"] {"allow-input":true, isTemplate: true}

使用 Google 搜索

搜索接地对于需要当前信息或外部知识的查询特别有用。通过使用 Google 搜索,Gemini 可以访问近乎实时的信息并提供更好的响应。

interactions.create 的响应包含一个 steps 列表。对于文本响应,通过 interaction.steps[-1].content[0].text 访问输出。
from IPython.display import display, HTML, Markdown

interaction = client.interactions.create(
    model=MODEL_ID,
    input='What was the latest Indian Premier League match and who won?',
    tools=[{"type": "google_search"}],
)

# Print the text response
model_step = next((s for s in interaction.steps if s.type == "model_output"), None)
if model_step:
    display(Markdown(model_step.content[0].text))

所提供的信息可能已过时,因为它基于知识截止日期。有关最新且权威的详细信息,请参阅官方模型文档,其中包含最新的知识截止日期。

您可以看到,在没有搜索接地的情况下运行相同的提示会得到过时的信息:

from IPython.display import display, Markdown

interaction = client.interactions.create(
    model=MODEL_ID,
    input='What was the latest Indian Premier League match and who won?',
)

# Print the response
text_output = next((o for o in interaction.steps if o.type == "model_output"), None)
if text_output:
    display(Markdown(text_output.content[0].text))

在聊天中使用搜索

首先定义一个辅助函数,用于显示返回响应的每个部分。

# @title Define some helpers (run this cell)
import json

from IPython.display import display, HTML, Markdown


def show_json(obj):
  print(json.dumps(obj.model_dump(exclude_none=True), indent=2))

def show_parts(r):
  parts = r.candidates[0].content.parts
  if parts is None:
    finish_reason = r.candidates[0].finish_reason
    print(f'{finish_reason=}')
    return
  for part in r.candidates[0].content.parts:
    if part.text:
      display(Markdown(part.text))
    elif part.executable_code:
      display(Markdown(f'```python\n{part.executable_code.code}\n```'))
    else:
      show_json(part)

  grounding_metadata = r.candidates[0].grounding_metadata
  if grounding_metadata and grounding_metadata.search_entry_point:
    display(HTML(grounding_metadata.search_entry_point.rendered_content))

首先尝试一个需要实时信息的查询,这样你可以看到模型在_没有_Google搜索的情况下的表现。

turn_1 = client.interactions.create(
    model=MODEL_ID,
    input='Who won the most recent Australian Open?',
)

text_output = next((o for o in turn_1.steps if o.type == "model_output"), None)
if text_output:
    display(Markdown(text_output.content[0].text))

现在设置一个新的聊天会话,使用 google_search 工具。show_parts 辅助函数将显示文本输出以及结果中使用的任何 Google 搜索查询。

search_turn_1 = client.interactions.create(
    model=MODEL_ID,
    input='Who won the most recent Australian Open?',
    tools=[{"type": "google_search"}],
)

for step in search_turn_1.steps:
    if step.type == "model_output":
        display(Markdown(step.content[0].text))

由于你使用的是 chat 会话,你也可以向模型提出后续问题。

search_turn_2 = client.interactions.create(
    model=MODEL_ID,
    input='Who scored the goals?',
    previous_interaction_id=search_turn_1.id,
    tools=[{"type": "google_search"}],
)

for step in search_turn_2.steps:
    if step.type == "model_output":
        display(Markdown(step.content[0].text))

绘制搜索结果

在这个例子中,你可以看到如何结合代码生成使用Google搜索工具来绘制结果。

movie_turn_1 = client.interactions.create(
    model=MODEL_ID,
    input='Search the web and list the top 5 grossing movies in 2024 and their worldwide revenue in USD? Also provide the code to plot this as a bar chart using matplotlib.',
    tools=[{"type": "google_search"}],
)

for step in movie_turn_1.steps:
    if step.type == "model_output":
        display(Markdown(step.content[0].text))

首先检查提供的代码,确保其行为符合预期,然后将其复制到这里来尝试图表。

import re

text = next((step.content[0].text for step in movie_turn_1.steps if step.type == "model_output"), "")
matchFound = re.search(r"python\n(.*?)```", text, re.DOTALL)
print(matchFound.group(1))

使用聊天对话进行此操作的一个特点是,你现在可以要求模型进行修改。

movie_turn_2 = client.interactions.create(
    model=MODEL_ID,
    input='Looks great! Can you give the chart a dark theme instead?',
    previous_interaction_id=movie_turn_1.id,
    tools=[{"type": "google_search"}],
)

for step in movie_turn_2.steps:
    if step.type == "model_output":
        display(Markdown(step.content[0].text))

同样,在运行模型生成的代码之前,请务必仔细审查。

import re

text = next((step.content[0].text for step in movie_turn_2.steps if step.type == "model_output"), "")
matchFound = re.search(r"python\n(.*?)```", text, re.DOTALL)

if matchFound:
    code = matchFound.group(1)
    exec(code)

在多模态实时 API 中使用搜索

搜索工具可以在实时流式传输环境中使用,让模型在对话过程中生成有依据的响应。

LIVE_MODEL_ID = 'gemini-2.5-flash-native-audio-preview-09-2025'  # @param ['gemini-2.5-flash-native-audio-preview-09-2025', 'gemini-live-2.5-flash-preview', 'gemini-2.0-flash-live-001'] {allow-input: true, isTemplate: true}

定义一些辅助函数

为了在 Colab 中使用双向流式 API,你需要缓冲音频流。定义一个 play_response 辅助函数来执行缓冲,并在当前回合的音频播放完成后显示 IPython 音频控件。

由于以下每个示例仅使用单个提示,因此还需定义一个 run 辅助函数,将设置和提示执行步骤封装为单个函数调用。该辅助函数接受一个 config 参数,该参数将添加到 generation_config 中,以便你可以在示例之间切换 Search 工具。

# @title Helper functions for the Live API (run this cell)

import asyncio
import io
import json
import re
import time
import wave

import numpy as np
from IPython.display import Audio, display


DEFAULT_OUTPUT_RATE = 24000
BASE_MODEL_CONFIG = {
    # Here you can change the model's output mode between either audio or text.
    # While this code expects an audio stream, text should work, but the stream
    # may interleave with the `Buffering....` text.
    'response_modalities': ['AUDIO']
}

async def play_response(stream):
  """Buffer audio output and display a widget. Returns the streamed responses."""
  turn_buf = io.BytesIO()
  sample_rate = DEFAULT_OUTPUT_RATE

  all_responses = []

  print('Buffering', end='')
  async for msg in stream.receive():
    all_responses.append(msg)

    if audio_data := msg.data:  # This is what triggers the warnings, use the full path to access the audio data
      turn_buf.write(audio_data)
      if m := re.search(
          r'rate=(?P<rate>\d+)',
          msg.server_content.model_turn.parts[0].inline_data.mime_type
      ):
            sample_rate = int(m.group('rate'))

    elif tool_call := msg.tool_call:
      # Handle tool-call requests. Here is where you would implement
      # custom tool code, but for this example, all tools respond 'ok'.
      for fc in tool_call.function_calls:
        print('Tool call', end='')
        tool_response = genai.types.LiveClientToolResponse(
            function_responses=[genai.types.FunctionResponse(
                name=fc.name,
                id=fc.id,
                response={'result': 'ok'},
            )]
        )
        await stream.send(input=tool_response)

    print('.', end='')

  print()

  # Play the audio
  if turn_buf.tell():
    audio = np.frombuffer(turn_buf.getvalue(), dtype=np.int16)
    display(Audio(audio, autoplay=True, rate=sample_rate))
  else:
    print('No audio :(')
    print(f'  {len(all_responses)=}')

  return all_responses


async def run(query, config=None):
  # Add any tools or other generation config.
  config = BASE_MODEL_CONFIG | (config or {})

  # Establish a live session. While this context manager is active, the
  # conversation will continue.
  async with client.aio.live.connect(model=LIVE_MODEL_ID, config=config) as strm:

    # Send the prompt.
    await strm.send(input=query, end_of_turn=True)
    # Handle the model response.
    responses = await play_response(strm)

    return responses

使用 Search 工具进行流式传输

首先,在不使用 Search 工具的情况下执行一个查询,以观察模型对时间敏感查询的响应。

请注意,Multimodal Live API 是一个双向流式 API,但为了简化在笔记本中的运行,每个音频响应都会被缓冲,并在完全流式传输后播放,因此您需要等待几秒钟才能开始播放响应。

await run('Who won the skateboarding gold medals in the 2024 olympics?');

现在重新运行,并启用搜索工具。

search_tool = {"type": "google_search"}

responses = await run('Who won the skateboarding gold medals in the 2024 olympics?', {'tools': [search_tool]})

如果你想查看返回的完整输出,可以在此处启用 show_output 并运行此单元格。它包含完整的音频二进制数据,因此默认情况下处于关闭状态。

show_output = False

if show_output:
  for msg in responses:
    print(msg.model_dump(exclude_none=True))

使用自定义工具进行搜索

在 Multimodal Live API 中,Search 工具可以与其他工具结合使用,包括你提供给模型的函数调用。

在此示例中,你定义了一个函数 set_climate,它接受两个参数:mode(hot、cold 等)和 strength(0-10),并要求模型根据你指定位置的实时天气来设置气候控制。

set_climate_tool = {
    "type": "function",
    "name": "set_climate",
    "description": "Switches the local climate control equipment to the specified parameters.",
    "parameters": {
        "type": "object",
        "properties": {
            "mode": {
                "type": "string",
                "enum": ["hot", "cold", "fan", "off"],
                "description": "Mode for the climate unit - whether to heat, cool or just blow air.",
            },
            "strength": {
                "type": "integer",
                "description": "Intensity of the climate to apply, 0-10 (0 is off, 10 is MAX).",
            },
        },
    },
}

search_tool = {"type": "google_search"}

tools = [search_tool, set_climate_tool]

responses = await run("Look up the weather in Paris using search and set my climate control appropriately. I trust your judgement, so just do it.", {'tools': tools})

现在检查对话期间收到的 tool_call 响应。

for r in responses:
  if tool := r.tool_call:
    for fn in tool.function_calls:
      args = ', '.join(f'{k}={v}' for k, v in fn.arguments.items())
      print(f'{fn.name}({args})  # id={fn.id}')

后续步骤

<a name="next_steps"></a>

搜索接地并不是为请求接地的唯一方式,你还可以使用 YouTube 链接和 URL 上下文。查看 Grounding 指南以了解这些功能的更多信息。

* 如需更多展示多工具在 Multimodal Live API 中使用的演示,请查看 绘图和地图绘制 cookbook。

* 如需通过 Python SDK 开始使用 Live API,请查看 入门指南。

* 如需了解 Live API 中工具使用的更多信息,请查看 Live API 工具使用 cookbook。

还可以查看 Gemini 的其他高级功能(如 空间理解),你可以在 Gemini Cookbook 中找到。

常见问题

常见错误包括:API 密钥未正确设置导致认证失败;模型 ID 不存在或不可用;未启用搜索工具导致响应过时;在实时 API 中未正确处理工具调用响应。排查方法:检查环境变量 GEMINI_API_KEY 是否设置;确认模型 ID 拼写正确;在请求中明确包含 tools=[{"type": "google_search"}];在实时 API 中,确保处理 tool_call 消息并发送响应。生产环境优化:使用缓存减少搜索调用;设置超时和重试机制;监控搜索成本;对搜索结果进行过滤和验证。

企业应用扩展

搜索接地可与其他功能结合:与代码生成结合,实现数据可视化;与自定义函数调用结合,实现基于实时数据的决策;与多模态实时 API 结合,实现语音交互。此外,还可探索 YouTube 链接和 URL 上下文作为接地方式。开发者可参考官方文档和 Cookbook 中的更多示例,如绘图和地图绘制、空间理解等高级功能。

总结

本教程面向有编程基础的开发者,深入讲解如何使用 Gemini API 的 Google 搜索工具实现搜索接地。通过一元 API 和多模态实时 API 的示例,展示如何获取实时信息、进行多轮对话、结合代码生成与绘图,以及将搜索工具与自定义函数调用结合。教程涵盖环境配置、核心原理、架构设计、常见错误排查及生产环境优化建议,帮助开发者构建可靠、高效的 AI 应用。

内容来源与验证

继续系统学习

站内还有更多完整实战教程

加入会员,解锁全部教程、完整代码与持续更新内容。

加入会员
查看全部RAG 与知识库教程