借助函数调用,您可以将模型连接到外部工具和 API。 模型不会生成文本回答,而是确定何时调用特定函数,并提供执行实际操作所需的参数。这使得模型能够充当自然语言与实际操作和数据之间的桥梁。函数调用有 3 个主要应用场景:
- 扩充知识:从数据库、API 和知识库等外部来源获取信息。
- 扩展功能:使用外部工具执行计算,并扩展模型的功能限制,例如使用计算器或创建图表。
- 执行操作:使用 API 与外部系统互动,例如安排预约、创建账单、发送电子邮件或控制智能家居设备。
函数调用的工作原理
函数调用涉及应用、模型和外部函数之间的结构化交互。下面详细介绍了这个流程:
- 定义函数声明:在应用代码中定义函数声明。函数声明向模型描述函数的名称、参数和用途。
- 使用函数声明调用 LLM:将用户提示与函数声明一起发送给模型。它会分析请求,并确定函数调用是否有帮助。如果存在,则以结构化 JSON 对象的形式进行响应。
- 执行函数代码(您的责任):模型不会自行执行函数。应用负责处理响应并检查是否存在函数调用,如果
- 是:提取函数的名称和实参,并在应用中执行相应的函数。
- 否:模型已直接针对提示提供文本回答(此流程在示例中不太突出,但也是可能的结果)。
- 创建用户友好的回答:如果执行了函数,请捕获结果,并在后续对话轮次中将其发送回模型。然后,它会使用该结果生成最终的、用户友好的回答,其中包含函数调用的信息。
此过程可以重复多次,从而实现复杂的互动和工作流程。该模型还支持在单个对话轮次中调用多个函数(并行函数调用)以及按顺序调用多个函数(组合式函数调用)。
第 1 步:定义函数声明
在应用代码中定义一个函数及其声明,以便用户设置光照值并发出 API 请求。此函数可以调用外部服务或 API。
Python
# Define a function that the model can call to control smart lights
set_light_values_declaration = {
"name": "set_light_values",
"description": "Sets the brightness and color temperature of a light.",
"parameters": {
"type": "object",
"properties": {
"brightness": {
"type": "integer",
"description": "Light level from 0 to 100. Zero is off and 100 is full brightness",
},
"color_temp": {
"type": "string",
"enum": ["daylight", "cool", "warm"],
"description": "Color temperature of the light fixture, which can be `daylight`, `cool` or `warm`.",
},
},
"required": ["brightness", "color_temp"],
},
}
# This is the actual function that would be called based on the model's suggestion
def set_light_values(brightness: int, color_temp: str) -> dict[str, int | str]:
"""Set the brightness and color temperature of a room light. (mock API).
Args:
brightness: Light level from 0 to 100. Zero is off and 100 is full brightness
color_temp: Color temperature of the light fixture, which can be `daylight`, `cool` or `warm`.
Returns:
A dictionary containing the set brightness and color temperature.
"""
return {"brightness": brightness, "colorTemperature": color_temp}
JavaScript
import { Type } from '@google/genai';
// Define a function that the model can call to control smart lights
const setLightValuesFunctionDeclaration = {
name: 'set_light_values',
description: 'Sets the brightness and color temperature of a light.',
parameters: {
type: Type.OBJECT,
properties: {
brightness: {
type: Type.NUMBER,
description: 'Light level from 0 to 100. Zero is off and 100 is full brightness',
},
color_temp: {
type: Type.STRING,
enum: ['daylight', 'cool', 'warm'],
description: 'Color temperature of the light fixture, which can be `daylight`, `cool` or `warm`.',
},
},
required: ['brightness', 'color_temp'],
},
};
/**
* Set the brightness and color temperature of a room light. (mock API)
* @param {number} brightness - Light level from 0 to 100. Zero is off and 100 is full brightness
* @param {string} color_temp - Color temperature of the light fixture, which can be `daylight`, `cool` or `warm`.
* @return {Object} A dictionary containing the set brightness and color temperature.
*/
function setLightValues(brightness, color_temp) {
return {
brightness: brightness,
colorTemperature: color_temp
};
}
第 2 步:使用函数声明调用模型
定义函数声明后,您可以提示模型使用这些函数声明。它会分析提示和函数声明,并决定是直接回答还是调用函数。如果调用了函数,响应对象将包含函数调用建议。
Python
from google.genai import types
# Configure the client and tools
client = genai.Client()
tools = types.Tool(function_declarations=[set_light_values_declaration])
config = types.GenerateContentConfig(tools=[tools])
# Define user prompt
contents = [
types.Content(
role="user", parts=[types.Part(text="Turn the lights down to a romantic level")]
)
]
# Send request with function declarations
response = client.models.generate_content(
model="gemini-2.5-flash",
contents=contents
config=config,
)
print(response.candidates[0].content.parts[0].function_call)
JavaScript
import { GoogleGenAI } from '@google/genai';
// Generation config with function declaration
const config = {
tools: [{
functionDeclarations: [setLightValuesFunctionDeclaration]
}]
};
// Configure the client
const ai = new GoogleGenAI({});
// Define user prompt
const contents = [
{
role: 'user',
parts: [{ text: 'Turn the lights down to a romantic level' }]
}
];
// Send request with function declarations
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: contents,
config: config
});
console.log(response.functionCalls[0]);
然后,模型会返回一个 functionCall
对象,其中包含与 OpenAPI 兼容的架构,用于指定如何调用一个或多个已声明的函数,以便回答用户的问题。
Python
id=None args={'color_temp': 'warm', 'brightness': 25} name='set_light_values'
JavaScript
{
name: 'set_light_values',
args: { brightness: 25, color_temp: 'warm' }
}
第 3 步:执行 set_light_values 函数代码
从模型的响应中提取函数调用详细信息,解析实参,然后执行 set_light_values
函数。
Python
# Extract tool call details, it may not be in the first part.
tool_call = response.candidates[0].content.parts[0].function_call
if tool_call.name == "set_light_values":
result = set_light_values(**tool_call.args)
print(f"Function execution result: {result}")
JavaScript
// Extract tool call details
const tool_call = response.functionCalls[0]
let result;
if (tool_call.name === 'set_light_values') {
result = setLightValues(tool_call.args.brightness, tool_call.args.color_temp);
console.log(`Function execution result: ${JSON.stringify(result)}`);
}
第 4 步:使用函数结果创建用户友好的回答,然后再次调用模型
最后,将函数执行结果发送回模型,以便模型将此信息纳入其对用户的最终回答中。
Python
# Create a function response part
function_response_part = types.Part.from_function_response(
name=tool_call.name,
response={"result": result},
)
# Append function call and result of the function execution to contents
contents.append(response.candidates[0].content) # Append the content from the model's response.
contents.append(types.Content(role="user", parts=[function_response_part])) # Append the function response
final_response = client.models.generate_content(
model="gemini-2.5-flash",
config=config,
contents=contents,
)
print(final_response.text)
JavaScript
// Create a function response part
const function_response_part = {
name: tool_call.name,
response: { result }
}
// Append function call and result of the function execution to contents
contents.push(response.candidates[0].content);
contents.push({ role: 'user', parts: [{ functionResponse: function_response_part }] });
// Get the final response from the model
const final_response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: contents,
config: config
});
console.log(final_response.text);
至此,函数调用流程全部完成。模型成功使用 set_light_values
函数执行了用户的请求操作。
函数声明
在提示中实现函数调用时,您需要创建一个 tools
对象,其中包含一个或多个 function declarations
。您可以使用 JSON(具体来说是 OpenAPI 架构格式的选择子集)来定义函数。单个函数声明可以包含以下参数:
name
(字符串):函数的唯一名称(get_weather_forecast
、send_email
)。使用不含空格或特殊字符的描述性名称(使用下划线或驼峰式命名法)。description
(字符串):对函数用途和功能的清晰详细说明。这对于模型了解何时使用函数至关重要。请具体说明,并在必要时提供示例(“根据位置查找影院,还可以选择查找目前正在影院上映的电影。”)。parameters
(对象):定义函数预期的输入参数。type
(字符串):指定总体数据类型,例如object
。properties
(对象):列出各个参数,每个参数都包含以下信息:type
(字符串):参数的数据类型,例如string
、integer
、boolean, array
。description
(字符串):对参数的用途和格式的说明。提供示例和限制条件(例如,“城市和州,“加利福尼亚州旧金山”或邮政编码(例如'95616'。”)。enum
(数组,可选):如果参数值来自固定集,请使用“enum”列出允许的值,而不是仅在说明中描述它们。这有助于提高准确性(“枚举”:["daylight", "cool", "warm"])。
required
(数组):一个字符串数组,列出了函数运行所必需的参数名称。
函数调用与思考
启用“思考”功能后,模型可以在建议函数调用之前对请求进行推理,从而提高函数调用性能。
不过,由于 Gemini API 是无状态的,因此这种推理上下文会在对话轮次之间丢失,这可能会降低函数调用的质量,因为函数调用需要多次对话轮次请求。
如需保留此上下文,您可以使用思路签名。思考签名是模型内部思考过程的加密表示形式,您可以在后续对话轮次中将其传递回模型。
如需使用想法签名,请执行以下操作:
- 接收签名:启用思考功能后,API 响应将包含一个 thought_signature 字段,其中包含模型推理的加密表示形式。
- 返回签名:将函数的执行结果发送回服务器时,请附上您收到的 thought_signature。
这样一来,模型便可恢复之前的思考上下文,从而可能提升函数调用性能。
从服务器接收签名
签名在模型思考阶段之后的部分中返回,通常是文本或函数调用。
以下是一些示例,展示了在响应“塔霍湖的天气如何?”这一请求时,每种类型的部件中返回的思路签名是什么样的(使用 Get Weather 示例):
文本部分
[{
"candidates": [
{
"content": {
"parts": [
{
"text": "Here's what the weather in Lake Tahoe is today",
"thoughtSignature": "ClcBVKhc7ru7KzUI7SrdUoIdAYLm/+i93aHjfIt4xHyAoO/G70tApxnK2ujBhOhC1PrRy1pkQa88fqFvpHNVd1HDjNLO7mkp6/hFwE+SPPEB3fh0hs4oM8MKhgIBVKhc7uIGvrS7i/T4HpfbnYrluFfWNjZ62gewqe4cVdR/Dlh+zbjtYmDD0gPZ+SuBO7vvHQdzsjePRP+2Y5XddX6LEf/cGGgakq8EhVvw/a6IVzUO6XmpHg2Ag1sl8E9+VFH/lC0R0ZuYdFWligtDuYwp5p5q3o59G0TtWeU2MC1y2MJfE9u/KWd313ldka80/X2W/xF2O/4djMp5G2WKcULfve75zeRCy0mc5iS3SB9mTH0cT6x0vtKjeBx50gcg+CQWtJcRuwTVzz54dmvmK9xvnqA8gKGw3DuaM9wfy5hyY7Qg0z3iyyWdP8T/lbjKim8IEQOk7O1vVwP1Ko7oMYH8JgA1CsoBAVSoXO6v4c5RSyd1cn6EIU0pEFQsjW7rYWPuZdOFq/tsGJT9BCfW7KGkPGwlNSq8jTJFvbcJ/DjtndISQYXwiXd2kGa5JfdS2Kh4zOxCxiWtOk+2nCc3+XQk2nonhO+esGJpkDdbbHZSqRgcUtYKq7q28iPFOQvOFyCiZNB7K86Z/6Hnagu2snSlN/BcTMaFGaWpcCClSUo4foRZn3WbNCoM8rcpD7qEJMp4a5baaSxyyeL1ZTGd2HLpFys/oiW6e3oAnhxuIysCwg=="
}
],
"role": "model"
},
"index": 0
}
],
# Remainder of response...
函数调用部分
[{
"candidates": [
{
"content": {
"parts": [
{
"functionCall": {
"name": "getWeather",
"args": {
"city": "Lake Tahoe"
}
},
"thoughtSignature": "CiwBVKhc7nRyTi3HmggPD9iQiRc261f5jwuMdw3H/itDH0emsb9ZVo3Nwx9p6wpsAVSoXO5i8fDV4jBSBLoaWxB5zUdlGY6aIGp+I0oEnwRRSRQ1LOvrDlojEH8JE8HjiKXALdJrvNPiG+HY3GZEO8pZjEZtc3UoBUh7+SVyjK7Xolu7aRYYeUyzrCapoETWypER1jbrJXnFV23hCosBAVSoXO6oIPNJSmbuEDfGafOhuCSHkpr1yjTp35RXYqmCESzRzWf5+nFXLqncqeFo4ohoxbiYQVpVQbOZF81p8o9zg6xeRE7qMeOv+XN7enXGJ4/s3qNFQpfkSMqRdBITN1VpX7jyfEAjvxBNc7PDfDJZmEPY338ZIY5nFFcmzJSWjVrboFt2sMFv+A=="
}
],
"role": "model"
},
"finishReason": "STOP",
"index": 0
}
],
# Remainder of response...
您可以使用以下代码确认是否收到了签名,并查看签名是什么样的:
# Step 2: Call the model with function declarations
# ...Generation config, Configure the client, and Define user prompt (No changes)
# Send request with declarations (using a thinking model)
response = client.models.generate_content(
model="gemini-2.5-flash", config=config, contents=contents)
# See thought signatures
for part in response.candidates[0].content.parts:
if part.thought_signature:
print("Thought signature:")
print(part.thought_signature)
将签名返回到服务器
如需恢复签名,请执行以下操作:
- 您应将签名及其包含的部分返回给服务器
- 您不应将包含签名的部分与也包含签名的另一部分合并。签名字符串不可串联
- 您不应将带有签名的部分与不带签名的部分合并。这会破坏签名所代表的想法的正确位置。
代码将与上一部分中的第 4 步保持一致。 但在这种情况下(如下方注释所示),您将向模型返回签名以及函数执行结果,以便模型将这些想法纳入其最终回答中:
Python
# Step 4: Create user friendly response with function result and call the model again
# ...Create a function response part (No change)
# Append thought signatures, function call and result of the function execution to contents
function_call_content = response.candidates[0].content
# Append the model's function call message, which includes thought signatures
contents.append(function_call_content)
contents.append(types.Content(role="user", parts=[function_response_part])) # Append the function response
final_response = client.models.generate_content(
model="gemini-2.5-flash",
config=config,
contents=contents,
)
print(final_response.text)
JavaScript
// Step 4: Create user friendly response with function result and call the model again
// ...Create a function response part (No change)
// Append thought signatures, function call and result of the function execution to contents
const function_response_content = response.candidates[0].content;
contents.push(function_response_content);
contents.push({ role: 'user', parts: [{ functionResponse: function_response_part }] });
const final_response = await ai.models.generateContent({
model: 'gemini-2.5-flash',
contents: contents,
config: config
});
console.log(final_response.text);
以下示例展示了返回思路签名的请求可能是什么样子:
[{
"contents": [
{
"role": "user",
"parts": [
{
"text": "what is the weather in Lake Tahoe?"
}
]
},
{
"parts": [
{
"functionCall": {
"name": "getWeather",
"args": {
"city": "Lake Tahoe"
}
},
"thoughtSignature": "CiIBVKhc7oDPpCaXyJKKssjqr4g3JNOSgJ/M2V+1THC1icsWCmwBVKhc7pBABbZ+zR3e9234WnWWS6GFXmf8IVwpnzjd5KYd7vyJbn/4vTorWBGayj/vbd9JPaZQjxdAIXhoE5mX/MDsQ7M9N/b0qJjHm39tYIBvS4sIWkMDHqTJqXGLzhhKtrTkfbV3RbaJEkQKmwEBVKhc7qVUgC3hfTXZLo9R3AJzUUIx50NKvJTb9B+UU+LBqgg7Nck1x5OpjWVS2R+SsveprIuYOruk2Y0H53J2OJF8qsxTdIq2si8DGW2V7WK8xyoJH5kbqd7drIw1jLb44b6lx4SMyB0VaULuTBki4d+Ljjg1tJTwR0IYMKqDLDZt9mheINsi0ZxcNjfpnDydRXdWbcSwzmK/wgqJAQFUqFzuKgNVElxs3cbO+xebr2IwcOro84nKTisi0tTp9bICPC9fTUhn3L+rvQWA+d3J1Za8at2bakrqiRj7BTh+CVO9fWQMAEQAs3ni0Z2hfaYG92tOD26E4IoZwyYEoWbfNudpH1fr5tEkyqnEGtWIh7H+XoZQ2DXeiOa+br7Zk88SrNE+trJMCogBAVSoXO5e9fBLg7hnbkmKsrzNLnQtLsQm1gNzjcjEC7nJYklYPp0KI2uGBE1PkM8XNsfllAfHVn7LzHcHNlbQ9pJ7QZTSIeG42goS971r5wNZwxaXwCTphClQh826eqJWo6A/28TtAVQWLhTx5ekbP7qb4nh1UblESZ1saxDQAEo4OKPbDzx5BgqKAQFUqFzuVyjNm5i0wN8hTDnKjfpDroEpPPTs531iFy9BOX+xDCdGHy8D+osFpaoBq6TFekQQbz4hIoUR1YEcP4zI80/cNimEeb9IcFxZTTxiNrbhbbcv0969DSMWhB+ZEqIz4vuw4GLe/xcUvqhlChQwFdgIbdOQHSHpatn5uDlktnP/bi26nKuXIwo0AVSoXO7US22OUH7d1f4abNPI0IyAvhqkPp12rbtWLx9vkOtojE8IP+xCfYtIFuZIzRNZqA=="
}
],
"role": "model"
},
{
"role": "user",
"parts": [
{
"functionResponse": {
"name": "getWeather",
"response": {
"response": {
"stringValue": "Sunny and hot. 90 degrees Fahrenheit"
}
}
}
}
]
}
],
# Remainder of request...
如需详细了解思维签名的限制和使用情况,以及一般的思维模型,请参阅思考页面。
并行函数调用
除了单轮函数调用之外,您还可以一次调用多个函数。并行函数调用可让您同时执行多个函数,适用于函数之间没有依赖关系的情况。这在以下场景中非常有用:从多个独立来源收集数据,例如从不同数据库检索客户详细信息、检查各个仓库的库存水平,或执行多项操作(例如将公寓改造成迪斯科舞厅)。
Python
power_disco_ball = {
"name": "power_disco_ball",
"description": "Powers the spinning disco ball.",
"parameters": {
"type": "object",
"properties": {
"power": {
"type": "boolean",
"description": "Whether to turn the disco ball on or off.",
}
},
"required": ["power"],
},
}
start_music = {
"name": "start_music",
"description": "Play some music matching the specified parameters.",
"parameters": {
"type": "object",
"properties": {
"energetic": {
"type": "boolean",
"description": "Whether the music is energetic or not.",
},
"loud": {
"type": "boolean",
"description": "Whether the music is loud or not.",
},
},
"required": ["energetic", "loud"],
},
}
dim_lights = {
"name": "dim_lights",
"description": "Dim the lights.",
"parameters": {
"type": "object",
"properties": {
"brightness": {
"type": "number",
"description": "The brightness of the lights, 0.0 is off, 1.0 is full.",
}
},
"required": ["brightness"],
},
}
JavaScript
import { Type } from '@google/genai';
const powerDiscoBall = {
name: 'power_disco_ball',
description: 'Powers the spinning disco ball.',
parameters: {
type: Type.OBJECT,
properties: {
power: {
type: Type.BOOLEAN,
description: 'Whether to turn the disco ball on or off.'
}
},
required: ['power']
}
};
const startMusic = {
name: 'start_music',
description: 'Play some music matching the specified parameters.',
parameters: {
type: Type.OBJECT,
properties: {
energetic: {
type: Type.BOOLEAN,
description: 'Whether the music is energetic or not.'
},
loud: {
type: Type.BOOLEAN,
description: 'Whether the music is loud or not.'
}
},
required: ['energetic', 'loud']
}
};
const dimLights = {
name: 'dim_lights',
description: 'Dim the lights.',
parameters: {
type: Type.OBJECT,
properties: {
brightness: {
type: Type.NUMBER,
description: 'The brightness of the lights, 0.0 is off, 1.0 is full.'
}
},
required: ['brightness']
}
};
配置函数调用模式,以允许使用所有指定的工具。 如需了解详情,您可以参阅配置函数调用。
Python
from google import genai
from google.genai import types
# Configure the client and tools
client = genai.Client()
house_tools = [
types.Tool(function_declarations=[power_disco_ball, start_music, dim_lights])
]
config = types.GenerateContentConfig(
tools=house_tools,
automatic_function_calling=types.AutomaticFunctionCallingConfig(
disable=True
),
# Force the model to call 'any' function, instead of chatting.
tool_config=types.ToolConfig(
function_calling_config=types.FunctionCallingConfig(mode='ANY')
),
)
chat = client.chats.create(model="gemini-2.5-flash", config=config)
response = chat.send_message("Turn this place into a party!")
# Print out each of the function calls requested from this single call
print("Example 1: Forced function calling")
for fn in response.function_calls:
args = ", ".join(f"{key}={val}" for key, val in fn.args.items())
print(f"{fn.name}({args})")
JavaScript
import { GoogleGenAI } from '@google/genai';
// Set up function declarations
const houseFns = [powerDiscoBall, startMusic, dimLights];
const config = {
tools: [{
functionDeclarations: houseFns
}],
// Force the model to call 'any' function, instead of chatting.
toolConfig: {
functionCallingConfig: {
mode: 'any'
}
}
};
// Configure the client
const ai = new GoogleGenAI({});
// Create a chat session
const chat = ai.chats.create({
model: 'gemini-2.5-flash',
config: config
});
const response = await chat.sendMessage({message: 'Turn this place into a party!'});
// Print out each of the function calls requested from this single call
console.log("Example 1: Forced function calling");
for (const fn of response.functionCalls) {
const args = Object.entries(fn.args)
.map(([key, val]) => `${key}=${val}`)
.join(', ');
console.log(`${fn.name}(${args})`);
}
每个打印结果都反映了模型请求的单个函数调用。如需将结果发送回去,请按请求顺序包含响应。
Python SDK 支持自动函数调用,可自动将 Python 函数转换为声明,并为您处理函数调用执行和响应周期。以下是 disco 用例的示例。
Python
from google import genai
from google.genai import types
# Actual function implementations
def power_disco_ball_impl(power: bool) -> dict:
"""Powers the spinning disco ball.
Args:
power: Whether to turn the disco ball on or off.
Returns:
A status dictionary indicating the current state.
"""
return {"status": f"Disco ball powered {'on' if power else 'off'}"}
def start_music_impl(energetic: bool, loud: bool) -> dict:
"""Play some music matching the specified parameters.
Args:
energetic: Whether the music is energetic or not.
loud: Whether the music is loud or not.
Returns:
A dictionary containing the music settings.
"""
music_type = "energetic" if energetic else "chill"
volume = "loud" if loud else "quiet"
return {"music_type": music_type, "volume": volume}
def dim_lights_impl(brightness: float) -> dict:
"""Dim the lights.
Args:
brightness: The brightness of the lights, 0.0 is off, 1.0 is full.
Returns:
A dictionary containing the new brightness setting.
"""
return {"brightness": brightness}
# Configure the client
client = genai.Client()
config = types.GenerateContentConfig(
tools=[power_disco_ball_impl, start_music_impl, dim_lights_impl]
)
# Make the request
response = client.models.generate_content(
model="gemini-2.5-flash",
contents="Do everything you need to this place into party!",
config=config,
)
print("\nExample 2: Automatic function calling")
print(response.text)
# I've turned on the disco ball, started playing loud and energetic music, and dimmed the lights to 50% brightness. Let's get this party started!
组合式函数调用
组合式或顺序式函数调用可让 Gemini 将多个函数调用链接在一起,以满足复杂的请求。例如,为了回答“获取我当前位置的温度”,Gemini API 可能会先调用 get_current_location()
函数,然后再调用以位置为参数的 get_weather()
函数。
以下示例演示了如何使用 Python SDK 和自动函数调用来实现组合式函数调用。
Python
此示例使用 google-genai
Python SDK 的自动函数调用功能。SDK 会自动将 Python 函数转换为所需的架构,在模型请求时执行函数调用,并将结果发送回模型以完成任务。
import os
from google import genai
from google.genai import types
# Example Functions
def get_weather_forecast(location: str) -> dict:
"""Gets the current weather temperature for a given location."""
print(f"Tool Call: get_weather_forecast(location={location})")
# TODO: Make API call
print("Tool Response: {'temperature': 25, 'unit': 'celsius'}")
return {"temperature": 25, "unit": "celsius"} # Dummy response
def set_thermostat_temperature(temperature: int) -> dict:
"""Sets the thermostat to a desired temperature."""
print(f"Tool Call: set_thermostat_temperature(temperature={temperature})")
# TODO: Interact with a thermostat API
print("Tool Response: {'status': 'success'}")
return {"status": "success"}
# Configure the client and model
client = genai.Client()
config = types.GenerateContentConfig(
tools=[get_weather_forecast, set_thermostat_temperature]
)
# Make the request
response = client.models.generate_content(
model="gemini-2.5-flash",
contents="If it's warmer than 20°C in London, set the thermostat to 20°C, otherwise set it to 18°C.",
config=config,
)
# Print the final, user-facing response
print(response.text)
预期输出
运行代码时,您会看到 SDK 编排函数调用。模型首先调用 get_weather_forecast
,接收温度,然后根据提示中的逻辑调用 set_thermostat_temperature
并传入正确的值。
Tool Call: get_weather_forecast(location=London)
Tool Response: {'temperature': 25, 'unit': 'celsius'}
Tool Call: set_thermostat_temperature(temperature=20)
Tool Response: {'status': 'success'}
OK. I've set the thermostat to 20°C.
JavaScript
此示例展示了如何使用 JavaScript/TypeScript SDK 通过手动执行循环进行组合式函数调用。
import { GoogleGenAI, Type } from "@google/genai";
// Configure the client
const ai = new GoogleGenAI({});
// Example Functions
function get_weather_forecast({ location }) {
console.log(`Tool Call: get_weather_forecast(location=${location})`);
// TODO: Make API call
console.log("Tool Response: {'temperature': 25, 'unit': 'celsius'}");
return { temperature: 25, unit: "celsius" };
}
function set_thermostat_temperature({ temperature }) {
console.log(
`Tool Call: set_thermostat_temperature(temperature=${temperature})`,
);
// TODO: Make API call
console.log("Tool Response: {'status': 'success'}");
return { status: "success" };
}
const toolFunctions = {
get_weather_forecast,
set_thermostat_temperature,
};
const tools = [
{
functionDeclarations: [
{
name: "get_weather_forecast",
description:
"Gets the current weather temperature for a given location.",
parameters: {
type: Type.OBJECT,
properties: {
location: {
type: Type.STRING,
},
},
required: ["location"],
},
},
{
name: "set_thermostat_temperature",
description: "Sets the thermostat to a desired temperature.",
parameters: {
type: Type.OBJECT,
properties: {
temperature: {
type: Type.NUMBER,
},
},
required: ["temperature"],
},
},
],
},
];
// Prompt for the model
let contents = [
{
role: "user",
parts: [
{
text: "If it's warmer than 20°C in London, set the thermostat to 20°C, otherwise set it to 18°C.",
},
],
},
];
// Loop until the model has no more function calls to make
while (true) {
const result = await ai.models.generateContent({
model: "gemini-2.5-flash",
contents,
config: { tools },
});
if (result.functionCalls && result.functionCalls.length > 0) {
const functionCall = result.functionCalls[0];
const { name, args } = functionCall;
if (!toolFunctions[name]) {
throw new Error(`Unknown function call: ${name}`);
}
// Call the function and get the response.
const toolResponse = toolFunctions[name](args);
const functionResponsePart = {
name: functionCall.name,
response: {
result: toolResponse,
},
};
// Send the function response back to the model.
contents.push({
role: "model",
parts: [
{
functionCall: functionCall,
},
],
});
contents.push({
role: "user",
parts: [
{
functionResponse: functionResponsePart,
},
],
});
} else {
// No more function calls, break the loop.
console.log(result.text);
break;
}
}
预期输出
运行代码时,您会看到 SDK 编排函数调用。模型首先调用 get_weather_forecast
,接收温度,然后根据提示中的逻辑调用 set_thermostat_temperature
并传入正确的值。
Tool Call: get_weather_forecast(location=London)
Tool Response: {'temperature': 25, 'unit': 'celsius'}
Tool Call: set_thermostat_temperature(temperature=20)
Tool Response: {'status': 'success'}
OK. It's 25°C in London, so I've set the thermostat to 20°C.
组合式函数调用是一项原生 Live API 功能。这意味着 Live API 可以像 Python SDK 一样处理函数调用。
Python
# Light control schemas
turn_on_the_lights_schema = {'name': 'turn_on_the_lights'}
turn_off_the_lights_schema = {'name': 'turn_off_the_lights'}
prompt = """
Hey, can you write run some python code to turn on the lights, wait 10s and then turn off the lights?
"""
tools = [
{'code_execution': {}},
{'function_declarations': [turn_on_the_lights_schema, turn_off_the_lights_schema]}
]
await run(prompt, tools=tools, modality="AUDIO")
JavaScript
// Light control schemas
const turnOnTheLightsSchema = { name: 'turn_on_the_lights' };
const turnOffTheLightsSchema = { name: 'turn_off_the_lights' };
const prompt = `
Hey, can you write run some python code to turn on the lights, wait 10s and then turn off the lights?
`;
const tools = [
{ codeExecution: {} },
{ functionDeclarations: [turnOnTheLightsSchema, turnOffTheLightsSchema] }
];
await run(prompt, tools=tools, modality="AUDIO")
函数调用模式
通过 Gemini API,您可以控制模型使用所提供工具(函数声明)的方式。具体来说,您可以在 .function_calling_config
中设置模式。
AUTO (Default)
:模型会根据提示和上下文决定是生成自然语言回答还是建议函数调用。这是最灵活的模式,建议在大多数情况下使用。ANY
:模型会受到限制,始终预测函数调用,并保证遵循函数架构。如果未指定allowed_function_names
,模型可以从任何提供的函数声明中进行选择。如果allowed_function_names
以列表形式提供,模型只能从该列表中的函数中进行选择。如果您需要针对每个提示(如果适用)获得函数调用响应,请使用此模式。NONE
:模型禁止进行函数调用。这相当于发送不含任何函数声明的请求。使用此参数可暂时停用函数调用,而无需移除工具定义。
Python
from google.genai import types
# Configure function calling mode
tool_config = types.ToolConfig(
function_calling_config=types.FunctionCallingConfig(
mode="ANY", allowed_function_names=["get_current_temperature"]
)
)
# Create the generation config
config = types.GenerateContentConfig(
tools=[tools], # not defined here.
tool_config=tool_config,
)
JavaScript
import { FunctionCallingConfigMode } from '@google/genai';
// Configure function calling mode
const toolConfig = {
functionCallingConfig: {
mode: FunctionCallingConfigMode.ANY,
allowedFunctionNames: ['get_current_temperature']
}
};
// Create the generation config
const config = {
tools: tools, // not defined here.
toolConfig: toolConfig,
};
自动函数调用(仅限 Python)
使用 Python SDK 时,您可以直接将 Python 函数作为工具提供。SDK 会自动将 Python 函数转换为声明,并为您处理函数调用执行和响应周期。然后,Python SDK 会自动执行以下操作:
- 检测来自模型的函数调用响应。
- 在代码中调用相应的 Python 函数。
- 将函数响应发送回模型。
- 返回模型的最终文本回答。
如需使用此功能,请使用类型提示和文档字符串定义函数,然后将函数本身(而非 JSON 声明)作为工具传递:
Python
from google import genai
from google.genai import types
# Define the function with type hints and docstring
def get_current_temperature(location: str) -> dict:
"""Gets the current temperature for a given location.
Args:
location: The city and state, e.g. San Francisco, CA
Returns:
A dictionary containing the temperature and unit.
"""
# ... (implementation) ...
return {"temperature": 25, "unit": "Celsius"}
# Configure the client
client = genai.Client()
config = types.GenerateContentConfig(
tools=[get_current_temperature]
) # Pass the function itself
# Make the request
response = client.models.generate_content(
model="gemini-2.5-flash",
contents="What's the temperature in Boston?",
config=config,
)
print(response.text) # The SDK handles the function call and returns the final text
您可以使用以下方法停用自动函数调用:
Python
config = types.GenerateContentConfig(
tools=[get_current_temperature],
automatic_function_calling=types.AutomaticFunctionCallingConfig(disable=True)
)
自动函数架构声明
从 Python 函数自动提取架构并非在所有情况下都有效。例如,它无法处理您描述嵌套字典对象的字段的情况。该 API 能够描述以下任何类型:
Python
AllowedType = (int | float | bool | str | list['AllowedType'] | dict[str, AllowedType])
如需查看推断架构的实际效果,您可以使用 from_callable
将其转换:
Python
def multiply(a: float, b: float):
"""Returns a * b."""
return a * b
fn_decl = types.FunctionDeclaration.from_callable(callable=multiply, client=client)
# to_json_dict() provides a clean JSON representation.
print(fn_decl.to_json_dict())
多工具使用:将原生工具与函数调用相结合
您可以同时启用多个工具,将原生工具与函数调用相结合。以下示例展示了如何使用 Live API 在请求中启用两项工具:Google 搜索基础知识和代码执行。
Python
# Multiple tasks example - combining lights, code execution, and search
prompt = """
Hey, I need you to do three things for me.
1. Turn on the lights.
2. Then compute the largest prime palindrome under 100000.
3. Then use Google Search to look up information about the largest earthquake in California the week of Dec 5 2024.
Thanks!
"""
tools = [
{'google_search': {}},
{'code_execution': {}},
{'function_declarations': [turn_on_the_lights_schema, turn_off_the_lights_schema]} # not defined here.
]
# Execute the prompt with specified tools in audio modality
await run(prompt, tools=tools, modality="AUDIO")
JavaScript
// Multiple tasks example - combining lights, code execution, and search
const prompt = `
Hey, I need you to do three things for me.
1. Turn on the lights.
2. Then compute the largest prime palindrome under 100000.
3. Then use Google Search to look up information about the largest earthquake in California the week of Dec 5 2024.
Thanks!
`;
const tools = [
{ googleSearch: {} },
{ codeExecution: {} },
{ functionDeclarations: [turnOnTheLightsSchema, turnOffTheLightsSchema] } // not defined here.
];
// Execute the prompt with specified tools in audio modality
await run(prompt, {tools: tools, modality: "AUDIO"});
Python 开发者可以在 Live API Tool Use notebook 中试用此功能。
模型上下文协议 (MCP)
模型上下文协议 (MCP) 是一种开放标准,用于将 AI 应用与外部工具和数据相关联。MCP 为模型提供了一种用于访问上下文(例如函数 [工具]、数据源 [资源] 或预定义提示)的通用协议。
Gemini SDK 内置了对 MCP 的支持,可减少样板代码并为 MCP 工具提供自动工具调用。当模型生成 MCP 工具调用时,Python 和 JavaScript 客户端 SDK 可以自动执行 MCP 工具,并在后续请求中将响应发送回模型,从而继续此循环,直到模型不再进行任何工具调用。
在此处,您可以找到一个示例,了解如何将本地 MCP 服务器与 Gemini 和 mcp
SDK 搭配使用。
Python
确保在您选择的平台上安装了最新版本的 mcp
SDK。
pip install mcp
import os
import asyncio
from datetime import datetime
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
from google import genai
client = genai.Client()
# Create server parameters for stdio connection
server_params = StdioServerParameters(
command="npx", # Executable
args=["-y", "@philschmid/weather-mcp"], # MCP Server
env=None, # Optional environment variables
)
async def run():
async with stdio_client(server_params) as (read, write):
async with ClientSession(read, write) as session:
# Prompt to get the weather for the current day in London.
prompt = f"What is the weather in London in {datetime.now().strftime('%Y-%m-%d')}?"
# Initialize the connection between client and server
await session.initialize()
# Send request to the model with MCP function declarations
response = await client.aio.models.generate_content(
model="gemini-2.5-flash",
contents=prompt,
config=genai.types.GenerateContentConfig(
temperature=0,
tools=[session], # uses the session, will automatically call the tool
# Uncomment if you **don't** want the SDK to automatically call the tool
# automatic_function_calling=genai.types.AutomaticFunctionCallingConfig(
# disable=True
# ),
),
)
print(response.text)
# Start the asyncio event loop and run the main function
asyncio.run(run())
JavaScript
确保您选择的平台上安装了最新版本的 mcp
SDK。
npm install @modelcontextprotocol/sdk
import { GoogleGenAI, FunctionCallingConfigMode , mcpToTool} from '@google/genai';
import { Client } from "@modelcontextprotocol/sdk/client/index.js";
import { StdioClientTransport } from "@modelcontextprotocol/sdk/client/stdio.js";
// Create server parameters for stdio connection
const serverParams = new StdioClientTransport({
command: "npx", // Executable
args: ["-y", "@philschmid/weather-mcp"] // MCP Server
});
const client = new Client(
{
name: "example-client",
version: "1.0.0"
}
);
// Configure the client
const ai = new GoogleGenAI({});
// Initialize the connection between client and server
await client.connect(serverParams);
// Send request to the model with MCP tools
const response = await ai.models.generateContent({
model: "gemini-2.5-flash",
contents: `What is the weather in London in ${new Date().toLocaleDateString()}?`,
config: {
tools: [mcpToTool(client)], // uses the session, will automatically call the tool
// Uncomment if you **don't** want the sdk to automatically call the tool
// automaticFunctionCalling: {
// disable: true,
// },
},
});
console.log(response.text)
// Close the connection
await client.close();
内置 MCP 支持的限制
内置 MCP 支持是我们 SDK 中的一项实验性功能,具有以下限制:
- 仅支持工具,不支持资源或提示
- 适用于 Python 和 JavaScript/TypeScript SDK。
- 未来版本可能会出现重大变更。
如果这些限制影响了您构建的内容,您可以随时选择手动集成 MCP 服务器。
支持的模型
本部分列出了模型及其函数调用功能。不包括实验性模型。您可以在模型概览页面上找到全面的功能概览。
型号 | 函数调用 | 并行函数调用 | 组合式函数调用 |
---|---|---|---|
Gemini 2.5 Pro | ✔️ | ✔️ | ✔️ |
Gemini 2.5 Flash | ✔️ | ✔️ | ✔️ |
Gemini 2.5 Flash-Lite | ✔️ | ✔️ | ✔️ |
Gemini 2.0 Flash | ✔️ | ✔️ | ✔️ |
Gemini 2.0 Flash-Lite | X | X | X |
最佳做法
- 函数和参数说明:说明应非常清晰且具体。模型会根据这些信息选择正确的函数并提供适当的实参。
- 命名:使用描述性函数名称(不含空格、句点或短划线)。
- 强类型:为参数使用特定类型(整数、字符串、枚举)以减少错误。如果某个形参的有效值集有限,请使用枚举。
- 工具选择:虽然模型可以使用任意数量的工具,但提供的工具过多可能会增加选择错误或次优工具的风险。为获得最佳效果,请尽量仅提供与上下文或任务相关的工具,最好将有效工具集保持在 10-20 个以内。如果您有大量工具,请考虑根据对话上下文动态选择工具。
- 提示工程:
- 提供背景信息:告知模型其角色(例如,“你是一位乐于助人的天气助理。”)。
- 提供指令:指定如何以及何时使用函数(例如,“不要猜测日期;始终使用未来的日期进行预测。”)。
- 鼓励澄清:指示模型在需要时提出澄清性问题。
- 温度:使用较低的温度(例如 0)以实现更具确定性和可靠性的函数调用。
- 验证:如果函数调用会产生重大后果(例如下单),请在执行之前先向用户验证该调用。
- 错误处理:在函数中实现强大的错误处理机制,以妥善处理意外输入或 API 故障。返回信息丰富的错误消息,供模型用来生成对用户的实用回答。
- 安全性:调用外部 API 时,请务必注意安全性。使用适当的身份验证和授权机制。避免在函数调用中公开敏感数据。
- token 限制:函数说明和参数会计入输入 token 限制。如果您遇到令牌限制,请考虑限制函数数量或说明长度,将复杂的任务分解为更小、更集中的函数集。
注释和限制
- 仅支持 OpenAPI 架构的一部分。
- Python 中支持的形参类型有限。
- 自动函数调用仅为 Python SDK 功能。