本文目录导读:

我来详细解释AI模型中的工具调用(Function Calling/Tool Calling)接口设计和使用。
工具调用接口概述
工具调用允许LLM在对话过程中调用预定义的外部函数或API,获取实时数据或执行操作。
标准化接口结构
工具定义格式
# 工具定义示例
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "获取指定城市的天气信息",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称"
},
"units": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "温度单位"
}
},
"required": ["city"]
}
}
}
]
API调用格式
# OpenAI风格调用
import openai
response = openai.chat.completions.create(
model="gpt-4",
messages=[
{"role": "user", "content": "北京今天天气怎么样?"}
],
tools=tools,
tool_choice="auto" # auto, none, or {"type": "function", "function": {"name": "get_weather"}}
)
响应处理流程
解析工具调用请求
# 解析模型返回的工具调用
def process_tool_call(response):
message = response.choices[0].message
if message.tool_calls:
for tool_call in message.tool_calls:
function_name = tool_call.function.name
arguments = json.loads(tool_call.function.arguments)
# 执行实际函数
if function_name == "get_weather":
result = get_weather(arguments["city"], arguments.get("units", "celsius"))
# 返回结果给模型
yield {
"tool_call_id": tool_call.id,
"function_name": function_name,
"result": result
}
完整的多轮调用示例
def chat_with_tools():
messages = [{"role": "user", "content": "北京和上海哪个城市今天更暖和?"}]
while True:
response = client.chat.completions.create(
model="gpt-4",
messages=messages,
tools=tools
)
message = response.choices[0].message
if message.tool_calls:
messages.append(message)
for tool_call in message.tool_calls:
# 执行工具
result = execute_tool(tool_call)
# 将结果添加回消息
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": json.dumps(result)
})
else:
# 模型最终回复
return message.content
不同模型的工具调用格式
OpenAI
# OpenAI格式
response = openai.chat.completions.create(
model="gpt-4-turbo-preview",
messages=[...],
tools=[...], # 或 functions=[...] (旧版)
tool_choice="auto"
)
Anthropic Claude
# Claude格式
response = anthropic.messages.create(
model="claude-3-opus-20240229",
messages=[...],
tools=[
{
"name": "get_weather",
"description": "获取天气信息",
"input_schema": {
"type": "object",
"properties": {
"city": {"type": "string"}
},
"required": ["city"]
}
}
]
)
Google Gemini
# Gemini格式
model = genai.GenerativeModel('gemini-pro')
response = model.generate_content(
"北京天气怎么样?",
tools=[
{
"function_declarations": [
{
"name": "get_weather",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string"}
},
"required": ["city"]
}
}
]
}
]
)
高级实现模式
并行工具调用
# 模型可能同时调用多个工具
def handle_parallel_tool_calls(response):
calls = response.choices[0].message.tool_calls
# 使用线程池并行执行
with ThreadPoolExecutor() as executor:
futures = []
for tool_call in calls:
future = executor.submit(execute_tool, tool_call)
futures.append((tool_call.id, future))
# 收集结果
results = []
for call_id, future in futures:
result = future.result()
results.append({
"tool_call_id": call_id,
"content": json.dumps(result)
})
return results
工具注册装饰器
tool_registry = {}
def tool(name, description, parameters):
def decorator(func):
tool_registry[name] = {
"function": func,
"definition": {
"type": "function",
"function": {
"name": name,
"description": description,
"parameters": parameters
}
}
}
return func
return decorator
# 使用装饰器定义工具
@tool(
name="search_database",
description="搜索数据库中的记录",
parameters={
"type": "object",
"properties": {
"query": {"type": "string"},
"limit": {"type": "integer", "default": 10}
},
"required": ["query"]
}
)
def search_database(query: str, limit: int = 10):
# 实现数据库搜索
return results
错误处理与重试
def safe_tool_call(tool_call, max_retries=3):
for attempt in range(max_retries):
try:
result = execute_tool(tool_call)
return {
"tool_call_id": tool_call.id,
"content": json.dumps(result),
"status": "success"
}
except ToolError as e:
if attempt == max_retries - 1:
return {
"tool_call_id": tool_call.id,
"content": json.dumps({
"error": str(e),
"message": "工具执行失败,请重试或使用其他方式回答"
}),
"status": "error"
}
time.sleep(1 * (attempt + 1))
最佳实践建议
工具命名规范
- 使用蛇形命名(snake_case)
- 动词开头(get, search, create, update, delete_)
- 明确描述功能
参数设计原则
- 参数类型明确定义
- 提供合理的默认值
- 设置清晰的枚举值
- 写入易懂的描述
安全性考量
# 验证工具调用权限
def validate_tool_call(user_id, tool_name, arguments):
# 检查用户权限
if not has_permission(user_id, tool_name):
raise PermissionError(f"User {user_id} cannot call {tool_name}")
# 参数验证
if tool_name == "delete_user":
if not is_admin(user_id):
raise PermissionError("Only admins can delete users")
return True
工具调用接口的设计重点是清晰、安全和可扩展,让模型能够可靠地发现和使用外部功能。