一、什么是 Function Calling?
Function Calling是一种让大语言模型能够理解何时需要调用外部函数,以及如何正确调用这些函数的技术。当用户提出需要外部工具协助的问题时,模型会:
- 识别意图:理解用户问题需要调用哪个工具
- 提取参数:从用户输入中提取调用函数所需的参数
- 执行调用:调用相应函数获取结果
- 整合回答:将函数结果整合到自然语言回答中
二、代码架构解析
让我们通过一个实际的代码示例来理解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)
如果模型判断需要调用工具,会进入多轮对话循环:
- 参数解析:模型从用户输入中提取函数参数
- 工具执行:调用相应的工具函数获取结果
- 结果反馈:将工具执行结果作为新的消息加入对话历史
- 继续推理:模型基于工具结果继续生成回答
第三阶段:结果整合
python
if not assistant_output.tool_calls:
print(f"最终答案:\n {assistant_output.content}")
当所有必要的工具调用完成后,模型将结果整合成自然语言回答返回给用户。