Function Calling 函数调用
大模型与外部世界的接口:从"能说"到"能做"
"2023年7月,OpenAI发布了Function Calling。在那之前,AI只会说话;在那之后,AI开始做事情。这不是一个功能的更新,这是一次进化——从鹦鹉变成助手。"
📱 一句话理解
Function Calling = 教AI调用函数。你预先定义好函数(如 get_weather、search_db),AI在对话中识别到需要这些功能时,会自动生成符合规范的函数调用请求,由你的代码执行后返回结果。
💡 周星驰式吐槽理解
想象你有一个超级聪明但被关在笼子里的大脑。他能回答任何问题,但他摸不到外面的东西。Function Calling就是给笼子开了个窗口——外面放个计算器,他说"调用calculate(2+3)",你帮他算出5,递回去。AI还是AI,但你帮他执行了动作,然后告诉他结果。他就是那个出主意的,你是那个干活的。
🧠 工作原理
Function Calling的核心流程:
1. 定义函数(告诉AI有哪些工具)
functions = [{
"name": "get_weather",
"description": "获取城市天气",
"parameters": {
"city": {"type": "string"}
}
}]
2. 用户提问(触发函数调用)
用户: "北京今天天气如何?"
3. AI判断需要调用函数
AI: → 识别到需要天气信息
→ 生成函数调用:
{
"name": "get_weather",
"arguments": {"city": "北京"}
}
4. 你的代码执行函数
result = get_weather(city="北京")
→ {"temp": 25, "weather": "晴"}
5. 将结果返回给AI
AI: → 看到结果
→ 组织语言回复:
"北京今天晴天,气温25°C"
关键点:AI不直接执行函数,它只生成调用请求,由你的应用执行。
⚡ OpenAI API实战
基本调用
import openai
client = openai.OpenAI()
# 定义可用的函数
functions = [
{
"name": "get_weather",
"description": "获取指定城市的天气信息",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称,如北京、上海"
}
},
"required": ["city"]
}
}
]
# 发送请求
response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": "北京天气怎么样?"}],
functions=functions,
function_call="auto" # auto/forced/none
)
# 检查是否调用了函数
if response.choices[0].finish_reason == "function_call":
func_call = response.choices[0].message.function_call
print(f"AI想调用: {func_call.name}")
print(f"参数: {func_call.arguments}")
# 执行函数并返回结果...
并行调用(Parallel Tool Calling)
GPT-4o支持同时调用多个函数:
用户: "查一下北京和上海明天的天气"
AI: → 同时生成两个函数调用:
{"name": "get_weather", "arguments": {"city": "北京"}}
{"name": "get_weather", "arguments": {"city": "上海"}}
→ 并行执行两个请求
→ 等待所有结果返回
→ 综合回答
🎭 Anthropic Claude实战
Claude使用 tool_use 格式:
import anthropic
client = anthropic.Anthropic()
response = client.messages.create(
model="claude-sonnet-4-20250514",
max_tokens=1024,
tools=[
{
"name": "get_weather",
"description": "获取天气信息",
"input_schema": {
"type": "object",
"properties": {
"city": {"type": "string"}
},
"required": ["city"]
}
}
],
messages=[{
"role": "user",
"content": "北京天气如何?"
}]
)
# 检查工具调用
for content in response.content:
if content.type == "tool_use":
print(f"工具: {content.name}")
print(f"参数: {content.input}")
# 执行工具并继续对话...
💡 最佳实践
- 函数名要描述性:get_weather 比 gw 好
- description是关键:AI靠描述判断调用时机
- 参数要简单:过多层级嵌套会让AI困惑
- 返回结果要结构化:JSON格式方便AI解析
- 要有超时机制:函数执行卡住会影响用户体验
- 错误处理要友好:函数失败时给AI有意义的错误信息
🔥 高级技巧
1. Structured Output(结构化输出)
强制AI返回特定JSON格式:
response = client.chat.completions.create(
model="gpt-4o-2024-08-06",
messages=[...],
response_format={
"type": "json_schema",
"json_schema": {
"name": "weather_response",
"schema": {
"type": "object",
"properties": {
"city": {"type": "string"},
"temp": {"type": "number"},
"condition": {"type": "string"}
},
"required": ["city", "temp"]
}
}
}
)
2. Chain-of-Tool-Calls(工具调用链)
多步骤任务,一个函数的输出作为下一个函数的输入:
用户: "找一下北京最便宜的酒店"
Step 1: search_hotels(city="北京") → [酒店列表]
Step 2: get_lowest_price(hotels=[...]) → 最便宜酒店
Step 3: book_hotel(hotel_id=xxx, dates=...) → 预订结果