Python调用Openai的Function calling功能—源码

一、什么是 Function Calling?

Function Calling是一种让大语言模型能够理解何时需要调用外部函数,以及如何正确调用这些函数的技术。当用户提出需要外部工具协助的问题时,模型会:

  1. 识别意图:理解用户问题需要调用哪个工具
  2. 提取参数:从用户输入中提取调用函数所需的参数
  3. 执行调用:调用相应函数获取结果
  4. 整合回答:将函数结果整合到自然语言回答中

二、代码架构解析

让我们通过一个实际的代码示例来理解Function Calling的实现:

1.安装第三方库

首先安装一下第三方库

复制代码
pip install openai

2. 完整示例代码

python 复制代码
# -*- coding: utf-8 -*-  
# @Author :Kan 
# @Date :2025/8/1 9:12  
# @File :1_function_calling.py  
import json  
import random  
from openai import OpenAI  
from datetime import datetime  
  
  
# ================================================================  
# 1. Function Calling(函数调用)  
# ================================================================  
  
class ToolsUsage:  
    tools = [  
        # 工具2 获取指定城市的天气  
        {  
            "type": "function",  
            "function": {  
                "name": "get_current_weather",  
                "description": "获取指定地点的天气信息",  
                "parameters": {  
                    "type": "object",  
                    "properties": {  
                        "location": {"type": "string", "description": "地点名称"}  
                    },  
                    "required": ["location"]  
                }  
            }  
        },  
        # 工具1 获取当前时刻的时间  
        {  
            "type": "function",  
            "function": {  
                "name": "get_current_time",  
                "description": "当你想知道现在的时间时非常有用。",  
                # 因为获取当前时间无需输入参数,因此parameters为空字典  
                "parameters": {},  
            },  
        },  
    ]  
  
    @staticmethod  
    # 天气查询工具。返回结果示例:"北京今天是雨天。"  
    def get_current_weather(location):  
        weather_conditions = ["晴天", "多云", "雨天"]  
        # 随机选择一个天气条件  
        random_weather = random.choice(weather_conditions)  
        # 返回格式化信息  
        return f"{location}今天是{random_weather}。"  
  
    @staticmethod  
    # 查询当前时间的工具。返回结果示例:"当前时间:2024-04-15 17:15:18。"  
    def get_current_time():  
        current_datetime = datetime.now()  
        # 格式化日期  
        formatted_time = current_datetime.strftime("%Y-%m-%d %H:%M:%S")  
        return f"当前时间:{formatted_time}。"  
  
    @staticmethod  
    def execute_tools(func_name, func_args):  
        func_dic = {  
            "get_current_weather": ToolsUsage.get_current_weather,  
            "get_current_time": ToolsUsage.get_current_time,  
        }  
        return func_dic[func_name](**func_args)  
  
  
class ChatAgent:  
    def __init__(self, api_key: str, url: str, model_name: str):  
        self.client = OpenAI(api_key=api_key, base_url=url)  
        self.model_name = model_name  
  
    def request_chat(self, messages: list):  
        response = self.client.chat.completions.create(  
            model=self.model_name,  
            messages=messages,  
            tools=ToolsUsage.tools,  
            extra_body={"enable_thinking": False},  
            tool_choice="auto",  
        )  
        return response  
  
    def execute_chat(self):  
        print("\n")  
        messages = [  
            {  
                # 提问示例:"现在几点了?" "一个小时后几点" "北京天气如何?"  
                "content": input(  
                    "请输入问题:"  
                ),  
                "role": "user",  
            }  
        ]  
        print("-*" * 60)  
        # 模型调用次数  
        i = 1  
        first_response = self.request_chat(messages)  
        assistant_output = first_response.choices[0].message  
        print(f"\n第{i}轮大模型输出信息:{assistant_output}\n")  
        # 不需要调用工具,则直接返回答案  
        if not assistant_output.tool_calls:  
            print(f"无需调用工具,直接回复:{assistant_output.content}")  
            return  
        tool_calls_result = assistant_output.tool_calls  
        # 如果需要调用工具,则进行模型的多轮调用,直到模型判断无需调用工具  
        while tool_calls_result:  
            # 执行工具调用  
            for tool_call in assistant_output.tool_calls:  
                tool_info = {  
                    "content": "",  
                    "role": "tool",  
                    "tool_call_id": assistant_output.tool_calls[0].id,  
                }  
                func_name = tool_call.function.name  
                func_args = json.loads(tool_call.function.arguments)  
                tools_result = ToolsUsage.execute_tools(func_name, func_args)  
                print(f"当前调用工具:{func_name},参数:{func_args},输出信息:{tools_result}\n")  
                tool_info["content"] = tools_result  
                messages.append(tool_info)  
                print("-*" * 60)  
            second_response = self.request_chat(messages)  
            assistant_output = second_response.choices[0].message  
            i += 1  
            print(f"第{i}轮大模型输出信息:{assistant_output}\n")  
            # 指导调用工具为空时终止  
            if not assistant_output.tool_calls:  
                tool_calls_result = None  
        print(f"最终答案:\n {assistant_output.content}")  
  
  
if __name__ == "__main__":  
    api_key = 'xxxxxx'  
    base_url = "http://xxxxxxxx/v1"  
    model = "qwen3"  
    chat_service = ChatAgent(api_key, base_url, model)  
    chat_service.execute_chat()

3. 工具定义类 - ToolsUsage

ini 复制代码
class ToolsUsage:
    tools = [
        # 天气查询工具
        {
            "type": "function",
            "function": {
                "name": "get_current_weather",
                "description": "获取指定地点的天气信息",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "location": {"type": "string", "description": "地点名称"}
                    },
                    "required": ["location"]
                }
            }
        },
        # 时间查询工具
        {
            "type": "function", 
            "function": {
                "name": "get_current_time",
                "description": "当你想知道现在的时间时非常有用。",
                "parameters": {},
            },
        },
    ]

这个类承担了两个核心职责:

工具声明 :通过tools列表定义了可用的函数。每个工具定义包含:

  • name:函数名称
  • description:功能描述,帮助模型理解何时使用
  • parameters:参数规范,使用JSON Schema格式

工具实现:提供了实际的函数实现,包括天气查询和时间获取功能。

4. 聊天代理类 - ChatAgent

python 复制代码
class ChatAgent:
    def __init__(self, api_key: str, url: str, model_name: str):
        self.client = OpenAI(api_key=api_key, base_url=url)
        self.model_name = model_name

ChatAgent类负责与大语言模型的交互,核心方法包括:

请求处理request_chat方法向模型发送消息,关键参数:

  • tools:传入可用工具列表
  • tool_choice="auto":让模型自动判断是否需要调用工具

执行逻辑execute_chat方法实现了完整的对话流程。

三、Function Calling 执行流程详解

第一阶段:意图识别

ini 复制代码
first_response = self.request_chat(messages)
assistant_output = first_response.choices[0].message

当用户输入问题时,模型首先分析是否需要调用外部工具。比如:

  • 输入"现在几点了?" → 需要调用时间工具
  • 输入"北京天气如何?" → 需要调用天气工具
  • 输入"你好" → 无需调用工具,直接回复

第二阶段:工具调用循环

ini 复制代码
while tool_calls_result:
    for tool_call in assistant_output.tool_calls:
        func_name = tool_call.function.name
        func_args = json.loads(tool_call.function.arguments)
        tools_result = ToolsUsage.execute_tools(func_name, func_args)

如果模型判断需要调用工具,会进入多轮对话循环:

  1. 参数解析:模型从用户输入中提取函数参数
  2. 工具执行:调用相应的工具函数获取结果
  3. 结果反馈:将工具执行结果作为新的消息加入对话历史
  4. 继续推理:模型基于工具结果继续生成回答

第三阶段:结果整合

python 复制代码
if not assistant_output.tool_calls:
    print(f"最终答案:\n {assistant_output.content}")

当所有必要的工具调用完成后,模型将结果整合成自然语言回答返回给用户。

相关推荐
在钱塘江10 分钟前
LangGraph构建Ai智能体-6-智能体ReAct-例子
人工智能·python
得帆云低代码2 小时前
2025平台进化趋势:AI与低代码重塑企业应用构建引擎(上)
低代码·openai·ai编程
袁袁袁袁满2 小时前
基于Python爬虫实战:获取财经股票数据
爬虫·python·ai编程
大模型真好玩2 小时前
深入浅出LangChain AI Agent智能体开发教程(七)—LangChain多智能体浏览器自动化
人工智能·python·mcp
机器之心2 小时前
40年后,Dijkstra算法极限再被突破,清华段然团队更快最短路径算法摘STOC最佳论文
人工智能·openai
Kan先生3 小时前
大模型工具集成四层架构:识别、协议、执行与实现
openai
码界筑梦坊4 小时前
97-基于Python的大众点评数据分析预测系统
开发语言·python·数据分析
技术老金4 小时前
我为什么又开始手写Agent框架了?从CrewAI和LangGraph的局限谈起
人工智能·python
余子越4 小时前
Python StringIO 和 BytesIO 用法
后端·python