函数调用

使用函数调用让模型调用外部工具

函数调用

函数调用(Function Calling)让模型能够调用外部工具和 API,实现更强大的功能。

什么是函数调用

函数调用允许模型:

  • 调用外部 API 获取实时数据
  • 执行计算和数据处理
  • 与数据库交互
  • 调用第三方服务

基本用法

1. 定义函数

from openai import OpenAI
import json

client = OpenAI(
    api_key="your-api-key",
    base_url="https://api.agicto.cn/v1"
)

# 定义函数描述
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "获取指定城市的天气信息",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {
                        "type": "string",
                        "description": "城市名称,例如:北京、上海"
                    },
                    "unit": {
                        "type": "string",
                        "enum": ["celsius", "fahrenheit"],
                        "description": "温度单位"
                    }
                },
                "required": ["city"]
            }
        }
    }
]

2. 调用模型

messages = [{"role": "user", "content": "北京今天天气怎么样?"}]

response = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=messages,
    tools=tools,
    tool_choice="auto"  # 让模型自动决定是否调用函数
)

# 检查是否需要调用函数
if response.choices[0].message.tool_calls:
    tool_call = response.choices[0].message.tool_calls[0]
    function_name = tool_call.function.name
    function_args = json.loads(tool_call.function.arguments)
    
    print(f"模型想调用函数: {function_name}")
    print(f"参数: {function_args}")

3. 执行函数并返回结果

# 实际的函数实现
def get_weather(city, unit="celsius"):
    # 这里应该调用真实的天气 API
    return {
        "city": city,
        "temperature": 22,
        "condition": "晴天",
        "unit": unit
    }

# 执行函数
if function_name == "get_weather":
    result = get_weather(**function_args)
    
    # 将结果返回给模型
    messages.append(response.choices[0].message)
    messages.append({
        "role": "tool",
        "tool_call_id": tool_call.id,
        "content": json.dumps(result, ensure_ascii=False)
    })
    
    # 获取最终回复
    final_response = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=messages
    )
    
    print(final_response.choices[0].message.content)

完整示例

天气查询助手

import json
from openai import OpenAI

client = OpenAI(
    api_key="your-api-key",
    base_url="https://api.agicto.cn/v1"
)

# 定义多个函数
tools = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "获取城市天气",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {"type": "string", "description": "城市名称"}
                },
                "required": ["city"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "get_time",
            "description": "获取当前时间",
            "parameters": {
                "type": "object",
                "properties": {}
            }
        }
    }
]

# 函数实现
def get_weather(city):
    return f"{city}今天晴天,温度22度"

def get_time():
    from datetime import datetime
    return datetime.now().strftime("%Y-%m-%d %H:%M:%S")

# 可用函数映射
available_functions = {
    "get_weather": get_weather,
    "get_time": get_time
}

# 对话
messages = [{"role": "user", "content": "北京天气怎么样?现在几点了?"}]

response = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=messages,
    tools=tools
)

# 处理函数调用
while response.choices[0].message.tool_calls:
    messages.append(response.choices[0].message)
    
    for tool_call in response.choices[0].message.tool_calls:
        function_name = tool_call.function.name
        function_args = json.loads(tool_call.function.arguments)
        
        # 执行函数
        function_response = available_functions[function_name](**function_args)
        
        # 添加函数结果
        messages.append({
            "role": "tool",
            "tool_call_id": tool_call.id,
            "content": str(function_response)
        })
    
    # 继续对话
    response = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=messages,
        tools=tools
    )

print(response.choices[0].message.content)

强制调用函数

使用 tool_choice 参数强制模型调用特定函数:

# 强制调用特定函数
response = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[{"role": "user", "content": "帮我查天气"}],
    tools=tools,
    tool_choice={"type": "function", "function": {"name": "get_weather"}}
)

并行函数调用

模型可以同时调用多个函数:

response = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[{"role": "user", "content": "查一下北京和上海的天气"}],
    tools=tools,
    parallel_tool_calls=True  # 启用并行调用
)

# 处理多个函数调用
for tool_call in response.choices[0].message.tool_calls:
    function_name = tool_call.function.name
    function_args = json.loads(tool_call.function.arguments)
    print(f"调用: {function_name}({function_args})")

支持的模型

以下模型支持函数调用:

  • GPT 系列: gpt-4o, gpt-4o-mini, gpt-4-turbo
  • Claude 系列: claude-3.5-sonnet, claude-3-opus
  • Gemini 系列: gemini-2.0-flash, gemini-1.5-pro
  • DeepSeek: deepseek-v3
  • 国产模型: qwen-max, qwen-plus

最佳实践

  1. 清晰的函数描述 - 详细描述函数的功能和参数
  2. 参数验证 - 验证模型传递的参数
  3. 错误处理 - 处理函数执行中的错误
  4. 超时控制 - 设置函数执行超时
  5. 安全性 - 验证函数调用的安全性
def safe_function_call(function_name, function_args):
    try:
        # 验证函数名
        if function_name not in available_functions:
            return {"error": "未知函数"}
        
        # 验证参数
        # ... 参数验证逻辑
        
        # 执行函数(带超时)
        import signal
        signal.alarm(5)  # 5秒超时
        result = available_functions[function_name](**function_args)
        signal.alarm(0)
        
        return result
    except Exception as e:
        return {"error": str(e)}

实际应用场景

数据查询

  • 查询数据库
  • 调用搜索 API
  • 获取实时信息

自动化任务

  • 发送邮件
  • 创建日程
  • 文件操作

计算处理

  • 数学计算
  • 数据分析
  • 格式转换

查看 模型总览 了解所有可用模型。

函数调用 | Agicto Docs