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}")
        # 执行工具并继续对话...

💡 最佳实践

🔥 高级技巧

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=...) → 预订结果

📚 相关教程