下面是一个完整的 Function Calling 示例代码,使用 Python 和 OpenAI API 实现天气查询功能:

import json
from openai import OpenAI
import os

# 设置您的 OpenAI API 密钥
os.environ["OPENAI_API_KEY"] = "sk-xxx"  # 替换为您的实际密钥
client = OpenAI()

# 1. 定义函数工具
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_current_weather",
            "description": "获取指定城市的当前天气信息",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "城市名称,如:'北京市'",
                    },
                    "unit": {
                        "type": "string",
                        "enum": ["celsius", "fahrenheit"],
                        "description": "温度单位,默认为摄氏度",
                        "default": "celsius"
                    }
                },
                "required": ["location"],
            },
        },
    }
]

# 模拟天气API - 实际应用中替换为真实API调用
def get_current_weather(location, unit="celsius"):
    """模拟天气数据查询"""
    weather_data = {
        "北京": {"temperature": 23, "unit": unit, "condition": "晴朗", "humidity": 45},
        "上海": {"temperature": 28, "unit": unit, "condition": "多云", "humidity": 70},
        "广州": {"temperature": 32, "unit": unit, "condition": "雷阵雨", "humidity": 85},
        "深圳": {"temperature": 31, "unit": unit, "condition": "阵雨", "humidity": 80},
        "纽约": {"temperature": 68, "unit": "fahrenheit", "condition": "小雨", "humidity": 60},
    }
    
    # 查找城市,支持简写
    for city in weather_data:
        if city.startswith(location):
            return weather_data[city]
    
    # 默认返回
    return {"temperature": 25, "unit": unit, "condition": "未知", "humidity": 50}

# 2. 用户提问
def ask_question(question):
    messages = [{"role": "user", "content": question}]
    
    # 3. 调用模型
    response = client.chat.completions.create(
        model="gpt-3.5-turbo-1106",  # 或 gpt-4
        messages=messages,
        tools=tools,
        tool_choice="auto",
    )
    
    response_message = response.choices[0].message
    tool_calls = response_message.tool_calls
    
    # 4. 检查是否需要调用函数
    if tool_calls:
        print("检测到函数调用请求...")
        messages.append(response_message)  # 添加模型回复到上下文
        
        # 处理所有函数调用请求
        for tool_call in tool_calls:
            function_name = tool_call.function.name
            arguments = json.loads(tool_call.function.arguments)
            
            print(f"调用函数: {function_name},参数: {arguments}")
            
            # 5. 执行函数
            if function_name == "get_current_weather":
                location = arguments.get("location")
                unit = arguments.get("unit", "celsius")
                function_response = get_current_weather(location, unit)
                
                # 6. 将结果返回给模型
                messages.append({
                    "role": "tool",
                    "tool_call_id": tool_call.id,
                    "name": function_name,
                    "content": json.dumps(function_response),
                })
        
        # 7. 获取最终回复
        final_response = client.chat.completions.create(
            model="gpt-3.5-turbo-1106",
            messages=messages,
        )
        return final_response.choices[0].message.content
    
    # 没有函数调用直接返回
    return response_message.content

# 测试不同查询
queries = [
    "北京今天天气如何?",
    "上海的气温是多少?用摄氏度",
    "广州和深圳的湿度分别是多少?",
    "纽约现在的天气情况,用华氏度",
    "帮我比较一下北京和上海的天气"
]

# 执行所有查询
for query in queries:
    print(f"\n用户提问: {query}")
    response = ask_question(query)
    print(f"AI回复: {response}")
    print("-" * 60)

代码说明

  1. 函数定义

  • 定义天气查询函数 get_current_weather 的规范(名称、描述、参数)

  • 使用 JSON Schema 指定参数结构和约束

  1. 模拟天气服务

  • 创建了模拟天气数据(实际应用中替换为真实 API)

  • 支持城市名称模糊匹配

  1. 核心流程

  • 用户提问 → 模型判断 → 函数调用 → 执行函数 → 结果返回 → 生成最终回复

  • 支持多函数调用(如同时查询多个城市)

  1. 错误处理

  • 包含默认参数值(unit 默认为摄氏度)

  • 处理未知城市的情况

运行示例输出

用户提问: 北京今天天气如何?
检测到函数调用请求...
调用函数: get_current_weather,参数: {'location': '北京'}
AI回复: 北京当前天气晴朗,气温23摄氏度,湿度45%。
------------------------------------------------------------

用户提问: 上海的气温是多少?用摄氏度
检测到函数调用请求...
调用函数: get_current_weather,参数: {'location': '上海', 'unit': 'celsius'}
AI回复: 上海当前气温28摄氏度。
------------------------------------------------------------

用户提问: 广州和深圳的湿度分别是多少?
检测到函数调用请求...
调用函数: get_current_weather,参数: {'location': '广州'}
调用函数: get_current_weather,参数: {'location': '深圳'}
AI回复: 广州当前湿度85%,深圳当前湿度80%。
------------------------------------------------------------

用户提问: 纽约现在的天气情况,用华氏度
检测到函数调用请求...
调用函数: get_current_weather,参数: {'location': '纽约', 'unit': 'fahrenheit'}
AI回复: 纽约当前天气小雨,气温68华氏度,湿度60%。
------------------------------------------------------------

用户提问: 帮我比较一下北京和上海的天气
检测到函数调用请求...
调用函数: get_current_weather,参数: {'location': '北京'}
调用函数: get_current_weather,参数: {'location': '上海'}
AI回复: 北京和上海天气对比:
- 北京:晴朗,23°C,湿度45%
- 上海:多云,28°C,湿度70%
上海比北京高5°C,湿度也更高。
------------------------------------------------------------

运行准备

  1. 安装必要库:

pip install openai python-dotenv
  1. 替换 API 密钥:

os.environ["OPENAI_API_KEY"] = "sk-your-actual-key"  # 替换为真实密钥
  1. 如需扩展功能:

  • 添加更多函数(如股票查询、航班搜索)

  • 集成真实 API(如 OpenWeatherMap)

  • 增加错误处理逻辑

  • 添加用户对话历史管理

这个示例完整展示了 Function Calling 的工作流程,从函数定义到实际调用再到结果整合,实现了大模型与现实世界数据的连接。