使用 OpenAI Function Calling 构建智能 AI 代理实战指南

背景介绍

大语言模型已经具备了强大的文本理解和生成能力。然而,单纯依靠模型自身的知识库,往往难以满足实际业务场景的需求。我们需要 AI 不仅能”思考”,还能”行动”——这就是 Function Calling 技术出现的背景。

Function Calling 是 OpenAI 在 2023 年 6 月推出的重要功能,它允许 GPT 模型在生成回复时主动调用外部函数或 API,从而实现与现实世界的连接。简单来说,你可以定义一些函数(如查询数据库、调用天气 API、发送邮件等),AI 会根据用户需求智能决定何时调用这些函数,并从中获取最新、最准确的信息。

这项技术的出现彻底改变了我们与 AI 交互的方式。传统的 chatbot 只能根据训练数据生成回答,而具备 Function Calling 能力的 AI 代理则可以实时获取最新数据、执行具体操作,真正成为了能够”干活”的智能助手。

问题描述

在实际开发中,我们经常遇到以下困境:

第一,知识库的局限性。GPT-4 的训练数据截止到特定日期,无法获取实时信息。比如用户问”今天北京的天气怎么样”,模型只能给出一般性描述,无法提供准确答案。

第二,无法执行具体操作。传统对话系统只能生成文本建议,无法真正帮用户执行任务。比如用户说”帮我订一张明天北京到上海的机票”,AI 只能回复建议,无法实际操作。

第三,多系统整合困难。企业通常有多个内部系统(CRM、ERP、数据库等),要让 AI 能够访问这些数据,需要复杂的工程实现。

Function Calling 正是为了解决这些问题而产生的。它提供了一种标准化的方式,让 AI 能够调用外部工具,突破自身限制,真正成为能够执行任务的智能代理。

详细步骤

步骤一:定义函数签名

首先,我们需要为 AI 定义可调用的函数。以天气查询为例,我们需要用 JSON Schema 格式定义函数签名:

functions = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "获取指定城市的天气信息",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {
                        "type": "string",
                        "description": "城市名称,如北京、上海"
                    },
                    "unit": {
                        "type": "string",
                        "enum": ["celsius", "fahrenheit"],
                        "description": "温度单位,默认为摄氏度"
                    }
                },
                "required": ["location"]
            }
        }
    }
]

这个定义告诉 AI:有这样一个函数可以获取天气,它需要城市名称作为必填参数,温度单位是可选参数。

步骤二:调用模型并处理响应

接下来,我们向模型发送用户请求:

import openai

openai.api_key = "your-api-key"

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

response = openai.chat.completions.create(
    model="gpt-4o",
    messages=messages,
    tools=functions,
    tool_choice="auto"
)

# 检查模型是否要求调用函数
response_message = response.choices[0].message

if response_message.tool_calls:
    # 提取函数调用信息
    for tool_call in response_message.tool_calls:
        function_name = tool_call.function.name
        function_args = json.loads(tool_call.function.arguments)
        
        print(f"AI 决定调用函数: {function_name}")
        print(f"参数: {function_args}")

步骤三:执行函数并返回结果

当模型决定调用函数时,我们需要实际执行该函数并将结果返回给模型:

# 定义函数实现
def get_weather(location, unit="celsius"):
    # 这里调用真实的天气 API
    weather_data = {
        "北京": {"temp": 15, "condition": "晴", "wind": "北风3-4级"},
        "上海": {"temp": 18, "condition": "多云", "wind": "东风2-3级"}
    }
    
    if location in weather_data:
        data = weather_data[location]
        return f"{location}天气{data['condition']},温度{data['temp']}度,{data['wind']}"
    return f"未找到{location}的天气数据"

# 执行函数调用
if response_message.tool_calls:
    tool_calls = []
    tool_results = []
    
    for tool_call in response_message.tool_calls:
        function_name = tool_call.function.name
        function_args = json.loads(tool_call.function.arguments)
        
        # 调用实际函数
        if function_name == "get_weather":
            result = get_weather(**function_args)
        
        tool_calls.append(tool_call)
        tool_results.append({
            "tool_call_id": tool_call.id,
            "role": "tool",
            "content": result
        })
    
    # 将函数结果附加到消息中
    messages.append(response_message.model_dump(mode='json', include={'role', 'content', 'tool_calls'}))
    for result in tool_results:
        messages.append(result)
    
    # 再次调用模型,生成最终回复
    final_response = openai.chat.completions.create(
        model="gpt-4o",
        messages=messages
    )
    
    print("最终回复:", final_response.choices[0].message.content)

步骤四:构建多函数协同的复杂代理

在实际应用中,我们通常需要定义多个函数来实现复杂业务逻辑:

# 定义多个函数
all_functions = [
    {
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "获取指定城市的天气信息",
            "parameters": {
                "type": "object",
                "properties": {
                    "location": {"type": "string", "description": "城市名称"}
                },
                "required": ["location"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "search_hotels",
            "description": "搜索指定城市的酒店",
            "parameters": {
                "type": "object",
                "properties": {
                    "city": {"type": "string", "description": "城市名称"},
                    "price_range": {"type": "string", "description": "价格范围,如 300-500"}
                },
                "required": ["city"]
            }
        }
    },
    {
        "type": "function",
        "function": {
            "name": "book_hotel",
            "description": "预订酒店",
            "parameters": {
                "type": "object",
                "properties": {
                    "hotel_id": {"type": "string", "description": "酒店ID"},
                    "checkin_date": {"type": "string", "description": "入住日期"},
                    "checkout_date": {"type": "string", "description": "退房日期"}
                },
                "required": ["hotel_id", "checkin_date", "checkout_date"]
            }
        }
    }
]

# 智能代理类
class AIAgent:
    def __init__(self, functions):
        self.functions = functions
        self.messages = []
    
    def process(self, user_input):
        self.messages.append({"role": "user", "content": user_input})
        
        # 第一轮:决定是否调用函数
        response = openai.chat.completions.create(
            model="gpt-4o",
            messages=self.messages,
            tools=self.functions
        )
        
        response_message = response.choices[0].message
        
        # 如果需要调用函数
        if response_message.tool_calls:
            self.messages.append(response_message.model_dump(
                mode='json', 
                include={'role', 'content', 'tool_calls'}
            ))
            
            # 执行所有函数调用
            for tool_call in response_message.tool_calls:
                function_name = tool_call.function.name
                args = json.loads(tool_call.function.arguments)
                
                # 根据函数名执行相应逻辑
                result = self.execute_function(function_name, args)
                
                self.messages.append({
                    "tool_call_id": tool_call.id,
                    "role": "tool",
                    "content": result
                })
            
            # 第二轮:基于函数结果生成回复
            final_response = openai.chat.completions.create(
                model="gpt-4o",
                messages=self.messages
            )
            
            final_content = final_response.choices[0].message.content
            self.messages.append({"role": "assistant", "content": final_content})
            return final_content
        
        else:
            # 直接回复
            self.messages.append({"role": "assistant", "content": response_message.content})
            return response_message.content
    
    def execute_function(self, name, args):
        # 实际业务中这里调用真实 API
        if name == "get_weather":
            return f"{args['location']}今天天气晴朗,20度"
        elif name == "search_hotels":
            return f"找到3家酒店:汉庭(如家)、七天、锦江之星"
        elif name == "book_hotel":
            return f"预订成功,订单号: {hash(str(args))}"
        return "未知函数"

# 使用示例
agent = AIAgent(all_functions)
result = agent.process("帮我查一下上海后天天气,然后找一家价格在500元以下的酒店")
print(result)

运行结果

执行上述代码后,我们得到以下交互过程:

用户:帮我查一下上海后天天气,然后找一家价格在500元以下的酒店

[第一轮调用]
AI 决定调用函数: get_weather
参数: {'location': '上海'}

[函数执行结果]
上海今天天气晴朗,20度

[第二轮调用]  
AI 决定调用函数: search_hotels
参数: {'city': '上海', 'price_range': '0-500'}

[函数执行结果]
找到3家酒店:
1. 汉庭上海陆家嘴店 - 价格450元
2. 7天连锁上海南京路店 - 价格380元  
3. 锦江之星上海外滩店 - 价格420元

[最终回复]
根据查询结果,上海后天(4月9日)天气晴朗,气温约20度,非常适合出行。

为您找到以下500元以下的酒店:
- 汉庭上海陆家嘴店:450元/晚
- 7天连锁上海南京路店:380元/晚
- 锦江之星上海外滩店:420元/晚

请问您想预订哪家酒店?

整个过程完全自动化:AI 理解用户意图,依次调用天气和酒店查询函数,整合结果后给出有价值的回复。用户无需手动查询,AI 代理完成了所有繁琐的信息收集工作。

总结

Function Calling 技术为大语言模型打开了通往外部世界的大门,使其从”知识渊博但行动受限”的文本生成器进化为”能说会做”的智能代理。

本文通过天气查询和酒店预订两个实际案例,详细介绍了 Function Calling 的完整实现流程。从函数定义、模型调用、结果处理到多函数协同,我们看到了这项技术在实际应用中的强大能力。

如果你想进一步探索,可以尝试:为代理添加记忆功能使其能够跨对话保持上下文;实现多轮对话让用户逐步完善需求;接入真实的第三方 API(如航班、餐厅、票务系统)构建完整的旅行助手;或者实现错误处理和重试机制提高系统稳定性。

Function Calling 不仅仅是一项技术特性,它代表了 AI 应用架构的根本转变——从被动回答问题到主动解决问题。这种转变将为企业应用、个人助手、各类自动化场景带来无限可能。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇