详解 OpenAI 函数调用(Function Calling):让模型具备数据获取与行动能力

详解 OpenAI 函数调用(Function Calling):让模型具备数据获取与行动能力

在人工智能应用开发中,让大模型能够与外部系统交互是提升其实用性的关键。OpenAI 的函数调用(Function Calling) 功能为此提供了强大支持,使模型能调用自定义代码或外部服务,实现数据获取与行动执行。本文将详细介绍函数调用的使用方法、核心场景及实践技巧,并结合实际案例说明如何快速上手。

什么是函数调用?

函数调用是 OpenAI 模型与外部代码或服务交互的桥梁。通过定义函数 schema,模型可根据用户输入和系统提示,自主决定调用哪些函数(而非仅生成文本),并在获取函数执行结果后,整合结果生成最终响应。

简单来说,函数调用让模型从“被动回答”升级为“主动行动”,主要解决两类问题:

  • 数据获取:获取实时信息(如天气、知识库内容),弥补模型训练数据时效性不足的问题;
  • 执行行动:触发外部操作(如发送邮件、提交表单、调用 API 等),实现自动化流程。

快速上手:函数调用示例

以下通过三个常见场景(获取天气、发送邮件、搜索知识库)展示函数调用的基本用法,所有示例均已适配 https://api.aaaaapi.com 端点(推荐通过 API 中转站 访问,提升稳定性)。

示例 1:获取天气(get_weather)

该函数用于获取指定地点的当前温度,需传入“城市+国家”格式的位置参数。

Python 实现

from openai import OpenAI

# 配置 API 中转站端点
client = OpenAI(
    base_url="https://api.aaaaapi.com/v1",
    api_key="your-api-key"  # 替换为你的 API 密钥
)

# 定义工具(函数)
tools = [{
    "type": "function",
    "name": "get_weather",
    "description": "获取指定地点的当前温度。",
    "parameters": {
        "type": "object",
        "properties": {
            "location": {
                "type": "string",
                "description": "城市和国家,例如:波哥大,哥伦比亚"
            }
        },
        "required": ["location"],
        "additionalProperties": False
    }
}]

# 调用模型,触发函数调用
response = client.responses.create(
    model="gpt-4.1",
    input=[{"role": "user", "content": "今天巴黎的天气怎么样?"}],
    tools=tools
)

print(response.output)

JavaScript 实现

import { OpenAI } from "openai";

// 配置 API 中转站端点
const openai = new OpenAI({
  baseURL: "https://api.aaaaapi.com/v1",
  apiKey: "your-api-key"  // 替换为你的 API 密钥
});

const tools = [{
    "type": "function",
    "name": "get_weather",
    "description": "获取指定地点的当前温度。",
    "parameters": {
        "type": "object",
        "properties": {
            "location": {
                "type": "string",
                "description": "城市和国家,例如:波哥大,哥伦比亚"
            }
        },
        "required": ["location"],
        "additionalProperties": false
    }
}];

const response = await openai.responses.create({
    model: "gpt-4.1",
    input: [{ role: "user", content: "今天巴黎的天气怎么样?" }],
    tools,
});

console.log(response.output);

接口调用(curl)

curl https://api.aaaaapi.com/v1/responses \
-H "Content-Type: application/json" \
-H "Authorization: Bearer your-api-key" \
-d '{
    "model": "gpt-4.1",
    "input": "今天巴黎的天气怎么样?",
    "tools": [
        {
            "type": "function",
            "name": "get_weather",
            "description": "获取指定地点的当前温度。",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "城市和国家,例如:波哥大,哥伦比亚"
                    }
                },
                "required": ["location"],
                "additionalProperties": false
            }
        }
    ]
}'

输出结果

[{
    "type": "function_call",
    "id": "fc_12345xyz",
    "call_id": "call_12345xyz",
    "name": "get_weather",
    "arguments": "{\"location\":\"巴黎,法国\"}"
}]

示例 2:发送邮件(send_email)

该函数用于向指定邮箱发送邮件,需传入收件人、主题和正文参数。

Python 实现(核心代码)

tools = [{
    "type": "function",
    "name": "send_email",
    "description": "向指定收件人发送包含主题和内容的邮件。",
    "parameters": {
        "type": "object",
        "properties": {
            "to": {"type": "string", "description": "收件人邮箱地址"},
            "subject": {"type": "string", "description": "邮件主题"},
            "body": {"type": "string", "description": "邮件正文内容"}
        },
        "required": ["to", "subject", "body"],
        "additionalProperties": False
    }
}]

# 用户输入:"请向 ilan@example.com 和 katia@example.com 发送一封问候邮件"
response = client.responses.create(model="gpt-4.1", input=[{"role": "user", "content": "请向 ilan@example.com 和 katia@example.com 发送一封问候邮件"}], tools=tools)
print(response.output)

输出结果

[
    {
        "type": "function_call",
        "id": "fc_12345xyz",
        "call_id": "call_9876abc",
        "name": "send_email",
        "arguments": "{\"to\":\"ilan@example.com\",\"subject\":\"你好!\",\"body\":\"只想说声嗨~\"}"
    },
    {
        "type": "function_call",
        "id": "fc_12345xyz",
        "call_id": "call_9876abc",
        "name": "send_email",
        "arguments": "{\"to\":\"katia@example.com\",\"subject\":\"你好!\",\"body\":\"只想说声嗨~\"}"
    }
]

示例 3:搜索知识库(search_knowledge_base)

该函数用于查询知识库,支持指定查询内容、结果数量、领域过滤和排序方式。

输出结果示例

[{
    "type": "function_call",
    "id": "fc_12345xyz",
    "call_id": "call_4567xyz",
    "name": "search_knowledge_base",
    "arguments": "{\"query\":\"什么是 ChatGPT?\",\"options\":{\"num_results\":3,\"domain_filter\":null,\"sort_by\":\"relevance\"}}"
}]

函数调用工作流程

函数调用的完整流程分为以下步骤,结合图示更易理解:

函数调用流程图

  1. 定义函数:通过 tools 参数传入函数 schema,告知模型函数的用途和参数格式;
  2. 模型决定调用:模型根据用户输入,生成函数调用指令(包含函数名和参数);
  3. 执行函数:解析模型输出,调用对应的自定义代码(如获取天气数据、发送邮件);
  4. 返回结果:将函数执行结果回传给模型;
  5. 生成最终响应:模型整合结果,生成自然语言回答。

定义函数的核心要素

函数 schema 是模型理解函数的关键,需包含以下字段:

字段 说明
type 固定为 "function"
name 函数名称(如 get_weather)
description 函数用途和使用场景(需详细清晰)
parameters 函数参数的 JSON schema 定义
strict 是否启用严格模式(推荐设为 true)

定义参数的最佳实践

  • 详细描述:为每个参数添加清晰的说明(如 location 参数注明“城市+国家”格式);
  • 指定类型:明确参数类型(string、number、object 等),避免歧义;
  • 必填项:通过 required 数组指定必填参数,确保调用完整性;
  • 限制范围:用 enum 约束可选值(如温度单位只能是 celsius/fahrenheit)。

示例:带参数约束的函数定义

{
  "type": "function",
  "name": "get_weather",
  "description": "获取指定地点的当前天气。",
  "parameters": {
    "type": "object",
    "properties": {
      "location": {
        "type": "string",
        "description": "城市和国家,例如:波哥大,哥伦比亚"
      },
      "units": {
        "type": "string",
        "enum": ["celsius", "fahrenheit"],
        "description": "温度单位"
      }
    },
    "required": ["location", "units"],
    "additionalProperties": false
  },
  "strict": true
}

处理函数调用的步骤

  1. 解析模型输出:从 response.output 中提取函数调用信息(name、arguments、call_id);
  2. 执行函数:根据函数名路由到对应的实现代码,传入解析后的参数;
  3. 格式化结果:将执行结果转为字符串(支持 JSON、文本等格式);
  4. 回传结果:通过 function_call_output 类型消息将结果返回给模型;
  5. 获取最终响应:模型整合结果后生成自然语言回答。

示例:执行函数并回传结果(Python)

import json

# 解析模型输出的函数调用
tool_call = response.output[0]
args = json.loads(tool_call.arguments)

# 执行自定义函数(如获取天气)
def get_weather(location):
    # 实际实现:调用天气API获取数据
    return {"temperature": 14, "unit": "celsius"}

result = get_weather(args["location"])

# 回传结果给模型
input_messages = [
    {"role": "user", "content": "今天巴黎的天气怎么样?"},
    tool_call,  # 模型的函数调用指令
    {
        "type": "function_call_output",
        "call_id": tool_call.call_id,
        "output": json.dumps(result)  # 函数执行结果
    }
]

# 模型生成最终回答
final_response = client.responses.create(
    model="gpt-4.1",
    input=input_messages,
    tools=tools,
    base_url="https://api.aaaaapi.com/v1"
)
print(final_response.output_text)  # 输出:"巴黎当前温度为14°C。"

高级配置选项

工具调用策略(tool_choice)

通过 tool_choice 参数控制模型调用行为:

  • "auto"(默认):模型自主决定是否调用函数;
  • "required":强制模型至少调用一个函数;
  • {"type": "function", "name": "get_weather"}:强制调用指定函数。

并行调用(parallel_tool_calls)

设置为 false 时,模型每次只能调用一个函数(默认支持并行调用多个函数)。

流式传输(Streaming)

通过 stream=true 实时获取函数调用过程,适用于需要展示进度的场景。示例:

stream = client.responses.create(
    model="gpt-4.1",
    input=[{"role": "user", "content": "今天巴黎的天气怎么样?"}],
    tools=tools,
    stream=True,
    base_url="https://api.aaaaapi.com/v1"
)

for event in stream:
    if event.type == "response.function_call_arguments.delta":
        print(f"函数参数更新:{event.delta}")

实际应用建议

  1. 使用可靠的 API 服务:在生产环境中,推荐通过 API 中转站 访问 https://api.aaaaapi.com 端点,提升调用稳定性和响应速度;
  2. 错误处理:函数执行失败时,返回明确的错误信息(如“邮箱格式无效”),便于模型调整;
  3. 迭代优化:根据模型调用日志,优化函数描述和参数定义,减少无效调用;
  4. 结合 RAG:将函数调用与知识库检索结合,实现“实时数据 + 私有知识”的混合回答。

通过函数调用,开发者可让大模型突破自身限制,与外部系统无缝协作,实现从信息查询到自动执行的全流程能力。合理设计函数和调用逻辑,能显著提升 AI 应用的实用性和扩展性。如需快速体验,可通过 https://link.ywhttp.com/foA8Wb 接入稳定的 API 服务,开始你的函数调用开发之旅。

posted @ 2025-07-29 16:43  大A就是我  阅读(516)  评论(0)    收藏  举报