【Agent学习笔记2:深入理解Function Calling技术:从原理到实践】
Function Calling技术扩展了AI模型的能力边界,使其能够调用外部函数、访问实时数据并执行特定任务。本文以阿里云DashScope API为例,详细讲解了该技术的原理、实现和应用。核心内容包括:1)系统提示词设计引导AI行为;2)JSON格式函数定义声明可用函数;3)实际函数实现执行具体操作;4)API请求构建与结果处理流程。通过天气查询和文件写入两个实例,展示了如何让AI模型具备实时
深入理解Function Calling技术:从原理到实践
引言
在人工智能和大语言模型(LLM)快速发展的今天,Function Calling(函数调用)技术已经成为扩展AI能力边界的关键技术之一。传统的AI模型虽然具备强大的自然语言理解和生成能力,但其知识库受限于训练数据,无法获取实时信息或执行具体操作。Function Calling技术的出现,完美解决了这一痛点,使得AI模型能够调用外部函数、访问实时数据、执行特定任务。
本文将通过一个完整的实际项目案例,详细讲解Function Calling技术的工作原理、实现方式以及在实际开发中的应用。我们将以阿里云DashScope API为例,演示如何让AI模型具备查询天气、写入文件等真实世界的能力。
一、Function Calling技术概述
1.1 什么是Function Calling
Function Calling是一种让大语言模型与外部工具、API或函数进行交互的技术。在传统的对话场景中,AI模型只能基于其训练数据来回答问题。但现实世界瞬息万变,股票价格、天气情况、新闻事件等实时信息都不在模型的训练数据范围内。Function Calling技术通过以下机制解决了这个问题:
- 模型识别需求:当用户提出需要外部信息或执行特定操作的请求时,模型能够识别并判断需要调用外部函数
- 参数提取:模型从用户输入中提取函数所需的参数
- 函数执行:外部系统执行实际函数调用,获取结果
- 结果整合:将函数执行结果返回给模型,由模型生成最终回复
这种机制使得AI模型从"知识库"转变为"智能助手",能够实时获取信息、执行操作,大大扩展了其应用场景。
1.2 Function Calling的应用场景
Function Calling技术的应用场景非常广泛:
- 信息查询:查询实时天气、股票价格、航班信息、新闻资讯等
- 数据操作:读写数据库、执行文件操作、管理系统资源
- 第三方集成:调用第三方API、执行支付操作、发送通知等
- 任务执行:预订机票酒店、安排日程、生成报告等
通过Function Calling,AI助手不再局限于"聊天",而是真正成为了能够帮助用户完成实际任务的智能助手。
1.3 技术原理简述
Function Calling的工作流程可以分为以下几个步骤:
- 用户输入:用户向AI助手提出请求
- 意图识别:AI模型分析用户请求,判断是否需要调用外部函数
- 参数提取:如果需要函数调用,模型从用户输入中提取相关参数
- 函数调用:外部系统执行实际函数,获取结果
- 结果处理:将函数结果整合到对话中,生成最终回复
这个过程的关键在于模型能够准确理解用户意图,并正确提取函数参数。这需要精心设计的系统提示词和函数定义。
二、项目整体架构
2.1 项目结构
项目包含一个主Python文件,实现了完整的Function Calling功能。项目结构如下:
项目目录/
├── aliyun_function_calling.py # 主程序文件(包含Function Calling核心逻辑)
├── .env # 环境变量配置文件(存储API密钥)
└── 文档目录/
└── 阿里云API函数调用与DeepSeek_API对比分析.md # 技术对比文档
2.2 核心功能
本项目实现了两个核心功能演示:
-
天气查询功能:
- 用户询问天气相关问题(如"明天去北京出差适合穿什么衣服?")
- AI模型识别需要查询天气,自动调用天气API
- 获取天气数据后,结合用户问题给出穿衣建议
-
文件写入功能:
- 用户要求写入文件(如"请在Test2.txt文件中写入内容")
- AI模型识别需要写入文件,自动调用文件操作函数
- 将指定内容写入到用户指定的文件中
2.3 技术栈
- 编程语言:Python 3.x
- HTTP请求库:requests
- 环境变量管理:python-dotenv
- AI服务提供商:阿里云DashScope(通义千问模型)
- 第三方天气API:高德地图天气API
三、核心代码解析
3.1 系统提示词设计
系统提示词(System Prompt)是引导AI模型行为的关键。在我们的项目中,系统提示词定义了AI助手的基本行为准则:
# 系统级提示词
system_prompt = """
你是一名AI助手,具备函数调用的能力,但是如果提供的信息已经足够回答用户的问题,则不需要再进行函数调用。
同时,请严格按照函数调用的方式进行处理,如果用户未提供函数所需参数,则必须询问,而不能自作主张。
"""
设计要点:
- 明确能力:告知模型具备函数调用能力
- 条件判断:如果现有信息足够,则不需要调用函数
- 参数完整性:如果参数不完整,必须询问用户而不是自行假设
这种设计确保了AI助手的行为是可预测和可控的,避免了因模型自行假设而导致的错误。
3.2 函数定义
函数定义是Function Calling的核心,它告诉AI模型有哪些函数可以调用、每个函数的用途以及参数要求。在阿里云API中,函数定义采用嵌套的JSON结构:
# 阿里云API需要的tools格式
tools = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "查询某个城市的天气",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "中国的城市名称或区县的名称",
}
},
"required": ["city"]
},
}
},
{
"type": "function",
"function": {
"name": "write_file",
"description": "往某个文件中写入内容",
"parameters": {
"type": "object",
"properties": {
"filename": {
"type": "string",
"description": "待写入的文件路径",
},
"content": {
"type": "string",
"description": "写入文件中的内容",
}
},
"required": ["filename", "content"]
},
}
}
]
函数定义的关键字段:
| 字段 | 说明 | 设计要点 |
|---|---|---|
type |
工具类型 | 固定为 "function" |
function.name |
函数名称 | 使用清晰的英文命名,见名知意 |
function.description |
函数描述 | 详细说明函数用途,帮助模型理解何时调用 |
function.parameters |
参数定义 | 包含参数类型、属性、描述和是否必需 |
设计原则:
- 描述要具体:函数描述应该让模型能够理解何时应该调用这个函数
- 参数要完整:每个参数都应有类型、描述,必要参数要标记在
required中 - 命名要规范:使用清晰的英文命名,避免歧义
3.3 实际函数实现
函数定义告诉AI模型"有什么函数可以用",而实际的函数实现则是真正执行操作的代码:
# 定义函数用于通过高德天气接口查询天气
def get_weather(city):
# 从环境变量获取高德地图API密钥
amap_api_key = os.getenv("AMAP_API_KEY")
if not amap_api_key:
return {"error": "未配置高德地图API密钥"}
url = f"https://restapi.amap.com/v3/weather/weatherInfo?city={city}&key={amap_api_key}&extensions=all"
response = requests.get(url)
return response.json()["forecasts"]
# 定义函数用于写入文件
def write_file(filename, content):
# 使用当前目录或指定目录
import os
base_dir = os.path.dirname(os.path.abspath(__file__))
file_path = os.path.join(base_dir, filename)
with open(file_path, "w", encoding="utf-8") as file:
file.write(content)
return f"文件{filename}写入成功"
函数实现要点:
- 函数名称一致:函数名必须与
tools定义中的name完全一致 - 参数匹配:函数的参数名和个数必须与函数定义中的参数一致
- 返回值清晰:函数应该返回清晰的结果,便于后续处理
- 错误处理:实际生产环境中应添加异常处理逻辑
- 路径处理:使用相对路径或动态获取路径,避免硬编码
3.4 API请求构建
send_messages函数负责构建和发送API请求到阿里云DashScope服务:
def send_messages(messages):
# 阿里云大模型API地址
url = "https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation"
# 构建请求数据
payload = {
"model": "qwen-plus", # 可以根据需要替换为其他阿里云模型
"input": {
"messages": messages
},
"parameters": {
"tools": tools, # 使用阿里云API需要的tools格式
"tool_choice": "auto", # 自动选择工具
"temperature": 0.7
}
}
# 阿里云API密钥
api_key = os.getenv("DASHSCOPE_API_KEY")
# 检查API密钥是否设置
if not api_key:
print("错误: 未设置 DASHSCOPE_API_KEY 环境变量")
# 如果响应格式不符合预期,返回一个空消息
class EmptyMessage:
def __init__(self):
self.content = ""
self.tool_calls = None
return EmptyMessage()
# 发送请求
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {api_key}"
}
try:
response = requests.post(url, headers=headers, json=payload)
print(f"API请求状态码: {response.status_code}")
# 检查响应状态码
if response.status_code != 200:
print(f"API请求失败,状态码: {response.status_code}")
print(f"错误信息: {response.text[:1000]}") # 限制输出长度,避免截断
# 如果响应格式不符合预期,返回一个空消息
class EmptyMessage:
def __init__(self):
self.content = ""
self.tool_calls = None
return EmptyMessage()
response_data = response.json()
# 检查响应数据中是否有错误
if "error" in response_data:
print(f"API返回错误: {response_data['error']}")
# 如果响应格式不符合预期,返回一个空消息
class EmptyMessage:
def __init__(self):
self.content = ""
self.tool_calls = None
return EmptyMessage()
# 处理响应
if "output" in response_data and "choices" in response_data["output"]:
choice = response_data["output"]["choices"][0]
# 构建与原代码兼容的返回格式
class Message:
def __init__(self, content, tool_calls=None):
self.content = content
self.tool_calls = tool_calls
class ToolCall:
def __init__(self, function):
self.function = function
class Function:
def __init__(self, name, arguments):
self.name = name
self.arguments = arguments
if "message" in choice:
message = choice["message"]
content = message.get("content", "")
tool_calls = []
if "tool_calls" in message:
for tool_call in message["tool_calls"]:
if "function" in tool_call:
func = tool_call["function"]
function_obj = Function(func.get("name"), func.get("arguments"))
tool_call_obj = ToolCall(function_obj)
tool_calls.append(tool_call_obj)
return Message(content, tool_calls if tool_calls else None)
except Exception as e:
print(f"请求过程中发生错误: {str(e)}")
# 如果响应格式不符合预期,返回一个空消息
class EmptyMessage:
def __init__(self):
self.content = ""
self.tool_calls = None
return EmptyMessage()
代码结构说明:
- 请求构建:构建符合阿里云API规范的请求体
- 认证管理:从环境变量获取API密钥
- 错误处理:检查API密钥、响应状态码、错误信息
- 响应解析:从阿里云特定的响应结构中提取数据和函数调用信息
- 数据封装:将原始响应数据封装为自定义对象,便于后续处理
3.5 响应处理与函数执行
invoke函数是整个流程的调度中心,负责协调整个函数调用过程:
def invoke(content):
messages = [{"role": "system", "content": system_prompt},
{"role": "user", "content": content}]
message = send_messages(messages)
print(f"收到模型响应: {'有函数调用' if message.tool_calls else '无函数调用'}")
# 如果响应中存在tool_calls不为空,则说明大模型返回了函数及参数,需要进行函数调用
if message.tool_calls:
# 提取函数调用信息:函数名称和函数的参数
func_name = message.tool_calls[0].function.name
func_args = eval(message.tool_calls[0].function.arguments) # 将参数字符串解析为字典
func = globals()[func_name] # 将函数名称字符串转换为函数体
func_response = func(**func_args) # 利用**将字典对象解析为参数
# 将查询到的天气信息再次与用户提问一同提交给大模型进行分析
messages = [
{"role": "user", "content": f"请基于该信息:{func_response}\n来回答以下问题,请直接回答问题,不需要再进行函数调用,直接返回结果\n{content}"}]
message = send_messages(messages)
print(message.content) # 得到最终的穿衣建议
else:
# 如果没有函数调用,直接输出模型的回复
print("无函数调用,模型回复内容为:", message.content)
执行流程详解:
- 构建消息:将系统提示词和用户输入组合成消息列表
- 发送请求:调用
send_messages函数发送请求到AI服务 - 检查结果:判断响应中是否包含函数调用(
tool_calls) - 提取信息:如果需要函数调用,提取函数名称和参数
- 执行函数:通过字符串名称动态获取函数对象并执行
- 结果整合:将函数执行结果和原始问题一起发送给模型
- 生成回复:模型基于函数结果生成最终回复
技术要点:
globals()[func_name]:通过字符串名称动态获取函数对象eval(message.tool_calls[0].function.arguments):将参数字符串转换为字典func(**func_args):将字典解包为函数参数
3.6 主程序入口
if __name__ == '__main__':
content = "明天去北京出差适合穿什么衣服?"
invoke(content)
content = "请在Test2.txt文件中写入内容:你好,Function Calling!"
invoke(content)
主程序演示了两个典型的使用场景:
- 天气查询和穿衣建议
- 文件写入操作
3.7 环境变量配置
项目的正常运行需要配置以下环境变量,建议使用.env文件进行管理:
# 阿里云DashScope API密钥
# 获取地址:https://dashscope.console.aliyun.com/
DASHSCOPE_API_KEY=your_dashscope_api_key
# 高德地图天气API密钥
# 获取地址:https://lbs.amap.com/api/weather-api/list
AMAP_API_KEY=your_amap_api_key
环境变量管理最佳实践:
- 使用.env文件:将API密钥存储在.env文件中,避免硬编码
- 添加到.gitignore:确保.env文件不会被提交到版本控制系统
- 提供模板:创建.env.example文件作为配置模板
四、运行结果分析
4.1 天气查询场景
用户输入:明天去北京出差适合穿什么衣服?
执行过程:
- 模型识别需要查询天气信息
- 提取参数:
city="北京" - 调用
get_weather("北京") - 获取天气数据
- 模型基于天气数据生成穿衣建议
模型回复:
根据天气信息,明天北京天气为晴,白天温度5℃,夜间温度-5℃,风向为西南风,风力1-3级。
建议穿着:
- 白天:保暖外套(如羽绒服或厚呢大衣)、毛衣、围巾、手套;
- 夜间:需加强保暖,可加穿保暖内衣、帽子等。
整体以防寒为主,注意温差较大,建议采用叠穿方式便于调节。
4.2 文件写入场景
用户输入:请在Test2.txt文件中写入内容:你好,FunctionCalling!
执行过程:
- 模型识别需要写入文件
- 提取参数:
filename="Test2.txt",content="你好,FunctionCalling!" - 调用
write_file("Test2.txt", "你好,FunctionCalling!") - 执行文件写入操作
- 返回操作结果
执行结果:
- 在项目目录下创建Test2.txt文件
- 文件内容为"你好,FunctionCalling!"
- 函数返回"文件Test2.txt写入成功"
4.3 完整运行日志
运行程序后,控制台输出类似以下内容:
API请求状态码: 200
收到模型响应: 有函数调用
API请求状态码: 200
根据天气信息,明天北京天气为晴,白天温度5℃,夜间温度-5℃,风向为西南风,风力1-3级。
建议穿着:
- 白天:保暖外套(如羽绒服或厚呢大衣)、毛衣、围巾、手套;
- 夜间:需加强保暖,可加穿保暖内衣、帽子等。
整体以防寒为主,注意温差较大,建议采用叠穿方式便于调节。
API请求状态码: 200
收到模型响应: 有函数调用
API请求状态码: 200
五、技术要点总结
5.1 函数定义的最佳实践
- 描述要详细:函数描述应该清晰说明函数的用途和适用场景
- 参数要完整:每个参数都应有类型定义和描述说明
- 必要参数明确:将必要的参数标记在
required数组中 - 命名要规范:使用清晰的英文命名,便于模型理解
示例:良好的函数定义
{
"type": "function",
"function": {
"name": "search_products",
"description": "根据关键词搜索商品,支持按价格区间和评分筛选",
"parameters": {
"type": "object",
"properties": {
"keyword": {
"type": "string",
"description": "搜索关键词,如:手机、耳机等"
},
"min_price": {
"type": "number",
"description": "最低价格,可选"
},
"max_price": {
"type": "number",
"description": "最高价格,可选"
},
"min_rating": {
"type": "number",
"description": "最低评分(0-5),可选"
}
},
"required": ["keyword"]
}
}
}
5.2 错误处理策略
- API密钥检查:在发送请求前检查API密钥是否设置
- 状态码验证:检查HTTP响应状态码
- 错误信息处理:解析API返回的错误信息
- 异常捕获:使用try-except捕获可能的异常
- 返回值规范:定义统一的错误返回格式
def send_messages(messages):
# 检查API密钥
api_key = os.getenv("DASHSCOPE_API_KEY")
if not api_key:
print("错误: 未设置 DASHSCOPE_API_KEY 环境变量")
return create_empty_response("未配置API密钥")
# 发送请求并处理异常
try:
response = requests.post(url, headers=headers, json=payload, timeout=30)
response.raise_for_status() # 检查HTTP错误
response_data = response.json()
# 检查API业务错误
if "error" in response_data:
print(f"API返回错误: {response_data['error']}")
return create_empty_response(f"API错误: {response_data['error']}")
# 正常处理响应
return parse_response(response_data)
except requests.exceptions.Timeout:
print("请求超时")
return create_empty_response("请求超时,请稍后重试")
except requests.exceptions.RequestException as e:
print(f"请求失败: {str(e)}")
return create_empty_response(f"网络请求失败: {str(e)}")
def create_empty_response(error_msg=None):
class EmptyMessage:
def __init__(self):
self.content = error_msg or ""
self.tool_calls = None
return EmptyMessage()
5.3 响应解析要点
- 理解API响应结构:不同AI服务提供商的响应结构可能不同
- 提取工具调用:从响应中提取
tool_calls信息 - 封装响应对象:将原始数据封装为易用的对象
- 处理边界情况:如无函数调用、响应格式异常等
阿里云API响应结构示例:
{
"output": {
"choices": [
{
"message": {
"content": "明天北京天气晴朗,适合穿轻薄外套。",
"tool_calls": [
{
"id": "call_123456",
"type": "function",
"function": {
"name": "get_weather",
"arguments": "{\"city\": \"北京\"}"
}
}
]
}
}
]
},
"usage": {
"total_tokens": 150,
"output_tokens": 50,
"input_tokens": 100
}
}
5.4 安全注意事项
- API密钥管理:使用环境变量存储敏感信息,不要硬编码在代码中
- 输入验证:对用户输入进行必要的验证和清理
- 函数安全:确保调用的函数是安全的,避免执行危险操作
- 日志记录:记录关键操作日志,便于问题排查
- 访问控制:对敏感函数实施访问控制
安全最佳实践:
import os
import re
def validate_filename(filename):
"""验证文件名安全性"""
# 阻止路径遍历攻击
if ".." in filename or filename.startswith("/"):
raise ValueError("非法的文件名")
# 限制文件类型
allowed_extensions = ['.txt', '.md', '.json', '.csv']
if not any(filename.endswith(ext) for ext in allowed_extensions):
raise ValueError("不支持的文件类型")
# 限制文件名长度
if len(filename) > 255:
raise ValueError("文件名过长")
return filename
def safe_write_file(filename, content):
"""安全的文件写入函数"""
# 验证文件名
safe_filename = validate_filename(filename)
# 获取安全的路径
base_dir = os.path.dirname(os.path.abspath(__file__))
safe_path = os.path.join(base_dir, "user_files", safe_filename)
# 确保目标目录存在
os.makedirs(os.path.dirname(safe_path), exist_ok=True)
# 写入文件
with open(safe_path, "w", encoding="utf-8") as f:
f.write(content)
return f"文件{safe_filename}写入成功"
六、扩展与应用
6.1 添加新函数
要添加新的函数,只需要:
- 在
tools数组中添加新的函数定义 - 实现对应的Python函数
- 确保函数名与定义中的
name一致
示例:添加股票查询功能
# 1. 添加函数定义
tools = [
# ... 现有函数 ...
{
"type": "function",
"function": {
"name": "get_stock_price",
"description": "查询股票价格和相关信息",
"parameters": {
"type": "object",
"properties": {
"stock_code": {
"type": "string",
"description": "股票代码,如:sh600519(上海)或 sz000001(深圳)",
}
},
"required": ["stock_code"]
},
}
}
]
# 2. 实现函数
def get_stock_price(stock_code):
"""查询股票价格"""
api_key = os.getenv("STOCK_API_KEY")
if not api_key:
return {"error": "未配置股票API密钥"}
url = f"https://api.example.com/stock/quote?code={stock_code}"
headers = {"Authorization": f"Bearer {api_key}"}
response = requests.get(url, headers=headers)
if response.status_code == 200:
return response.json()
else:
return {"error": f"查询失败: {response.status_code}"}
6.2 支持多个AI服务提供商
通过封装可以支持多个AI服务提供商:
class LLMClient:
"""LLM客户端基类"""
def __init__(self, api_key, api_endpoint):
self.api_key = api_key
self.api_endpoint = api_endpoint
def format_functions(self, functions):
"""格式化函数定义"""
raise NotImplementedError
def parse_response(self, response):
"""解析响应"""
raise NotImplementedError
def send_message(self, messages, functions=None):
"""发送消息"""
raise NotImplementedError
class AlibabaClient(LLMClient):
"""阿里云DashScope客户端"""
def format_functions(self, functions):
"""阿里云格式的函数定义"""
return [{"type": "function", "function": f} for f in functions]
def parse_response(self, response):
"""解析阿里云响应"""
return response["output"]["choices"][0]["message"]
def send_message(self, messages, functions=None):
"""发送消息到阿里云"""
payload = {
"model": "qwen-plus",
"input": {"messages": messages},
"parameters": {
"tools": self.format_functions(functions) if functions else [],
"tool_choice": "auto"
}
}
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {self.api_key}"
}
response = requests.post(self.api_endpoint, headers=headers, json=payload)
return self.parse_response(response.json())
class DeepSeekClient(LLMClient):
"""DeepSeek客户端"""
def format_functions(self, functions):
"""DeepSeek格式的函数定义"""
return [{"type": "function", "function": f} for f in functions]
def parse_response(self, response):
"""解析DeepSeek响应"""
return response["choices"][0]["message"]
def send_message(self, messages, functions=None):
"""发送消息到DeepSeek"""
payload = {
"model": "deepseek-chat",
"messages": messages,
"tools": self.format_functions(functions) if functions else [],
"tool_choice": "auto"
}
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {self.api_key}"
}
response = requests.post(self.api_endpoint, headers=headers, json=payload)
return self.parse_response(response.json())
# 使用示例
def create_client(provider):
"""工厂函数:创建指定提供商的客户端"""
providers = {
"alibaba": lambda: AlibabaClient(
api_key=os.getenv("DASHSCOPE_API_KEY"),
api_endpoint="https://dashscope.aliyuncs.com/api/v1/services/aigc/text-generation/generation"
),
"deepseek": lambda: DeepSeekClient(
api_key=os.getenv("DEEPSEEK_API_KEY"),
api_endpoint="https://api.deepseek.com/v1/chat/completions"
)
}
if provider in providers:
return providers[provider]()
else:
raise ValueError(f"不支持的提供商: {provider}")
6.3 高级功能
6.3.1 并发调用
支持同时调用多个函数:
import concurrent.futures
def execute_functions(tool_calls):
"""并发执行多个函数调用"""
results = {}
with concurrent.futures.ThreadPoolExecutor() as executor:
# 准备所有函数调用任务
future_to_func = {
executor.submit(globals()[call.function.name], **eval(call.function.arguments)): call
for call in tool_calls
}
# 收集结果
for future in concurrent.futures.as_completed(future_to_func):
call = future_to_func[future]
try:
result = future.result()
results[call.function.name] = result
except Exception as e:
results[call.function.name] = {"error": str(e)}
return results
6.3.2 函数链
支持多个函数按顺序调用:
def execute_function_chain(tool_calls, intermediate_results=None):
"""执行函数链,支持依赖传递"""
if intermediate_results is None:
intermediate_results = {}
results = []
for i, call in enumerate(tool_calls):
func_name = call.function.name
func_args = eval(call.function.arguments)
# 替换依赖的参数
for key, value in func_args.items():
if isinstance(value, str) and value.startswith("$"):
# 从中间结果中获取值
ref_key = value[1:]
if ref_key in intermediate_results:
func_args[key] = intermediate_results[ref_key]
# 执行函数
func = globals()[func_name]
result = func(**func_args)
# 保存结果供后续使用
results.append({
"function": func_name,
"result": result
})
intermediate_results[func_name] = result
return results
6.3.3 缓存机制
对重复调用进行缓存,提高效率:
from functools import lru_cache
import hashlib
import json
def cache_key(*args, **kwargs):
"""生成缓存键"""
key_dict = {"args": args, "kwargs": kwargs}
key_str = json.dumps(key_dict, sort_keys=True)
return hashlib.md5(key_str.encode()).hexdigest()
class CachedFunctionCaller:
"""带缓存的函数调用器"""
def __init__(self):
self.cache = {}
self.cache_ttl = 300 # 缓存5分钟
def call_with_cache(self, func_name, **kwargs):
"""带缓存的函数调用"""
key = cache_key(func_name, **kwargs)
current_time = __import__('time').time()
# 检查缓存
if key in self.cache:
cached_data = self.cache[key]
if current_time - cached_data["time"] < self.cache_ttl:
print(f"使用缓存: {func_name}")
return cached_data["result"]
# 执行函数
func = globals()[func_name]
result = func(**kwargs)
# 保存到缓存
self.cache[key] = {
"time": current_time,
"result": result
}
return result
七、总结与展望
7.1 技术总结
通过本文的讲解和实际代码示例,我们了解了:
- 技术原理:Function Calling如何让AI模型与外部世界交互
- 实现方式:如何在阿里云DashScope API中实现函数调用
- 代码结构:如何组织Function Calling的代码结构
- 最佳实践:函数定义、错误处理、响应解析等方面的最佳实践
- 扩展应用:如何添加新函数、支持多个服务提供商
7.2 应用前景
Function Calling技术的应用远不止本文所述的天气查询和文件操作。在实际开发中,您可以将其应用于:
- 智能客服系统:自动查询订单状态、产品信息
- 自动化工作流:按顺序执行多个操作步骤
- 数据分析助手:查询数据库、生成报表
- 智能家居控制:控制设备、查询状态
- 企业应用集成:连接CRM、ERP等企业系统
7.3 未来发展方向
随着AI技术的不断发展,Function Calling技术也将持续演进:
- 更智能的函数选择:模型能够更准确地选择合适的函数
- 更强的参数理解:能够处理更复杂的参数提取场景
- 更丰富的工具生态:更多预定义的工具和API集成
- 更好的安全性:更严格的访问控制和权限管理
7.4 学习建议
对于想要深入学习Function Calling技术的开发者,建议:
- 理解原理:先理解Function Calling的基本原理和工作流程
- 动手实践:跟随本文示例动手实现一个简单的Function Calling应用
- 阅读文档:深入阅读阿里云、OpenAI等平台的官方文档
- 参与社区:加入AI开发者社区,了解最新动态和最佳实践
- 探索创新:尝试将Function Calling应用到自己的项目中
Function Calling技术是现代AI应用开发中不可或缺的技术之一。通过这项技术,AI不再仅仅是"聊天机器人",而是真正能够与现实世界交互、帮助用户完成实际任务的智能助手。希望本文能够帮助您更好地理解和应用这项技术,开启AI应用开发的新篇章。
关键词标签:Function Calling、AI、大语言模型、阿里云、Python、API集成
技术分类:人工智能、API开发、Python编程
更多推荐



所有评论(0)