第五章:Agent智能体开发实战之【Function Calling深度剖析】

文章目录
一、前言
在大语言模型(LLM)广泛应用的今天,单一的文本生成能力已难以满足复杂场景的需求。当用户需要处理实时数据、执行计算操作或访问外部系统时,传统LLM的“凭空生成”模式往往力有不逮。Function Calling(函数调用)技术的出现,为LLM打通了与外部工具、系统的连接通道,让AI不仅能“思考”,更能“行动”。
本教案面向初级到中级技术从业者、AI爱好者及在校学生,将从基础概念入手,逐步解析Function
Calling的原理、应用场景与实践方法。无论您是后端开发者希望通过AI优化业务流程,前端开发者想打造智能交互应用,还是运维人员探索自动化运维方案,都能从Function
Calling技术中找到新的解决方案。我们将通过通俗易懂的讲解和可运行的代码示例,帮助您系统掌握这一AI技术的核心能力。
二、Function Calling深度剖析
2.1 Function Calling 介绍
Function Calling是大语言模型的一项核心扩展能力,它允许模型根据用户的自然语言指令,自主判断是否需要调用外部函数(工具),并以结构化的格式输出调用请求。简单来说,Function Calling让LLM从“文本生成器”升级为“任务调度者”,能够将复杂任务拆解为“思考决策”与“工具执行”两个环节,从而解决传统LLM无法处理的实时性、计算性、数据访问类问题。
Function Calling的典型应用场景包括:
- 实时数据查询:如查询天气、股票价格、航班信息等;
- 复杂计算处理:如数学运算、数据统计、科学计算等;
- 外部系统交互:如调用企业API、操作数据库、控制物联网设备等;
- 多工具协同:如结合搜索工具、计算工具、文档处理工具完成复杂任务。
与传统的Prompt Engineering(提示词工程)相比,Function Calling具有以下优势:
- 结构化输出:模型以固定格式输出函数调用请求,便于程序解析执行;
- 自主决策:模型可根据用户需求自主判断是否需要调用工具,无需人工干预;
- 结果整合:模型可将工具返回的结果与自身的语言生成能力结合,生成自然语言回复;
- 可扩展性:通过定义不同的函数,可轻松扩展LLM的能力边界。
2.2 Function Calling 简单理解
为了帮助您快速理解Function Calling的工作流程,我们可以将其类比为一个“智能助理”的工作过程:
- 接收需求:用户向智能助理提出一个问题或请求,例如“帮我查询北京明天的天气”;
- 分析判断:智能助理分析用户需求,判断是否需要调用外部工具。如果是常识性问题,可直接回答;如果需要实时数据,则需要调用天气查询工具;
- 调用工具:智能助理根据需求选择合适的工具,并按照工具要求的格式传递参数,例如调用天气API,传入城市“北京”和日期“明天”;
- 处理结果:工具返回查询结果,智能助理将结果整理成自然语言回复用户,例如“北京明天晴转多云,气温15-25摄氏度”。
在这个过程中,Function Calling扮演的就是“智能助理”的角色,它负责连接用户需求与外部工具,实现从“思考”到“行动”的闭环。
我们可以用一个简单的流程图来表示Function Calling的基本流程:
用户指令 → LLM分析判断 → 生成函数调用请求 → 执行外部函数 → 获取返回结果 → LLM整理结果 → 生成自然语言回复
2.3 Function Calling 原理解析
Function Calling的核心原理是通过“函数定义”和“结构化输出”两个关键环节,实现LLM与外部工具的交互。

2.3.1 函数定义
在使用Function Calling之前,我们需要向LLM提供函数的定义信息,包括函数名称、描述、参数列表等。这些信息通常以JSON格式传递给模型,帮助模型理解函数的功能和使用方法。
一个典型的函数定义示例如下:
{
"name": "get_weather",
"description": "查询指定城市的天气信息",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "要查询的城市名称"
},
"date": {
"type": "string",
"description": "要查询的日期,格式为YYYY-MM-DD,默认是当天"
}
},
"required": ["city"]
}
}
2.3.2 结构化输出
当LLM分析用户指令后,判断需要调用外部函数时,会以结构化的格式输出函数调用请求。目前主流LLM通常使用JSON格式输出,包含函数名称和参数列表。
一个典型的函数调用请求示例如下:
{
"name": "get_weather",
"parameters": {
"city": "北京",
"date": "2026-04-08"
}
}
2.3.3 执行与结果整合
程序解析LLM输出的函数调用请求后,执行对应的外部函数,并将返回结果再次传递给LLM。LLM会将工具返回的结构化结果整理成自然语言回复,最终返回给用户。
2.3.4 技术实现关键点
- Prompt设计:需要在Prompt中明确告知模型可以调用的函数列表,以及函数调用的格式要求;
- 格式约束:需要确保模型输出符合指定的JSON格式,通常可以通过示例和格式说明来引导;
- 错误处理:需要处理模型输出不符合格式要求的情况,例如使用重试机制或格式校验;
- 结果解析:需要正确解析外部函数返回的结果,并传递给模型进行自然语言生成。
2.4 Function Calling 支持的国产模型介绍
随着国内大语言模型技术的发展,越来越多的国产模型开始支持Function Calling能力。以下是几个主流国产模型的Function Calling特性介绍:
2.4.1 文心一言(ERNIE Bot)
文心一言是百度开发的大语言模型,全面支持Function Calling能力。它提供了丰富的工具调用接口,支持自定义函数定义,并且具有良好的格式稳定性。文心一言的Function Calling支持多函数并行调用,能够根据用户需求自主选择合适的函数。
2.4.2 通义千问(Qwen)
通义千问是阿里云开发的大语言模型,支持Function Calling能力。它提供了简洁的函数定义格式,并且能够根据函数描述智能判断是否需要调用工具。通义千问的Function Calling支持参数自动补全,能够根据上下文推断缺失的参数。
2.4.3 讯飞星火(Spark)
讯飞星火是科大讯飞开发的大语言模型,支持Function Calling能力。它提供了灵活的工具调用方式,支持同步和异步调用,并且具有良好的错误处理机制。讯飞星火的Function Calling支持多轮对话中的上下文保持,能够在多轮交互中正确调用工具。
2.4.4 智谱清言(GLM)
智谱清言是智谱AI开发的大语言模型,支持Function Calling能力。它提供了详细的函数定义规范,并且能够根据函数参数的描述智能生成调用请求。智谱清言的Function Calling支持工具结果的深度整合,能够将工具返回的复杂数据结构整理成自然语言回复。
2.5 Function Calling 调用外部API
调用外部API是Function Calling最常见的应用场景之一。通过Function Calling,LLM可以根据用户的自然语言指令,自主调用对应的API接口,获取实时数据或执行操作。
以下是使用Python和文心一言API实现调用天气查询API的示例:
首先,我们需要定义天气查询函数的描述:
# 定义天气查询函数的描述
weather_function = {
"name": "get_weather",
"description": "查询指定城市的天气信息",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "要查询的城市名称,如北京、上海等"
}
},
"required": ["city"]
}
}
接下来,我们需要实现调用文心一言API的函数:
import requests
import json
def call_ernie_bot(prompt, functions=None):
"""
调用文心一言API
:param prompt: 用户输入的提示词
:param functions: 可选的函数列表
:return: 模型返回的结果
"""
# 替换为您的API密钥
api_key = "your-api-key"
url = "https://aip.baidubce.com/rpc/2.0/ai_custom/v1/wenxinworkshop/chat/completions_pro?access_token=" + api_key
headers = {
"Content-Type": "application/json"
}
payload = {
"messages": [
{
"role": "user",
"content": prompt
}
],
"temperature": 0.7
}
if functions:
payload["functions"] = functions
payload["function_call"] = "auto"
response = requests.post(url, headers=headers, data=json.dumps(payload))
return response.json()
然后,我们需要实现天气查询的实际函数:
def get_weather(city):
"""
模拟天气查询API
:param city: 城市名称
:return: 天气信息
"""
# 这里使用模拟数据,实际应用中可以调用真实的天气API
weather_data = {
"北京": {"temperature": "15-25°C", "condition": "晴转多云"},
"上海": {"temperature": "18-28°C", "condition": "阴有小雨"},
"广州": {"temperature": "22-30°C", "condition": "多云"}
}
if city in weather_data:
return f"{city}的天气:{weather_data[city]['condition']},气温{weather_data[city]['temperature']}"
else:
return f"暂不支持查询{city}的天气信息"
最后,我们将这些组件整合起来,实现完整的Function Calling流程:
def process_user_query(query):
"""
处理用户查询
:param query: 用户输入的查询语句
:return: 最终回复
"""
# 调用文心一言API,传入函数描述
response = call_ernie_bot(query, functions=[weather_function])
# 检查是否需要调用函数
if "result" in response and "function_call" in response["result"]:
function_call = response["result"]["function_call"]
function_name = function_call["name"]
function_args = function_call["parameters"]
# 根据函数名称调用对应的函数
if function_name == "get_weather":
city = function_args.get("city")
if city:
weather_result = get_weather(city)
# 将函数返回结果再次传递给模型,生成自然语言回复
final_response = call_ernie_bot(f"根据以下天气信息生成自然语言回复:{weather_result}")
return final_response["result"]
else:
return "请提供要查询的城市名称"
else:
return f"不支持的函数调用:{function_name}"
else:
# 直接返回模型生成的回复
return response["result"]
# 示例使用
user_query = "帮我查询北京的天气"
result = process_user_query(user_query)
print(result)
2.6 Function Calling 进行数据库操作
除了调用外部API,Function Calling还可以用于执行数据库操作。通过Function Calling,LLM可以根据用户的自然语言指令,生成对应的SQL语句并执行,实现数据的查询、插入、更新和删除操作。
以下是使用Python和文心一言API实现数据库操作的示例:
首先,我们需要定义数据库操作函数的描述:
# 定义数据库查询函数的描述
db_query_function = {
"name": "execute_sql",
"description": "执行SQL查询语句,获取数据库中的数据",
"parameters": {
"type": "object",
"properties": {
"sql": {
"type": "string",
"description": "要执行的SQL查询语句"
}
},
"required": ["sql"]
}
}
接下来,我们需要实现执行SQL语句的函数:
import sqlite3
def execute_sql(sql):
"""
执行SQL查询语句
:param sql: SQL查询语句
:return: 查询结果
"""
# 连接到SQLite数据库(如果不存在则创建)
conn = sqlite3.connect('example.db')
cursor = conn.cursor()
try:
# 执行SQL语句
cursor.execute(sql)
# 如果是查询语句,返回查询结果
if sql.strip().upper().startswith('SELECT'):
results = cursor.fetchall()
columns = [desc[0] for desc in cursor.description]
return {"columns": columns, "data": results}
else:
# 如果是修改语句,提交事务
conn.commit()
return {"message": f"执行成功,影响了{cursor.rowcount}行数据"}
except Exception as e:
return {"error": str(e)}
finally:
# 关闭连接
conn.close()
# 初始化数据库,创建示例表
def init_database():
conn = sqlite3.connect('example.db')
cursor = conn.cursor()
# 创建用户表
cursor.execute('''
CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL,
age INTEGER,
email TEXT UNIQUE NOT NULL
)
''')
# 插入示例数据
cursor.execute('''
INSERT OR IGNORE INTO users (name, age, email)
VALUES ('张三', 25, 'zhangsan@example.com'),
('李四', 30, 'lisi@example.com'),
('王五', 28, 'wangwu@example.com')
''')
conn.commit()
conn.close()
# 初始化数据库
init_database()
然后,我们将这些组件整合起来,实现完整的数据库操作流程:
def process_db_query(query):
"""
处理数据库查询
:param query: 用户输入的查询语句
:return: 最终回复
"""
# 调用文心一言API,传入函数描述
response = call_ernie_bot(query, functions=[db_query_function])
# 检查是否需要调用函数
if "result" in response and "function_call" in response["result"]:
function_call = response["result"]["function_call"]
function_name = function_call["name"]
function_args = function_call["parameters"]
# 根据函数名称调用对应的函数
if function_name == "execute_sql":
sql = function_args.get("sql")
if sql:
db_result = execute_sql(sql)
# 将函数返回结果再次传递给模型,生成自然语言回复
final_response = call_ernie_bot(f"根据以下数据库查询结果生成自然语言回复:{json.dumps(db_result)}")
return final_response["result"]
else:
return "请提供要执行的SQL语句"
else:
return f"不支持的函数调用:{function_name}"
else:
# 直接返回模型生成的回复
return response["result"]
# 示例使用
user_query = "帮我查询所有用户的姓名和年龄"
result = process_db_query(user_query)
print(result)
2.7 多 Function Calling 的使用
在实际应用中,我们往往需要同时使用多个工具来完成复杂任务。Function Calling支持多函数调用,LLM可以根据用户需求自主选择合适的函数组合,实现多工具协同工作。
以下是使用Python和文心一言API实现多函数调用的示例:
首先,我们需要定义多个函数的描述:
# 定义天气查询函数的描述
weather_function = {
"name": "get_weather",
"description": "查询指定城市的天气信息",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "要查询的城市名称,如北京、上海等"
}
},
"required": ["city"]
}
}
# 定义股票查询函数的描述
stock_function = {
"name": "get_stock_price",
"description": "查询指定股票的当前价格",
"parameters": {
"type": "object",
"properties": {
"symbol": {
"type": "string",
"description": "股票代码,如600000(浦发银行)、000001(平安银行)等"
}
},
"required": ["symbol"]
}
}
# 定义翻译函数的描述
translate_function = {
"name": "translate_text",
"description": "将文本从一种语言翻译成另一种语言",
"parameters": {
"type": "object",
"properties": {
"text": {
"type": "string",
"description": "要翻译的文本"
},
"target_language": {
"type": "string",
"description": "目标语言,如en(英语)、ja(日语)、fr(法语)等"
}
},
"required": ["text", "target_language"]
}
}
接下来,我们需要实现这些函数的实际逻辑:
def get_weather(city):
"""
模拟天气查询API
:param city: 城市名称
:return: 天气信息
"""
weather_data = {
"北京": {"temperature": "15-25°C", "condition": "晴转多云"},
"上海": {"temperature": "18-28°C", "condition": "阴有小雨"},
"广州": {"temperature": "22-30°C", "condition": "多云"}
}
if city in weather_data:
return f"{city}的天气:{weather_data[city]['condition']},气温{weather_data[city]['temperature']}"
else:
return f"暂不支持查询{city}的天气信息"
def get_stock_price(symbol):
"""
模拟股票价格查询API
:param symbol: 股票代码
:return: 股票价格信息
"""
stock_data = {
"600000": {"name": "浦发银行", "price": "7.85元", "change": "+0.5%"},
"000001": {"name": "平安银行", "price": "12.30元", "change": "-0.2%"},
"601318": {"name": "中国平安", "price": "55.60元", "change": "+1.2%"}
}
if symbol in stock_data:
stock = stock_data[symbol]
return f"{stock['name']}({symbol})当前价格:{stock['price']},涨跌幅:{stock['change']}"
else:
return f"暂不支持查询股票代码{symbol}的价格信息"
def translate_text(text, target_language):
"""
模拟翻译API
:param text: 要翻译的文本
:param target_language: 目标语言
:return: 翻译结果
"""
# 这里使用简单的映射关系,实际应用中可以调用真实的翻译API
translations = {
"你好": {"en": "Hello", "ja": "こんにちは", "fr": "Bonjour"},
"谢谢": {"en": "Thank you", "ja": "ありがとう", "fr": "Merci"},
"再见": {"en": "Goodbye", "ja": "さようなら", "fr": "Au revoir"}
}
if text in translations and target_language in translations[text]:
return translations[text][target_language]
else:
return f"暂不支持将'{text}'翻译成{target_language}"
然后,我们将这些组件整合起来,实现多函数调用流程:
def process_multi_function_query(query):
"""
处理多函数查询
:param query: 用户输入的查询语句
:return: 最终回复
"""
# 调用文心一言API,传入多个函数描述
response = call_ernie_bot(query, functions=[weather_function, stock_function, translate_function])
# 检查是否需要调用函数
if "result" in response and "function_call" in response["result"]:
function_call = response["result"]["function_call"]
function_name = function_call["name"]
function_args = function_call["parameters"]
# 根据函数名称调用对应的函数
if function_name == "get_weather":
city = function_args.get("city")
if city:
result = get_weather(city)
else:
result = "请提供要查询的城市名称"
elif function_name == "get_stock_price":
symbol = function_args.get("symbol")
if symbol:
result = get_stock_price(symbol)
else:
result = "请提供要查询的股票代码"
elif function_name == "translate_text":
text = function_args.get("text")
target_language = function_args.get("target_language")
if text and target_language:
result = translate_text(text, target_language)
else:
result = "请提供要翻译的文本和目标语言"
else:
result = f"不支持的函数调用:{function_name}"
# 将函数返回结果再次传递给模型,生成自然语言回复
final_response = call_ernie_bot(f"根据以下结果生成自然语言回复:{result}")
return final_response["result"]
else:
# 直接返回模型生成的回复
return response["result"]
# 示例使用
user_query1 = "帮我查询上海的天气"
result1 = process_multi_function_query(user_query1)
print(result1)
user_query2 = "帮我查询中国平安的股票价格"
result2 = process_multi_function_query(user_query2)
print(result2)
user_query3 = "把'你好'翻译成英语"
result3 = process_multi_function_query(user_query3)
print(result3)
三、本章练习题及其答案
3.1 选择题
- 以下哪项不是Function Calling的优势?( )
A. 结构化输出 B. 自主决策 C. 离线运行 D. 结果整合 - 以下哪个国产模型不支持Function Calling能力?( )
A. 文心一言 B. 通义千问 C. 讯飞星火 D. 以上都支持 - Function Calling最核心的作用是?( )
A. 提升文本生成质量 B. 实现LLM与外部工具的交互 C. 减少模型训练成本 D. 提高模型推理速度
答案:1.C;2.D;3.B
3.2 填空题
- Function Calling的基本流程包括:用户指令、、生成函数调用请求、执行外部函数、获取返回结果、、生成自然语言回复。
- 在使用Function Calling之前,需要向LLM提供______信息,包括函数名称、描述、参数列表等。
- Function Calling支持多函数调用,LLM可以根据用户需求自主选择合适的______,实现多工具协同工作。
答案:1.LLM分析判断、LLM整理结果;2.函数定义;3.函数组合
3.3 简答题
- 简述Function Calling与传统Prompt Engineering的区别。
- 举例说明Function Calling在运维工作中的应用场景。
答案:
- 传统Prompt Engineering主要通过优化提示词来引导模型生成高质量的文本,仍然局限于模型自身的知识和能力范围;而Function Calling则允许模型调用外部工具,扩展了模型的能力边界,能够处理实时数据、执行计算操作和访问外部系统。Function Calling具有结构化输出、自主决策、结果整合和可扩展性等优势。
- Function Calling在运维工作中的应用场景包括:
- 自动查询服务器状态:根据用户的自然语言指令,调用服务器监控API,获取CPU、内存、磁盘等使用情况;
- 自动化故障排查:当系统出现异常时,自动调用日志分析工具,定位故障原因;
- 批量执行运维操作:根据用户需求,生成并执行批量操作脚本,如批量重启服务、批量更新配置等;
- 智能告警处理:接收告警信息后,自动调用相关工具进行分析,并给出处理建议。
3.4 实操题
使用Python和文心一言API实现一个智能客服系统,要求具备以下功能:
- 能够根据用户的自然语言指令,自主判断是否需要调用外部工具;
- 支持查询订单状态、查询物流信息和退换货申请三个功能;
- 能够将工具返回的结果整理成自然语言回复用户。
参考实现思路:
- 定义三个函数的描述:查询订单状态、查询物流信息、退换货申请;
- 实现这三个函数的实际逻辑(可以使用模拟数据);
- 调用文心一言API,传入函数描述,获取模型返回的函数调用请求;
- 解析函数调用请求,执行对应的函数;
- 将函数返回结果再次传递给模型,生成自然语言回复;
- 实现一个简单的交互界面,允许用户输入查询语句并获取回复。
四、总结
Function Calling作为大语言模型的核心扩展能力,为AI技术的应用带来了革命性的变化。它让LLM从“文本生成器”升级为“任务调度者”,能够连接外部工具和系统,实现从“思考”到“行动”的闭环。
本教案从Function Calling的基础概念入手,详细解析了其工作原理、应用场景和实践方法。通过调用外部API、执行数据库操作和多函数协同等示例,展示了Function Calling的强大能力。同时,我们还介绍了支持Function Calling的国产模型,为开发者提供了更多的选择。
随着AI技术的不断发展,Function Calling将在更多领域得到应用,推动AI系统向更智能、更实用的方向发展。掌握Function
Calling技术,将为您的AI开发工作带来新的思路和方法,帮助您构建更加强大的智能应用。
🌟 感谢您耐心阅读到这里!
🚀 技术成长没有捷径,但每一次的阅读、思考和实践,都在默默缩短您与成功的距离。
💡 如果本文对您有所启发,欢迎点赞👍、收藏📌、分享📤给更多需要的伙伴!
🗣️ 期待在评论区看到您的想法、疑问或建议,我会认真回复,让我们共同探讨、一起进步~
🔔 关注我,持续获取更多干货内容!
🤗 我们下篇文章见!
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐


所有评论(0)