Hugging Face 生成式 AI 服务 (HUGS) 文档
函数调用
加入 Hugging Face 社区
并获得增强的文档体验
开始使用
函数调用
函数调用是一项强大的功能,使大型语言模型 (LLM) 能够以结构化的方式与您的代码和外部系统进行交互。LLM 不仅仅生成文本响应,还可以理解何时调用特定函数,并提供必要的参数来执行现实世界的操作。
函数调用工作原理
该过程遵循以下步骤
此循环可以根据需要继续进行,从而允许应用程序和 LLM 之间进行复杂的多步骤交互。
用例示例
函数调用对于许多实际应用都很有用,例如
- 数据检索:将自然语言查询转换为 API 调用以获取数据(例如,“显示我最近的订单”触发数据库查询)
- 操作执行:将用户请求转换为特定的函数调用(例如,“安排会议”变为日历 API 调用)
- 计算任务:通过专用函数处理数学或逻辑运算(例如,计算复利或统计分析)
- 数据处理管道:将多个函数调用链接在一起(例如,获取数据 → 解析 → 转换 → 存储)
- UI/UX 集成:根据用户交互触发界面更新(例如,更新地图标记或显示图表)
使用工具(函数定义)
工具是为您 LLM 定义可调用函数的主要方式。每个工具都需要
- 唯一的名称
- 清晰的描述
- 定义预期参数的 JSON 模式
这是一个定义天气相关函数的示例
from huggingface_hub import InferenceClient
client = InferenceClient("http://localhost:8080") # Replace with your HUGS host
messages = [
{
"role": "system",
"content": "Don't make assumptions about values. Ask for clarification if needed.",
},
{
"role": "user",
"content": "What's the weather like the next 3 days in San Francisco, CA?",
},
]
tools = [
{
"type": "function",
"function": {
"name": "get_n_day_weather_forecast",
"description": "Get an N-day weather forecast",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The city and state, e.g. San Francisco, CA",
},
"format": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "The temperature unit to use",
},
"num_days": {
"type": "integer",
"description": "The number of days to forecast",
},
},
"required": ["location", "format", "num_days"],
},
},
}
]
response = client.chat_completion(
messages=messages,
tools=tools,
tool_choice="auto",
max_tokens=500,
)
print(response.choices[0].message.tool_calls[0].function)
# ChatCompletionOutputFunctionDefinition(arguments={'format': 'celsius', 'location': 'San Francisco, CA', 'num_days': 3}, name='get_n_day_weather_forecast', description=None)
模型将分析用户的请求,并生成对适当函数的结构化调用,并带有正确的参数。
使用 Pydantic 模型进行结构化输出
为了获得更好的类型安全性和验证,您可以使用 Pydantic 模型来定义函数模式。这种方法提供:
- 运行时类型检查
- 自动验证
- 更好的 IDE 支持
- 通过 Python 类型获得清晰的文档
以下是如何使用 Pydantic 模型进行函数调用
from pydantic import BaseModel, Field
from typing import List
class ParkObservation(BaseModel):
location: str = Field(..., description="Where the observation took place")
activity: str = Field(..., description="What activity was being done")
animals_seen: int = Field(..., description="Number of animals spotted", ge=1, le=5)
animals: List[str] = Field(..., description="List of animals observed")
client = InferenceClient("http://localhost:8080") # Replace with your HUGS host
response_format = {"type": "json", "value": ParkObservation.model_json_schema()}
messages = [
{
"role": "user",
"content": "I saw a puppy, a cat and a raccoon during my bike ride in the park.",
},
]
response = client.chat_completion(
messages=messages,
response_format=response_format,
max_tokens=500,
)
print(response.choices[0].message.content)
# { "activity": "bike ride",
# "animals": ["puppy", "cat", "raccoon"],
# "animals_seen": 3,
# "location": "the park"
# }
这将返回一个与您的模式匹配的 JSON 对象,使其易于在您的应用程序中解析和使用。
高级用法模式
链式函数调用
LLM 可以编排多个函数调用来完成复杂的任务
tools = [
{
"type": "function",
"function": {
"name": "search_products",
"description": "Search product catalog",
"parameters": {
"type": "object",
"properties": {
"query": {"type": "string"},
"category": {"type": "string", "enum": ["electronics", "clothing", "books"]}
}
}
}
},
{
"type": "function",
"function": {
"name": "create_order",
"description": "Create a new order",
"parameters": {
"type": "object",
"properties": {
"product_id": {"type": "string"},
"quantity": {"type": "integer", "minimum": 1}
}
}
}
}
]
错误处理和执行
始终在执行前验证函数调用
import json
def get_n_day_weather_forecast(location, format, num_days):
return '{"temperature": 70, "condition": "sunny"}'
def handle_tool_call(tool_call):
try:
args = tool_call.function.arguments
# Validate required parameters
if tool_call.function.name == "get_n_day_weather_forecast":
if not all(k in args for k in ["location", "format", "num_days"]):
raise ValueError("Missing required parameters")
# Only pass arguments that match the function's parameters
valid_args = {k: v for k, v in args.items()
if k in get_n_day_weather_forecast.__code__.co_varnames}
return get_n_day_weather_forecast(**valid_args)
except json.JSONDecodeError:
return {"error": "Invalid function arguments"}
except Exception as e:
return {"error": str(e)}
res = handle_tool_call(response.choices[0].message.tool_calls[0])
print(res)
# {"temperature": 70, "condition": "sunny"}
最佳实践
函数设计
- 保持函数名称清晰且具体
- 为函数和参数使用详细的描述
- 包含参数约束(最小值/最大值、枚举等)
错误处理
- 验证所有函数输入
- 为失败的函数调用实施适当的错误处理
- 考虑瞬时故障的重试逻辑
安全性
- 在执行前验证和清理所有输入
- 实施速率限制和访问控制
- 根据用户上下文考虑函数调用权限
切勿通过函数调用直接暴露敏感操作。始终实施适当的验证和授权检查。
有关基本推理能力的更多信息,请参阅我们的推理指南。
< > 在 GitHub 上更新