推理提供商文档
函数调用与推理提供商
并获得增强的文档体验
开始使用
函数调用与推理提供商
函数调用使语言模型能够通过根据用户输入生成结构化函数调用来与外部工具和 API 进行交互。此功能允许您构建可以执行检索实时数据、进行计算或与外部服务交互等操作的 AI 代理。
当您向经过工具使用微调的语言模型提供函数描述时,它可以根据用户请求决定何时调用这些函数,执行它们,并将结果整合到自然语言响应中。例如,您可以构建一个助手来获取实时天气数据以提供准确的响应。
本指南假定您拥有 Hugging Face 帐户和访问令牌。您可以在 huggingface.co 创建免费帐户,并从您的设置页面获取令牌。
定义函数
第一步是实现您希望模型调用的函数。我们将使用一个简单的天气函数示例,它返回给定位置的当前天气。
一如既往,我们将首先初始化我们的推理客户端。
在 OpenAI 客户端中,我们将使用 base_url
参数来指定我们希望用于请求的提供商。
import json
import os
from openai import OpenAI
# Initialize client
client = OpenAI(
base_url="https://router.huggingface.co/v1",
api_key=os.environ["HF_TOKEN"],
)
我们可以将函数定义为执行简单任务的 Python 函数。在本例中,该函数将以位置、温度和条件字典的形式返回当前天气。
# Define the function
def get_current_weather(location: str) -> dict:
"""Get weather information for a location."""
# In production, this would call a real weather API
weather_data = {
"San Francisco": {"temperature": "22°C", "condition": "Sunny"},
"New York": {"temperature": "18°C", "condition": "Cloudy"},
"London": {"temperature": "15°C", "condition": "Rainy"},
}
return weather_data.get(location, {
"location": location,
"error": "Weather data not available"
})
现在我们需要定义函数模式,它向语言模型描述我们的天气函数。此模式告诉模型函数期望哪些参数以及它执行什么操作。
# Define the function schema
tools = [
{
"type": "function",
"function": {
"name": "get_current_weather",
"description": "Get current weather for a location",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City name"
},
},
"required": ["location"],
},
},
},
]
该模式是一种 JSON Schema 格式,描述了函数的功能、其参数以及哪些参数是必需的。描述有助于模型理解何时以及如何调用函数。
在聊天中处理函数
函数在典型的聊天完成对话中起作用。模型将根据用户输入决定何时调用它们。
user_message = "What's the weather like in San Francisco?"
messages = [
{
"role": "system",
"content": "You are a helpful assistant with access to weather data."
},
{"role": "user", "content": user_message}
]
# Initial API call with tools
response = client.chat.completions.create(
model="deepseek-ai/DeepSeek-R1-0528",
messages=messages,
tools=tools,
tool_choice="auto" # Let the model decide when to call functions
)
response_message = response.choices[0].message
tool_choice
参数用于控制模型何时调用函数。在本例中,我们使用 auto
,这意味着模型将决定何时调用函数(0 次或多次)。下面我们将扩展 tool_choice
和其他参数。
接下来,我们需要检查模型响应中模型决定调用了哪些函数。如果调用了,我们需要执行该函数并将结果添加到对话中,然后将最终响应发送给用户。
# Check if model wants to call functions
if response_message.tool_calls:
# Add assistant's response to messages
messages.append(response_message)
# Process each tool call
for tool_call in response_message.tool_calls:
function_name = tool_call.function.name
function_args = json.loads(tool_call.function.arguments)
# Execute the function
if function_name == "get_current_weather":
result = get_current_weather(function_args["location"])
# Add function result to messages
messages.append({
"tool_call_id": tool_call.id,
"role": "tool",
"name": function_name,
"content": json.dumps(result),
})
# Get final response with function results
final_response = client.chat.completions.create(
model="deepseek-ai/DeepSeek-R1-0528",
messages=messages,
)
return final_response.choices[0].message.content
else:
return response_message.content
工作流程很简单:使用您的工具进行初始 API 调用,检查模型是否要调用函数,如果需要则执行它们,将结果添加到对话中,并获取用户的最终响应。
我们已经处理了模型想要调用函数并且该函数实际存在的情况。然而,模型可能会尝试调用不存在的函数,因此我们也需要考虑这一点。我们还可以使用 strict
模式来处理这个问题,我们将在后面介绍。
多个函数
您可以为更复杂的助手定义多个函数。
# Define multiple functions
def get_current_weather(location: str) -> dict:
"""Get current weather for a location."""
return {"location": location, "temperature": "22°C", "condition": "Sunny"}
def get_weather_forecast(location: str, date: str) -> dict:
"""Get weather forecast for a location."""
return {
"location": location,
"date": date,
"forecast": "Sunny with chance of rain",
"temperature": "20°C"
}
# Function registry
AVAILABLE_FUNCTIONS = {
"get_current_weather": get_current_weather,
"get_weather_forecast": get_weather_forecast,
}
# Multiple tool schemas
tools = [
{
"type": "function",
"function": {
"name": "get_current_weather",
"description": "Get current weather for a location",
"parameters": {
"type": "object",
"properties": {
"location": {"type": "string", "description": "City name"}
},
"required": ["location"],
},
},
},
{
"type": "function",
"function": {
"name": "get_weather_forecast",
"description": "Get weather forecast for a location",
"parameters": {
"type": "object",
"properties": {
"location": {"type": "string", "description": "City name"},
"date": {"type": "string", "description": "Date in YYYY-MM-DD format"},
},
"required": ["location", "date"],
},
},
},
]
response = client.chat.completions.create(
model="deepseek-ai/DeepSeek-R1-0528",
messages=messages,
tools=tools,
tool_choice="auto"
)
我们定义了多个函数并将它们添加到了工具列表中。模型将根据用户输入决定何时调用它们。我们还可以使用 tool_choice
参数强制模型调用特定函数。
我们可以以与单个函数示例类似的方式处理工具执行。这次使用 elif
语句来处理不同的函数。
# execute the response
response_message = response.choices[0].message
# check if the model wants to call functions
if response_message.tool_calls:
# process the tool calls
for tool_call in response_message.tool_calls:
function_name = tool_call.function.name
function_args = json.loads(tool_call.function.arguments)
# execute the function
if function_name == "get_current_weather":
result = get_current_weather(function_args["location"])
elif function_name == "get_weather_forecast":
result = get_weather_forecast(function_args["location"], function_args["date"])
# add the result to the conversation
messages.append({
"tool_call_id": tool_call.id,
"role": "tool",
"name": function_name,
"content": json.dumps(result),
})
# get the final response with function results
final_response = client.chat.completions.create(
model="deepseek-ai/DeepSeek-R1-0528",
messages=messages,
)
return final_response.choices[0].message.content
else:
return response_message.content
🎉 您已经构建了一个功能性助手,可以调用多个函数来获取天气数据!
额外配置
让我们看看函数调用与推理提供商的一些额外配置选项,以充分利用其功能。
提供商选择
您可以指定要使用的推理提供商,以更好地控制性能和成本。这将通过减少模型响应中的差异来帮助函数调用。
在 OpenAI 客户端中,您可以通过将提供商 ID 附加到模型参数来指定要用于请求的提供商,如下所示
# The OpenAI client automatically routes through Inference Providers
# You can specify provider preferences in your HF settings
client = OpenAI(
base_url="https://router.huggingface.co/v1",
api_key=os.environ["HF_TOKEN"],
)
client.chat.completions.create(
- model="deepseek-ai/DeepSeek-R1-0528", # automatically select provider based on hf.co/settings/inference-providers
+ model="deepseek-ai/DeepSeek-R1-0528:nebius", # manually select Nebius AI
+ model="deepseek-ai/DeepSeek-R1-0528:hyperbolic", # manually select Hyperbolic
...
)
通过切换提供商,您可以看到模型的响应发生变化,因为每个提供商都使用不同的模型配置。
每个推理提供商都有不同的功能和性能特征。您可以在推理提供商部分找到有关每个提供商的更多信息。
工具选择选项
您可以使用 tool_choice
参数控制何时以及调用哪些函数。
tool_choice
参数用于控制模型何时调用函数。在大多数情况下,我们使用 auto
,这意味着模型将决定何时调用函数(0 次或多次)。
# Let the model decide (default)
response = client.chat.completions.create(
model="deepseek-ai/DeepSeek-R1-0528",
messages=messages,
tools=tools,
tool_choice="auto" # Model decides when to call functions
)
然而,在某些用例中,您可能希望强制模型调用函数,以便它从不根据自己的知识回复,而只根据函数调用结果回复。
# Force the model to call at least one function
response = client.chat.completions.create(
model="deepseek-ai/DeepSeek-R1-0528",
messages=messages,
tools=tools,
tool_choice="required" # Must call at least one function
)
如果您有简单的函数,这会很好用,但如果您有更复杂的函数,您可能希望使用 tool_choice
参数强制模型至少调用一次特定函数。
例如,假设您的助手的唯一工作是提供给定位置的天气。您可能希望强制模型调用 get_current_weather
函数,而不调用任何其他函数。
# Force a specific function call
response = client.chat.completions.create(
model="deepseek-ai/DeepSeek-R1-0528",
messages=messages,
tools=tools,
tool_choice={
"type": "function",
"function": {"name": "get_current_weather"}
}
)
在这里,我们强制模型调用 get_current_weather
函数,而不调用任何其他函数。
严格模式
使用严格模式可确保函数调用完全遵循您的模式。这有助于防止模型使用意外参数调用函数,或调用不存在的函数。
# Define tools with strict mode
tools = [
{
"type": "function",
"function": {
"name": "get_current_weather",
"description": "Get current weather for a location",
"parameters": {
"type": "object",
"properties": {
"location": {"type": "string", "description": "City name"},
},
"required": ["location"],
+ "additionalProperties": False, # Strict mode requirement
},
+ "strict": True, # Enable strict mode
},
},
]
严格模式确保函数参数与您的模式完全匹配:不允许使用额外属性,必须提供所有必需参数,并且严格执行数据类型。
并非所有提供商都支持严格模式。您可以查看提供商的文档以了解它是否支持严格模式。
流式响应
启用流式传输以实现带有函数调用的实时响应。这对于向用户显示模型的进度或更有效地处理长时间运行的函数调用很有用。
# Enable streaming with function calls
stream = client.chat.completions.create(
model="deepseek-ai/DeepSeek-R1-0528",
messages=messages,
tools=tools,
tool_choice="auto",
stream=True # Enable streaming
)
# Process the stream
for chunk in stream:
if chunk.choices[0].delta.tool_calls:
# Handle tool call chunks
tool_calls = chunk.choices[0].delta.tool_calls
if chunk.choices[0].delta.content:
# Handle content chunks
content = chunk.choices[0].delta.content
流式传输允许您在响应到达时处理它们,向用户显示实时进度,并更有效地处理长时间运行的函数调用。
并非所有提供商都支持流式传输。您可以查看提供商的文档以了解它是否支持流式传输,或者您可以参考此动态模型兼容性表。
后续步骤
现在您已经了解了如何使用函数调用与推理提供商,您可以开始构建自己的代理和助手了!为什么不尝试以下一些想法呢
- 尝试更小的模型以获得更快的响应和更低的成本
- 构建一个可以获取实时数据的代理
- 使用推理模型构建一个可以与外部工具进行推理的代理