Gemini 工具组合:一次请求混用内置工具与自定义函数,模型自己排调用顺序

山止川行AI 前沿2026-09-18204 阅读💛 171 收藏

大多数真正能干活的智能体,一次任务里需要好几个工具配合。一个 DevOps 智能体发现了 CVE 漏洞,还需要顺手在内部系统里建一张工单。直到最近,这类交接要么得你自己写编排逻辑,要么只能在自定义工具里绕开内置工具。

Gemini API 的工具组合(tool combination)能力改变了这一点:现在可以在同一次请求里,把内置工具与自定义函数声明(function declarations)组合起来用。由 Gemini 自己决定调用哪些工具、按什么顺序调用,并在工具之间自动传递上下文。

下面是两个可以直接复现的工具组合示例。

示例一:函数调用与内置工具的组合

在同一个请求里组合 Google 搜索、URL 上下文读取和一个自定义函数。模型自己去网上搜索、读完页面、调用你的函数——全程不需要你指定顺序。

先准备环境:申请一个 Gemini API 密钥,然后安装官方 SDK:

pip install google-genai

接着定义一个自定义函数,把它与内置工具一起传入:

from google import genai

client = genai.Client()

file_incident = {
    "type": "function",
    "name": "file_incident",
    "description": "Files a security incident in the internal tracking system.",
    "parameters": {
        "type": "object",
        "properties": {
            "cve_id": {"type": "string", "description": "CVE identifier"},
            "severity": {"type": "string", "description": "Critical, High, Medium, or Low"},
            "summary": {"type": "string", "description": "Brief description of the vulnerability"},
        },
        "required": ["cve_id", "severity", "summary"],
    },
}

interaction = client.interactions.create(
    model="gemini-3-flash-preview",
    input="Search for the latest critical CVE affecting react, read the full advisory page, and file an incident for it.",
    tools=[
        {"type": "google_search"},
        {"type": "url_context"},
        {"type": "function", "name": "file_incident", "parameters": ...},
    ],
)

for output in interaction.outputs:
    print(f"{output.type}...")
    if output.type == "function_call":
        print(f"Function: {output.name}")
        print(f"Arguments: {output.arguments}")

运行这段代码,你会看到输出按顺序滚动:先是一轮 google_search_callgoogle_search_result,接着又是一轮搜索调用与结果,然后是一个 thought,最后是 function_call。模型自己完成了”搜索最新 React 严重漏洞 → 打开完整公告页读取细节 → 调用 file_incident 建工单”的全链条,函数收到的参数是结构化好的真实数据:CVE 编号 CVE-2025-55182、严重级别 Critical,以及一段从公告页提炼的漏洞摘要——React Server Components 的不安全反序列化漏洞,影响 19.0 到 19.2.0 版本,攻击者可通过构造 HTTP 请求执行任意代码。

这就是工具组合的实际价值:搜索结果和页面内容作为上下文自动流向了你的自定义函数,你写的只有函数声明本身。

动手验证时可以对比旧做法:先单独调一次搜索 API,把结果手工拼进第二次请求,再手动触发函数调用——三段编排代码,现在收敛为一次请求。在你的编程项目里粘贴上面代码,替换 file_incident 为你自己的业务函数(比如建客服工单、写数据库、发通知),跑一轮观察 output.type 的输出序列,就能确认模型确实在工具间自动流转上下文。

示例二:跨轮上下文传递

第二个能力是上下文循环(context circulation):内置工具的结果可以跨对话轮次保留。传入 previous_interaction_id,后续提问就能直接推理早前轮次的结果,不必重新执行工具。当然,如果模型需要新数据,它仍然可以发起新的工具调用。

from google import genai

client = genai.Client()

# 第一轮:URL 上下文工具读取 Philipp 的个人介绍页
turn1 = client.interactions.create(
    model="gemini-3-flash-preview",
    input="Who is Philipp Schmid? https://www.philschmid.de/philipp-schmid",
    tools=[{"type": "url_context"}],
)
print(turn1.outputs[-1].text)

# 第二轮:后续问题复用第一轮的上下文
turn2 = client.interactions.create(
    model="gemini-3-flash-preview",
    input="What is his twitter handle?",
    tools=[{"type": "url_context"}],
    previous_interaction_id=turn1.id,
)
print(turn2.outputs[-1].text)

第一轮让模型用 URL 上下文工具读一个网页并回答”这是谁”;第二轮只问”他的 Twitter 账号是什么”,不重新给 URL——因为 previous_interaction_id 把第一轮读取的页面内容带进来了,模型直接从已有上下文里答出账号,不再发起第二次页面抓取。省一次工具调用,也就省一次延迟和成本。

把这两个能力叠起来,就能搭出过去要写大量编排代码才能实现的智能体:多工具自动协作,加上跨轮记忆。编程实现时建议先在测试项目里跑通示例二(只有两轮、无自定义函数,最简单),确认 previous_interaction_id 生效后,再叠加示例一的混合工具声明,观察每一步的 output.type 序列,你会清楚看到模型在工具之间的自主调度路径。

原文信息

作者:Philipp Schmid(@_philschmid),AI 工程师

原文地址:

文章评论(9

墨沐雨50 分钟前

有没有更详细的教程,期待后续。

回复
空向阳38 分钟前

不错不错,已加入书签。

回复
逐光而行12 分钟前

看完了,收获满满,期待更多更新。

回复
星寻梦35 分钟前

内容翔实,正好需要,先收藏再看。

回复
星观澜13 分钟前

路过

回复
风倚栏47 分钟前

支持作者,持续关注中。

回复
晨沐雨5 分钟前

看完了,收获满满,期待更多更新。

回复
逐光而行刚刚

写得挺用心的,支持一下。

回复
空向阳43 分钟前

作者写得真不错,学到了不少。

回复