导读:本期聚焦于布兰登创作的《Gemini API Function Calling怎么用?自动函数选择机制详解与实践教程》,敬请观看详情。为什么Gemini API的Function Calling能让大模型主动调用你写好的外部函数?本文从函数声明的基本结构讲起,逐步演示如何用REST接口和SDK定义工具、发起请求、解析模型返回的functionCall字段,并深入分析自动函数选择机制——模型如何在多个候选函数中依据语义匹配度挑选最合适的那个。文中还包含并行调用、函数响应回传、强制指定函数调用等进阶技巧,以及参数校验失败、模型幻觉参数等常见问题的排查思路,帮助你快速把Gemini接入真实业务系统。

Function Calling是Gemini API最实用的能力之一:你在请求中描述一组自己写的函数,模型在对话过程中判断是否需要调用某个函数,并以结构化JSON的形式返回函数名和参数,由你的代码执行后再把结果回传给模型继续生成回答。整个过程里模型并不真正执行函数,它只负责决策与参数组织,执行权完全在你的服务端,这也是Function Calling安全性的核心设计。本文将完整讲解函数声明的写法、自动函数选择的内部逻辑,并给出可直接运行的代码示例。

Gemini API Function Calling怎么用?自动函数选择机制详解与实践教程

一、函数声明的基本结构与请求格式

要启用Function Calling,首先需要在请求的tools字段中声明可用函数。每个函数包含名称、描述和参数的JSON Schema定义。描述的质量直接决定自动函数选择的准确率,因为模型主要依靠语义理解来匹配用户意图,描述越清晰,误判越少。

下面是一个通过REST接口声明的完整请求示例,定义了获取天气和查询订单两个函数:

const requestBody = {
  contents: [{
    role: "user",
    parts: [{ text: "帮我查一下上海明天的天气" }]
  }],
  tools: [{
    functionDeclarations: [
      {
        name: "get_weather",
        description: "查询指定城市在指定日期的天气情况,包括温度、湿度、风力",
        parameters: {
          type: "OBJECT",
          properties: {
            city: { type: "STRING", description: "城市名称,例如:上海" },
            date: { type: "STRING", description: "日期,格式为yyyy-mm-dd" }
          },
          required: ["city"]
        }
      },
      {
        name: "get_order_status",
        description: "根据订单编号查询订单的当前状态和物流信息",
        parameters: {
          type: "OBJECT",
          properties: {
            order_id: { type: "STRING", description: "订单编号" }
          },
          required: ["order_id"]
        }
      }
    ]
  }]
};

// 发送请求
const response = await fetch(
  "https://generativelanguage.googleapis.com/v1beta/models/gemini-1.5-pro:generateContent",
  {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
      "x-goog-api-key": "你的API密钥"
    },
    body: JSON.stringify(requestBody)
  }
);
const data = await response.json();

当模型判断需要调用函数时,响应中不会直接返回文本,而是返回一个functionCall对象。它的结构大致如下:

{
  "candidates": [{
    "content": {
      "role": "model",
      "parts": [{
        "functionCall": {
          "name": "get_weather",
          "args": {
            "city": "上海",
            "date": "2025-06-10"
          }
        }
      }]
    }
  }]
}

注意几个细节:参数类型使用大写的OBJECTSTRINGNUMBER等Schema类型名;required数组指明必填参数,模型会尽量为必填参数生成值;如果用户输入缺少必要信息,模型有时会直接反问用户,而不是硬编造参数,这一点比多数同类模型表现更好。

二、自动函数选择机制是如何工作的

自动函数选择指的是模型在没有人工指定的情况下,自行决定调用哪个函数、是否调用函数。它的工作原理可以拆解为三步:第一步,模型对用户输入做语义解析,提取意图关键词;第二步,将解析结果与所有functionDeclarations的名称和描述做匹配度计算;第三步,选择匹配度最高的函数并按Schema组装参数。

理解这个机制对写好函数声明至关重要。例如用户说“我的包裹到哪了”,如果只有get_order_status一个函数,模型会自然选择它;但如果同时存在多个相似函数,比如又加了一个get_logistics_detail,模型的选择就可能出现摇摆。实践中推荐的做法是:让函数职责边界清晰,避免语义重叠;在描述中明确说明适用场景与不适用场景;必要时在函数名中体现业务语义。

模型的函数选择还支持并行调用。当用户一句话包含多个意图,比如“查一下上海天气,顺便看看订单12345的状态”,模型会返回多个functionCall片段:

{
  "candidates": [{
    "content": {
      "role": "model",
      "parts": [
        { "functionCall": { "name": "get_weather", "args": { "city": "上海" } } },
        { "functionCall": { "name": "get_order_status", "args": { "order_id": "12345" } } }
      ]
    }
  }]
}

处理这种响应时,你的代码要遍历所有parts,逐个执行函数并收集结果。另外,如果你希望模型不要自作主张选函数,Gemini提供了tool_configfunctionCallingConfig模式,可以设置为ANY强制调用指定函数,或设置为NONE完全禁用函数调用:

toolConfig: {
  functionCallingConfig: {
    mode: "ANY",          // 强制必须调用函数
    allowedFunctionNames: ["get_weather"]  // 只允许调用这个函数
  }
}

这个配置在构建确定性流程时非常有用,例如表单填写场景中,你明确知道下一步必须调用校验函数,就可以用ANY模式消除模型的不确定性。

三、执行函数并把结果回传给模型

拿到functionCall之后,真正执行函数的是你自己的代码。执行完毕后,需要把结果包装成functionResponse,连同历史消息一起回传给模型,模型才能基于真实数据生成最终回答。完整的循环流程是:用户提问、模型返回函数调用请求、代码执行函数、回传结果、模型生成自然语言回复。

下面是一个完整的Python示例,使用官方SDK实现整个闭环:

import google.generativeai as genai
import json

genai.configure(api_key="你的API密钥")

# 定义本地真实函数
def get_weather(city: str, date: str = None) -> dict:
    # 实际项目中这里调用天气服务接口
    return {"city": city, "date": date, "temp": "26度", "condition": "多云"}

model = genai.GenerativeModel(
    model_name="gemini-1.5-pro",
    tools=[{
        "function_declarations": [{
            "name": "get_weather",
            "description": "查询指定城市的天气情况",
            "parameters": {
                "type_": "OBJECT",
                "properties": {
                    "city": {"type_": "STRING", "description": "城市名称"}
                },
                "required": ["city"]
            }
        }]
    }]
)

chat = model.start_chat()
response = chat.send_message("上海今天天气怎么样?")

# 检查是否返回了函数调用
for part in response.parts:
    if fn := part.function_call:
        args = {k: v for k, v in fn.args.items()}
        result = get_weather(**args)
        # 把执行结果回传给模型
        response = chat.send_message({
            "function_response": {
                "name": fn.name,
                "response": result
            }
        })

print(response.text)

回传结果时有几个要点值得注意。functionResponse中的response字段必须是JSON对象,不能是纯字符串;如果函数执行失败,也应该返回一个包含错误信息的结构化对象,例如{"error": "城市名无法识别"},模型会据此向用户解释或重新发起调用,而不是让程序直接抛异常中断对话。

多轮对话中记得保留完整的消息历史。Gemini需要看到之前的functionCallfunctionResponse配对,才能理解上下文。如果只回传函数结果而不带上对应的调用记录,接口会报格式错误。

四、常见问题与排查思路

第一个常见问题是参数幻觉:模型给函数编造了不存在的参数值,比如用户没说日期,模型自己填了一个。解决办法是在参数描述里写明“如果用户未提供,不要猜测”,或者把该参数从required中移除,让模型学会在信息不足时反问用户。

第二个问题是模型选错函数。遇到这种情况,优先检查函数描述是否模糊、函数之间是否存在语义重叠。一个有效的技巧是在描述中加入具体触发例句,例如写上“当用户询问物流、快递、到货时间时使用本函数”,能显著提升选择准确率。

第三个问题是Schema类型不匹配。Gemini对枚举值支持enum字段,对嵌套对象支持properties嵌套定义,但对数组的items定义在不同版本中行为略有差异,建议先用简单类型跑通流程,再逐步增加复杂度。此外,所有Schema属性名要用驼峰式小写开头,type_在Python SDK中由于与关键字冲突需要加下划线。

最后一点关于安全:永远不要把函数执行的决策权交给模型而无校验。在真正执行前,务必对模型返回的参数做类型检查、范围校验和权限验证,尤其是涉及数据库写入、支付、文件操作的函数。Function Calling的架构设计本身就是“模型决策、代码执行”,把这个边界守住,就能在获得灵活性的同时保证系统安全。

Gemini APIFunction Calling自动函数选择修改时间:2026-09-01 07:34:58

免责声明:​ 已尽一切努力确保本网站所含信息的准确性。网站内容多为原创整理与精心编撰,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。