OpenAI Function Calling 教程

OpenAI Function Calling 让 GPT 模型能够调用外部函数,实现查询数据库、调用 API、执行计算等操作。本文介绍 Function Calling 的定义、调用流程和 Agent 构建方法。

Function Calling 原理

Function Calling 的工作流程:

  1. 开发者定义可用函数(名称、描述、参数 JSON Schema)
  2. GPT 分析用户请求,决定是否调用函数,并输出调用参数
  3. 开发者执行函数,将结果返回给 GPT
  4. GPT 根据函数结果生成最终回复

定义函数

from openai import OpenAI

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

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_stock_price",
            "description": "获取指定股票的当前价格和涨跌幅",
            "parameters": {
                "type": "object",
                "properties": {
                    "symbol": {
                        "type": "string",
                        "description": "股票代码,如 AAPL、GOOGL、600519"
                    },
                    "market": {
                        "type": "string",
                        "enum": ["US", "CN", "HK"],
                        "description": "市场,US=美股,CN=A股,HK=港股"
                    }
                },
                "required": ["symbol"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "calculate_investment",
            "description": "计算投资收益,包括本金、利率和时间",
            "parameters": {
                "type": "object",
                "properties": {
                    "principal": {"type": "number", "description": "本金(元)"},
                    "annual_rate": {"type": "number", "description": "年化利率(%)"},
                    "years": {"type": "number", "description": "投资年限"}
                },
                "required": ["principal", "annual_rate", "years"]
            }
        }
    }
]

处理函数调用

import json

def get_stock_price(symbol, market="US"):
    """模拟股票查询"""
    prices = {
        "AAPL": {"price": 198.50, "change": "+1.2%"},
        "GOOGL": {"price": 175.30, "change": "-0.5%"},
        "600519": {"price": 1685.00, "change": "+0.8%"}
    }
    return prices.get(symbol, {"price": 0, "change": "未知"})

def calculate_investment(principal, annual_rate, years):
    """计算复利收益"""
    total = principal * (1 + annual_rate / 100) ** years
    return {"total": round(total, 2), "profit": round(total - principal, 2)}

# 函数映射
function_map = {
    "get_stock_price": get_stock_price,
    "calculate_investment": calculate_investment
}

# 第一次调用
response = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "苹果股票现在多少钱?如果投10万美元,年化10%,5年后能有多少?"}],
    tools=tools,
    tool_choice="auto"
)

message = response.choices[0].message

# 处理工具调用
if message.tool_calls:
    messages = [
        {"role": "user", "content": "苹果股票现在多少钱?如果投10万美元,年化10%,5年后能有多少?"},
        message
    ]

    for tool_call in message.tool_calls:
        func_name = tool_call.function.name
        func_args = json.loads(tool_call.function.arguments)

        # 执行函数
        result = function_map[func_name](**func_args)

        messages.append({
            "role": "tool",
            "tool_call_id": tool_call.id,
            "content": json.dumps(result, ensure_ascii=False)
        })

    # 第二次调用:让 GPT 基于函数结果生成回复
    final_response = client.chat.completions.create(
        model="gpt-4o",
        messages=messages,
        tools=tools
    )
    print(final_response.choices[0].message.content)

Node.js 示例

import OpenAI from 'openai';

const client = new OpenAI({
  apiKey: 'your-api-key',
  baseURL: 'https://claude4u.com/v1'
});

const tools = [{
  type: 'function',
  function: {
    name: 'search_products',
    description: '搜索商品信息',
    parameters: {
      type: 'object',
      properties: {
        keyword: { type: 'string', description: '搜索关键词' },
        max_price: { type: 'number', description: '最高价格' }
      },
      required: ['keyword']
    }
  }
}];

const response = await client.chat.completions.create({
  model: 'gpt-4o',
  messages: [{ role: 'user', content: '帮我搜索500元以下的蓝牙耳机' }],
  tools,
  tool_choice: 'auto'
});

// 处理 tool_calls
const toolCalls = response.choices[0].message.tool_calls;
if (toolCalls) {
  for (const call of toolCalls) {
    console.log(`调用函数: ${call.function.name}`);
    console.log(`参数: ${call.function.arguments}`);
  }
}

构建循环 Agent

def run_agent(user_message, tools, function_map, max_iterations=10):
    messages = [{"role": "user", "content": user_message}]

    for _ in range(max_iterations):
        response = client.chat.completions.create(
            model="gpt-4o",
            messages=messages,
            tools=tools,
            tool_choice="auto"
        )

        message = response.choices[0].message
        messages.append(message)

        # 没有工具调用,返回最终回复
        if not message.tool_calls:
            return message.content

        # 执行所有工具调用
        for tool_call in message.tool_calls:
            func = function_map[tool_call.function.name]
            args = json.loads(tool_call.function.arguments)
            result = func(**args)
            messages.append({
                "role": "tool",
                "tool_call_id": tool_call.id,
                "content": json.dumps(result, ensure_ascii=False)
            })

    return "Agent 达到最大迭代次数"

函数设计最佳实践

提示:通过 claude4u.com 轻舟 AI 中转服务使用 Function Calling,兼容 OpenAI 和 Claude 的工具调用格式,可以方便地在不同模型之间切换,对比效果选择最优方案。
注意:GPT 生成的函数参数可能不完全符合预期,务必在执行前做参数验证。不要让函数直接执行数据库删除等危险操作,应添加确认步骤。

Start Using 轻舟 AI

Stable, fast AI API relay — supports Claude, OpenAI, Gemini and more

Sign Up Now