Gemini API 的函数调用(Function Calling)功能。它解决了传统大语言模型(LLM)的一个关键局限:LLM 本身是基于训练数据的“知识库”,擅长生成文本和回答问题,但无法直接执行代码、访问实时数据或操作外部系统。函数调用就是为LLM 装上“手脚”和“眼睛”,使其能够主动与外部世界交互。
https://ai.google.dev/gemini-api/docs/models?hl=zh-cn
函数调用的核心价值(Why Use It?)
函数调用解决了“纯文本生成”到“实际行动”的转变问题,并提炼了三大核心应用场景:
扩充知识 (Augmenting Knowledge):
- 痛点: LLM 的训练数据具有时效性和范围限制,无法获取最新信息或特定专有数据。
- 解决方案: 通过函数调用,模型可以查询:
- 数据库: 获取最新的用户信息、订单状态、库存等。
- API: 获取实时天气、股票行情、航班信息、新闻等。
- 知识库: 检索特定领域的专业知识库(如公司内部文档、行业报告)。
- 本质: 让模型拥有**“查资料”**的能力。
扩展功能 (Extending Capabilities):
- 痛点: LLM 本身不擅长执行精确计算、生成复杂图表或进行需要特定算法的操作。
- 解决方案: 通过函数调用,模型可以委托任务给外部工具:
- 计算引擎: 执行复杂的数学运算、统计分析。
- 可视化工具: 生成图表(折线图、饼图、柱状图)、数据可视化。
- 文件处理工具: 读取PDF、Excel,提取特定信息。
- 其他算法服务: 调用图像识别、语音合成等。
- 本质: 让模型拥有 “使用工具” 的能力。
执行操作 (Performing Actions):
- 痛点: LLM 不能直接改变外部世界的状态(如发送邮件、修改数据库记录)。
- 解决方案: 通过函数调用,模型可以触发操作:
- 日历/会议系统: 安排会议、发送邀请。
- 邮件系统: 发送通知邮件。
- CRM/ERP系统: 创建客户工单、更新订单状态、生成账单。
- IoT平台: 控制智能家居设备(开灯、调温)。
- 工作流引擎: 启动自动化流程。
- 本质: 让模型拥有 “做事” 的能力。
总结核心价值: 函数调用将LLM从“纸上谈兵”的参谋,变成了可以“真枪实弹”执行任务的智能代理(Agent),极大地扩展了AI应用的可能性和实用性。
技术原理深度解析 (How It Works)
函数调用的完整交互流程(共4步):
定义函数声明 (Function Declaration Definition):
- 开发者在应用代码中,使用特定的 JSON 格式(基于 OpenAPI Schema 子集) 来描述函数。
- 内容: 包括函数
name
,description
,parameters
(参数的类型type
、描述description
、是否必需required
,可选值enum
)。 - 目的: 告诉模型“这个函数叫什么?是干什么用的?需要什么信息?”。
- 关键点: 描述(
description
)的质量至关重要,直接影响模型理解何时调用和如何传参。
模型分析决策 (Model Analysis and Decision):
- 开发者将用户提示 (Prompt) 和 函数声明列表 (Tool Declarations) 一起发送给Gemini模型。
- 模型分析用户的请求意图。
- 模型判断是否需要调用函数(一个或多个)来满足用户请求。
- 如果决定调用,模型会返回一个结构化的函数调用请求 (Function Call Request),包含要调用的函数名(
name
)和计算好的参数值(args
)。模型不会执行代码,只负责生成调用指令。
执行函数代码 (Function Execution):
- 应用程序(开发者编写的后端代码)接收到模型的函数调用响应。
- 应用代码解析响应,提取出函数名和参数。
- 应用代码查找并调用本地定义的或连接到远程API的实际函数代码。
- 应用代码获取函数执行后的结果(或错误信息)。
- 关键点: 实际代码执行完全在开发者控制的应用环境中进行,模型不直接执行任何代码。
生成用户回答 (Generate Final Response):
- 应用程序将函数执行的结果(或错误信息)作为新的上下文信息,再次发送给Gemini模型(通常连同原始对话历史)。
- Gemini模型根据用户原始请求和函数调用的结果,生成自然、友好的最终文本回答,呈现给用户。
- 本质: 模型负责将“机器执行的结果”翻译成“人能理解的语言”。
交互模式扩展:
- 并行函数调用 (Parallel Function Calling): 模型可以在单次响应中要求调用多个函数。应用可以并行执行这些函数,提高效率(例如,同时查询天气和航班)。
- 组合式函数调用 (Compositional Function Calling): 模型可以按顺序调用多个函数,一个函数的结果作为下一个函数的输入,实现复杂工作流(例如,先查询用户信息,再用该信息发送邮件)。
- 多轮对话支持: 整个4步流程可以在一次对话中循环多次,实现更复杂的交互。
实际代码实现 (Code Implementation)
会议安排 (schedule_meeting
) 示例详细展示了代码流程:
定义函数声明 (
schedule_meeting_function
):- 使用Python字典结构定义JSON Schema。
- 包含
name
,description
, 参数properties
(attendees
,date
,time
,topic
) 及其type
,description
, 以及required
字段。 - 强调参数描述的清晰性(如
date
格式示例)。
配置客户端和工具 (
client
,tools
,config
):- 使用
genai.Client()
初始化Gemini API客户端。 - 将函数声明包装成
types.Tool
对象。 - 将工具列表放入
types.GenerateContentConfig
配置中,准备发送给API。
- 使用
发送请求 (
generate_content
):- 调用
client.models.generate_content
方法。 - 指定模型(如
gemini-2.5-flash
)。 - 提供用户提示内容(
"Schedule a meeting..."
)。 - 传入配置(
config
),其中包含工具定义。
- 调用
处理响应:
- 检查响应中是否存在
function_call
(response.candidates[0].content.parts[0].function_call
)。 - 如果存在,提取
function_call.name
和function_call.args
。 - 关键点(注释强调): 在实际应用中,这里会使用提取的参数调用真正的会议安排函数/API (
# result = schedule_meeting(**function_call.args)
)。示例中仅打印出来。 - 如果没有函数调用,则打印模型直接生成的文本回答 (
response.text
)。
- 检查响应中是否存在
函数声明规范详解:
name
: 唯一标识符。要求:描述性、无空格/特殊字符、推荐蛇形(schedule_meeting
)或驼峰(scheduleMeeting
)。description
: 极其重要! 清晰、详细说明函数用途、适用场景。使用具体示例(如“查找影院及上映电影”)。模型靠这个决定是否调用。parameters
: 嵌套对象。"type": "object"
: 表示参数是一个对象(包含多个属性)。properties
: 字典,定义每个参数的属性:type
: 数据类型 (string
,integer
,boolean
,array
等)。description
: 每个参数的清晰描述! 说明用途、格式要求、示例、限制(如“城市和州,‘加利福尼亚州旧金山’或邮编’95616’”)。enum
(可选): 当参数取值是有限集合时,强烈推荐使用enum
列出所有可能值(如["daylight", "cool", "warm"]
),比在描述中写更可靠。
required
: 数组,列出哪些参数是调用时必须提供的(如["attendees", "date", "time", "topic"]
)。
动态函数声明 (types.FunctionDeclaration.from_callable
):
- 一个方便的辅助方法。
- 允许开发者直接传入一个Python函数对象 (
your_function
)。 - API库会尝试自动解析该函数的签名(参数名、类型提示)和文档字符串 (
docstring
) 来生成函数声明。 - 好处: 简化开发流程,减少手动编写JSON Schema的工作量和错误。
- 注意点: 需要确保函数签名清晰,且
docstring
包含足够的信息(相当于description
和参数description
)。自动生成的效果依赖于函数定义的质量。
思考功能与上下文保持 (Thought Signature)
这部分解决了一个关键挑战:在无状态的API调用中如何保持多轮对话的连续性,特别是涉及需要多步推理的函数调用时。
- 思考功能 (Enable Thought Process):
- 开启后(通常是默认或推荐开启),模型在决定是否调用函数以及调用哪个函数、传递什么参数之前,会进行内部推理。
- 好处: 显著提高函数调用的准确性和质量,因为决策是基于更深入的上下文理解。
- 上下文丢失问题: Gemini API 本身是无状态 (Stateless) 的。每次
generate_content
调用都是独立的。模型内部的推理状态(思考过程)在请求结束后不会自动保留到下一次调用。这对于需要多轮交互才能完成的复杂函数调用任务(例如,分步骤收集信息再执行)是个问题。 - 思考签名 (Thought Signature):
- 是什么: 一个加密的字符串,代表了模型在当前轮次完成思考后内部状态的紧凑表示(快照)。
- 如何获取: 在
generate_content
的响应中提取 (response.thought_signature
)。 - 如何保持上下文: 在后续的
generate_content
请求中,开发者需要显式地将前一轮得到的thought_signature
作为参数 (thought_signature=previous_signature
) 传入。 - 作用: 告诉模型“请基于之前的思考状态继续”。这使得模型在后续请求中能回忆起之前的推理过程,从而实现跨轮次的上下文连贯性。
- 出现位置: 签名通常在模型完成思考后返回,可能在包含文本回答或函数调用建议的响应中。
模型支持情况 (Model Support)
不同Gemini模型对函数调用功能的支持差异:
- 关键功能:
- 函数调用: 基础功能,模型能理解函数声明、决定调用并返回调用请求。
- 并行函数调用: 模型能在单次响应中请求调用多个函数。
- 组合式函数调用: 模型能按顺序调用多个函数,构建工作流。
- 支持模型 (截至2025年7月):
- Gemini 2.5 Pro/Flash/Flash-Lite: 完全支持所有三个关键功能。
- Gemini 2.0 Flash: 支持函数调用和并行调用,但不支持组合式调用。
- Gemini 2.0 Flash-Lite: 完全不支持函数调用功能。
- 重要提示:
- 实验性模型未包含在表格中。
- 强烈建议开发者参考https://ai.google.dev/gemini-api/docs/models获取最新、最准确的功能支持信息,因为模型更新很快。
开发最佳实践 (Best Practices)
开发指导:
函数设计原则:
- 清晰详尽的描述:
description
和参数description
是模型的“使用说明书”,必须清晰、具体、无歧义,包含示例和限制条件。 - 描述性命名: 函数名
name
要能自解释其功能(如get_weather_forecast
,calculate_loan_payment
),避免模糊命名。 - 强类型定义: 明确指定参数
type
(string
,integer
,boolean
等) 和约束(如enum
列举选项),减少模型传参错误。优先使用enum
而非开放式描述。
- 清晰详尽的描述:
工具选择策略:
- 控制工具数量: 一次提供给模型的函数声明(工具)不宜过多(建议10-20个以内)。过多会增加模型选择错误工具或次优工具的风险,并消耗更多Token。
- 动态工具选择: 如果工具库很大,根据当前对话上下文动态筛选并只提供最相关的工具子集给模型。避免每次都提供全部工具。
提示工程技巧 (Prompt Engineering):
- 提供角色背景: 在系统提示(
system instruction
)中明确设定模型的角色和职责(如“你是一位乐于助人的天气助理”),引导其行为。 - 明确使用指令: 在提示中清晰说明模型应如何以及何时使用函数(如“不要猜测日期;始终使用未来的日期进行预测”、“在信息不足时主动询问用户澄清”)。
- 鼓励主动澄清: 指示模型在用户请求信息不足或模糊时,主动提出澄清性问题,而不是猜测或调用可能错误的函数。
- 提供角色背景: 在系统提示(
技术优化建议:
- 温度设置 (Temperature): 进行函数调用时,使用较低的温度值(如0或接近0)。这使模型的输出更确定性、可靠、可预测,减少随机性导致的错误调用。
- 关键操作验证: 对于会产生实际后果的操作(下单、发邮件、修改数据、付费操作等),在执行函数前,务必先向用户确认(例如,模型生成确认信息:“确认要发送邮件给XX吗?”)。
- 健壮的错误处理: 在应用执行的函数代码中实施严密的错误处理。处理意外输入、网络故障、API限流等问题,返回信息丰富的错误消息给模型,以便模型能向用户生成有用的错误说明。
- 安全考虑:
- API安全: 调用外部API时,使用安全的认证授权机制(API Keys, OAuth)。
- 数据安全: 避免在函数声明、提示或参数中暴露敏感信息(密码、密钥、个人身份信息)。
- 权限控制: 确保应用执行函数的权限是最小必要权限。
- Token 管理: 函数声明(特别是描述)会消耗输入Token。遇到Token限制时:
- 限制单次请求提供的工具数量。
- 简化函数和参数的描述(在保证清晰的前提下)。
- 将复杂任务分解为更小的、功能更聚焦的函数。
实际应用场景 (Use Cases)
典型场景,展示函数调用的强大潜力:
- 企业级应用:
- 智能办公助手: 集成日历(安排会议)、邮件(发送通知/摘要)、文档系统(检索/总结文档)、数据库(查询项目数据)。
- 智能客服: 连接CRM(查询客户信息/历史)、订单系统(查询状态/更新)、知识库(解答问题)、工单系统(创建/更新工单)。
- 数据分析平台: 调用数据库查询、可视化引擎(生成图表)、报表生成服务,根据自然语言指令生成洞察。
- 消费级应用:
- 智能家居控制: 通过IoT平台接口控制灯光、空调、电视、安防摄像头等设备。
- 个人财务管理: 连接银行API/记账App,分析支出、设定预算、提供储蓄/投资建议。
- 健康管理助手: 集成健康设备(读取数据)、医疗数据库(提供信息)、用药提醒服务。
展望 (Conclusion)
函数调用是AI应用发展的重要里程碑,使LLM从“知识提供者”转变为“任务执行者”。成功的关键在于:
- 深入理解用户需求。
- 精心设计函数接口(清晰描述、强类型)。
- 遵循最佳实践(控制工具、明确提示、优化配置)。
- 确保系统健壮安全(错误处理、验证、权限、安全)。
随着技术演进(模型能力提升、开发工具优化、生态扩展),函数调用将支持更多创新场景,构建真正智能的Agent型应用。
文本嵌入(Embedding)和重排序(Reranking)技术在自然语言处理和信息检索中的重要性。Qwen3 Embedding和ReRanker模型是基于Qwen3基础模型的密集版本开发,提供多种参数尺寸(0.6B、4B和8B),旨在通过高质量的嵌入捕捉语义关系,并通过有效的重排序机制优先展示相关结果。分为以下核心部分:
- 模型架构:描述Embedding和ReRanker的设计
- 训练方案:分三个阶段(弱监督预训练、有监督微调、模型合并)优化模型
- 实战代码:提供Python代码示例,展示如何加载模型和计算相似度
- 资源链接:技术报告和模型下载地址
- 推荐阅读:相关AI研究(如IBM的PDF处理工具、字节跳动的LangManus等)
2. 模型架构解析
Embedding模型和ReRanker模型共享基于Qwen3基础模型的架构,但针对不同任务优化。高质量的嵌入能捕捉文本间的语义关系,而重排序机制则确保检索结果的优先级。以下是关键细节:
Embedding模型
核心设计:使用带有因果注意力的语言模型(LLMs)。输入序列(查询q、文档d和指令i)被连接成一个单一上下文,末尾添加[EOS]令牌。嵌入值从最后一层对应[EOS]令牌的隐藏状态中提取。例如,给定查询“What is the capital of China?”和文档“The capital of China is Beijing.”,模型结合指令(如任务描述)生成输入上下文。
相似性计算:模型的输出是基于指令的相似性分数,通过计算[EOS]令牌的隐藏状态得出。余弦相似度(cosine similarity)用作相似性函数,公式为:
s(q,d)=cos(embedding(q),embedding(d)) s(q, d) = \cos(\text{embedding}(q), \text{embedding}(d)) s(q,d)=cos(embedding(q),embedding(d))
其中,指令i动态调整语义表示,提高不同下游任务的适用性。损失函数:采用改进的InfoNCE框架对比损失函数:
L=−logexp(s(q,d+)/τ)∑d′∈negativesexp(s(q,d′)/τ)+exp(s(q,d+)/τ) \mathcal{L} = -\log \frac{\exp(s(q, d^+) / \tau)}{\sum_{d' \in \text{negatives}} \exp(s(q, d') / \tau) + \exp(s(q, d^+) / \tau)} L=−log∑d′∈negativesexp(s(q,d′)/τ)+exp(s(q,d+)/τ)exp(s(q,d+)/τ)
这里,τ\tauτ是温度参数,用于平衡相似度分数;分母包括正样本对(d+d^+d+)和负样本对。动态Mask策略用于减少“伪负例”干扰(当批内样本与正例相似度过高时,将其相似度置零)。参数尺寸:提供0.6B、4B和8B三种尺寸,适合不同计算资源需求。8B版本尤其适合高精度任务。
展示输入上下文处理和嵌入提取流程。
ReRanker模型
核心设计:采用点式重排序策略,将文本相似性评估转化为二元分类问题(判断文档d是否满足查询q)。输入上下文包含指令i,并使用LLMs的聊天模板处理。例如,输入“Instruct: Retrieve relevant passages\nQuery: What is gravity?”时,模型输出概率判断文档是否相关。
损失函数:优化监督微调(SFT)损失函数,使用二分类交叉熵:
LSFT=−logP(label∣input) \mathcal{L}_{\text{SFT}} = -\log P(\text{label} | \text{input}) LSFT=−logP(label∣input)
其中,标签l为正文档时为“yes”,负文档时为“no”。这确保模型优先排序高相关性结果。优势:基于指令的嵌入方式使模型更灵活,适用于信息检索、语义相似度等多种任务。与Embedding模型共享基础架构,但输出层针对分类任务调整。
ReRanker模型没有单独的架构图,它与Embedding模型共享设计原则。
3. 训练方案解析
训练过程分三个阶段,旨在提升模型的泛化能力、精度和鲁棒性。合成数据和多阶段优化是关键创新点。以下是详细步骤:
Stage 1: 弱监督预训练(Weakly Supervised Pre-Training)
- 目标:利用大规模合成数据进行初始训练,增强模型的多任务适应性。
- 数据合成:将多语种文档转化为“查询-文档”对。过程包括:
- Configuration阶段:为每段文档分配角色(Character)、问题类型(Question_Type)、难度(Difficulty)。
- Query Generation阶段:基于配置生成用户角度的查询句(如角色为“学生”,生成教育相关查询)。
- 数据规模:约1.5亿对样本,覆盖信息检索、比对挖掘、分类和语义相似度等多种任务类型。
- 作用:预训练提升模型泛化能力,减少对标注数据的依赖。
Stage 2: 有监督微调(Supervised Fine-Tuning)
- 目标:在弱监督模型基础上,用高质量数据进一步提升性能。
- 数据处理:从1.5亿合成数据中筛选余弦相似度大于0.7的高质量样本,约1200万对。
- 微调方法:
- Embedding模型:沿用InfoNCE损失函数进行微调。
- ReRanker模型:直接使用二分类交叉熵损失。
- 优势:小规模但高质量的数据精调模型,提高任务特定性能(如检索精度)。
Stage 3: 模型合并(Model Merging)
- 目标:提高模型鲁棒性和稳健性。
- 方法:通过球面线性插值(slerp)技术合并多个检查点(checkpoints)。slerp在参数空间中平滑插值不同模型权重,生成“混合”模型。
- 例如,合并不同训练阶段或任务偏好的模型,减少过拟合风险。
- 效果:增强模型在多样化数据上的表现,尤其适合实际部署环境。
展示三阶段流程。
提供Python代码示例,展示如何加载模型、计算嵌入和相似度分数。以下是关键步骤解析(基于Qwen/Qwen3-Embedding-8B模型):
代码概述
- 环境依赖:使用PyTorch和ModelScope库。
- 核心函数:
last_token_pool
: 从最后隐藏状态提取[EOS]令牌嵌入。get_detailed_instruct
: 生成任务指令的详细字符串。tokenize
: 处理输入文本,添加[EOS]令牌并填充。
- 流程:
- 定义任务和查询(例如:“Given a web search query, retrieve relevant passages that answer the query”)。
- 加载tokenizer和模型(推荐启用flash_attention_2加速)。
- Tokenize查询和文档,并计算嵌入。
- 归一化嵌入并计算余弦相似度分数。
示例代码
import torch
import torch.nn.functional as F
from torch import Tensor
from modelscope import AutoTokenizer, AutoModel
# 定义函数:提取[EOS]令牌嵌入
def last_token_pool(last_hidden_states: Tensor, attention_mask: Tensor) -> Tensor:
# 实现细节(略)
return embeddings
# 定义函数:生成指令字符串
def get_detailed_instruct(task_description: str, query: str) -> str:
return f'Instruct: {task_description}\nQuery:{query}'
# 定义函数:Tokenize输入
def tokenize(tokenizer, input_texts, eod_id, max_length):
# 实现细节(略)
return batch_dict
# 示例使用
task = 'Given a web search query, retrieve relevant passages that answer the query'
queries = [
get_detailed_instruct(task, 'What is the capital of China?'),
get_detailed_instruct(task, 'Explain gravity')
]
documents = [
"The capital of China is Beijing.",
"Gravity is a force that attracts two bodies towards each other..."
]
input_texts = queries + documents
tokenizer = AutoTokenizer.from_pretrained('Qwen/Qwen3-Embedding-8B', padding_side='left')
model = AutoModel.from_pretrained('Qwen/Qwen3-Embedding-8B') # 推荐添加 attn_implementation="flash_attention_2" 加速
eod_id = tokenizer.convert_tokens_to_ids("<|endoftext|>")
max_length = 8192
batch_dict = tokenize(tokenizer, input_texts, eod_id, max_length)
batch_dict.to(model.device)
outputs = model(**batch_dict)
embeddings = last_token_pool(outputs.last_hidden_state, batch_dict['attention_mask'])
embeddings = F.normalize(embeddings, p=2, dim=1) # 归一化嵌入
scores = (embeddings[:2] @ embeddings[2:].T) # 计算相似度矩阵
print(scores.tolist()) # 输出分数
输出解释
代码输出一个相似度矩阵(scores),其中行对应查询,列对应文档。例如,查询“What is the capital of China?”与文档“The capital of China is Beijing.”的相似度较高。
实战建议:模型支持长上下文(max_length=8192),适用于大规模检索任务。启用flash_attention_2可提升性能。
技术报告:详细模型设计和实验结果:https://github.com/QwenLM/Qwen3-Embedding/blob/main/qwen3_embedding_technical_report.pdf
模型下载:
- Embedding模型:https://modelscope.cn/collections/Qwen3-Embedding-3edc3762d50f48
- ReRanker模型:https://modelscope.cn/collections/Qwen3-Reranker-6316e71b146c4f
推荐阅读:文档末尾列出相关AI研究(如IBM的PDF处理工具、字节跳动的LangManus、港中大的GraphRAG等),这些内容强化了Qwen3模型在实际应用中的价值。
Qwen3 Embedding和ReRanker模型通过创新的架构(基于指令的嵌入和重排序)和三阶段训练方案(弱监督预训练、有监督微调、模型合并),显著提升了文本检索的准确性和效率。实战代码展示了易用性,资源链接便于深入探索。如果您有具体任务(如部署模型或处理特定文档),请提供更多细节,我可以进一步协助!
https://mp.weixin.qq.com/s/o5WiSYa7hKz1jRB6oR6LVw
https://mp.weixin.qq.com/s/7JrYaMdJMMOaz04_e4BSyg