【Agent从入门到实践】13 工具调用模块:如何调用工具
文章目录
目前国内还是很缺AI人才的,希望更多人能真正加入到AI行业,共同促进行业进步。想要系统学习AI知识的朋友可以看看我的教程 http://blog.csdn.net/jiangjunshow,教程通俗易懂,风趣幽默,从深度学习基础原理到各领域实战应用都有讲解。
前言
各位AI入门的小伙伴们,前面咱们把Agent的“感知-决策-执行-记忆”四大核心模块都讲完了——Agent能看、能想、能做、能记!但还有个关键问题:Agent自己的能力有限,就像咱们人类需要用手机、电脑、工具来帮自己做事一样,Agent也需要“调用外部工具”来拓展能力边界~
比如:
- Agent想查天气,不能自己“感知”全国天气数据,得调用天气API;
- Agent想帮你整理文档,得能操作本地的Word、Excel文件;
- Agent想做图片识别,自己写算法太麻烦,得调用现成的AI模型(比如OpenAI的图片识别API)。
今天咱们就聊聊Agent的“工具箱”——工具调用模块到底是怎么帮Agent“借用外力”的?重点讲三个最常用的场景:调用第三方API、操作本地文件、调用其他AI模型,每个场景都配Python代码,看完你就能上手!
一、先搞懂:工具调用模块的本质——“Agent的外接设备”
咱们先举个生活例子:你想做一顿饭,需要用到:
- 工具1:电饭煲(煮饭);
- 工具2:菜刀(切菜);
- 工具3:燃气灶(炒菜)。
你不需要自己具备“煮饭、切菜、炒菜”的本能,只要会用这些工具就行。Agent的工具调用模块也是这个逻辑!
它的核心作用就是:
- 识别需求:根据决策模块的指令,判断“需要用什么工具”(比如“查天气”→ 天气API工具);
- 调用工具:按照工具的“使用规则”(比如API的调用格式、文件的操作方法),发送指令并执行;
- 接收结果:获取工具的执行结果(比如天气数据、文件处理结果、AI模型的输出);
- 反馈结果:把结果传给决策模块,完成任务闭环。
用一句话总结:工具调用模块就是Agent的“双手”,负责拿起各种“外部工具”,帮Agent完成自己做不到的事 。
二、工具调用的3个核心场景(通俗版拆解)
Agent最常用的工具调用场景有3个,咱们一个个讲,每个场景都结合“奶茶Agent”的延伸需求来举例:
场景1:调用第三方API——获取外部数据
第三方API就像“Agent的信息窗口”——通过API,Agent能获取自己没有的外部数据(天气、地图、新闻、支付信息等)。
比如:奶茶Agent想知道“A店今天是否营业”,但自己没有实时营业数据,就需要调用“商家营业状态API”;想知道“去A店的实时路况”,就需要调用“地图导航API”。
核心逻辑:Agent → 发送请求(按API规范)→ 第三方服务器 → 返回数据(JSON/XML格式)→ Agent解析数据。
场景2:操作本地文件——读写本地数据
本地文件操作就像“Agent的记事本”——Agent能读取本地的文档、图片、表格,也能创建、修改、删除文件(比如帮你整理日志、生成报告、备份数据)。
比如:奶茶Agent想把“每次买奶茶的记录”保存到本地Excel文件;想读取你提前写好的“奶茶口味偏好清单”(txt文件),根据清单推荐奶茶。
核心逻辑:Agent → 调用文件操作工具 → 读取/写入本地文件 → 返回操作结果(成功/失败+数据)。
场景3:调用其他AI模型——借用高级能力
其他AI模型就像“Agent的专家顾问”——Agent自己做不了的复杂任务(比如图片识别、语音转文字、复杂文本生成),可以调用现成的AI模型来完成。
比如:奶茶Agent想识别你拍的“奶茶图片”是什么口味(三分糖/全糖),就调用图片识别AI模型;想把你说的“我要一杯珍珠奶茶”语音转换成文字,就调用语音转文字AI模型。
核心逻辑:Agent → 发送任务数据(图片/语音/文本)→ AI模型 → 返回处理结果 → Agent使用结果。
三、代码实战:3个场景完整实现(基于奶茶Agent拓展)
咱们基于之前的奶茶Agent,给它增加工具调用能力,分别实现“查A店营业状态(API调用)”“保存购买记录(本地文件操作)”“识别奶茶图片(AI模型调用)”三个功能。
先准备:工具调用模块基础框架
首先,咱们定义一个通用的工具调用模块类,包含“API调用工具”“文件操作工具”“AI模型调用工具”三个子工具,方便后续调用:
import requests
import json
import pandas as pd
from datetime import datetime
# 工具调用模块核心类
class ToolCallModule:
def __init__(self):
# 初始化各类工具
self.api_tool = APITool()
self.file_tool = FileTool()
self.ai_model_tool = AIModelTool()
# 统一调用入口:根据工具类型和参数调用对应工具
def call_tool(self, tool_type, **kwargs):
"""
tool_type: 工具类型(api/file/ai_model)
kwargs: 工具所需参数(比如api_url、file_path、model_input等)
"""
try:
if tool_type == "api":
# 调用第三方API
result = self.api_tool.call_api(**kwargs)
elif tool_type == "file":
# 操作本地文件
result = self.file_tool.operate_file(**kwargs)
elif tool_type == "ai_model":
# 调用其他AI模型
result = self.ai_model_tool.call_ai_model(**kwargs)
else:
result = {"success": False, "msg": "未知工具类型"}
return result
except Exception as e:
return {"success": False, "msg": f"工具调用失败:{str(e)}"}
# 1. 第三方API调用工具
class APITool:
def call_api(self, api_url, method="get", params=None, headers=None, data=None):
"""
调用第三方API
api_url: API地址
method: 请求方法(get/post)
params: get请求参数(字典)
headers: 请求头(字典)
data: post请求数据(字典)
"""
print(f"正在调用API:{api_url}")
try:
response = requests.request(
method=method,
url=api_url,
params=params,
headers=headers,
data=data,
timeout=10
)
response.raise_for_status() # 抛出HTTP错误
# 解析JSON响应(大部分API返回JSON格式)
result = response.json()
return {"success": True, "data": result, "msg": "API调用成功"}
except requests.exceptions.RequestException as e:
return {"success": False, "msg": f"API调用失败:{str(e)}"}
# 2. 本地文件操作工具
class FileTool:
def operate_file(self, operation_type, file_path, content=None, sheet_name=None):
"""
操作本地文件(支持txt、csv、excel)
operation_type: 操作类型(read_txt/write_txt/read_csv/write_csv/read_excel/write_excel)
file_path: 文件路径
content: 写入内容(仅write类操作需要)
sheet_name: Excel工作表名称(仅excel操作需要,默认"Sheet1")
"""
print(f"正在操作文件:{file_path}(操作类型:{operation_type})")
try:
if operation_type == "read_txt":
# 读取txt文件
with open(file_path, "r", encoding="utf-8") as f:
data = f.read()
return {"success": True, "data": data, "msg": "TXT文件读取成功"}
elif operation_type == "write_txt":
# 写入txt文件
with open(file_path, "w", encoding="utf-8") as f:
f.write(content)
return {"success": True, "msg": "TXT文件写入成功"}
elif operation_type == "read_csv":
# 读取csv文件(需要pandas库)
df = pd.read_csv(file_path)
data = df.to_dict("records") # 转换为字典列表
return {"success": True, "data": data, "msg": "CSV文件读取成功"}
elif operation_type == "write_csv":
# 写入csv文件
df = pd.DataFrame(content)
df.to_csv(file_path, index=False, encoding="utf-8-sig")
return {"success": True, "msg": "CSV文件写入成功"}
elif operation_type == "read_excel":
# 读取excel文件
sheet_name = sheet_name or "Sheet1"
df = pd.read_excel(file_path, sheet_name=sheet_name)
data = df.to_dict("records")
return {"success": True, "data": data, "msg": "Excel文件读取成功"}
elif operation_type == "write_excel":
# 写入excel文件
sheet_name = sheet_name or "Sheet1"
df = pd.DataFrame(content)
with pd.ExcelWriter(file_path, engine="openpyxl") as writer:
df.to_excel(writer, sheet_name=sheet_name, index=False)
return {"success": True, "msg": "Excel文件写入成功"}
else:
return {"success": False, "msg": "未知的文件操作类型"}
except Exception as e:
return {"success": False, "msg": f"文件操作失败:{str(e)}"}
# 3. AI模型调用工具(以调用OpenAI API为例,需提前安装openai库)
class AIModelTool:
def __init__(self, api_key=None):
# 初始化AI模型配置(这里以OpenAI为例)
self.api_key = api_key or "你的OpenAI API密钥" # 替换为自己的API密钥
# 导入openai库(需提前安装:pip install openai)
import openai
self.openai = openai
self.openai.api_key = self.api_key
def call_ai_model(self, model_type, **kwargs):
"""
调用AI模型
model_type: 模型类型(text_completion:文本生成,image_recognition:图片识别)
kwargs: 模型所需参数(比如prompt、image_url等)
"""
print(f"正在调用AI模型:{model_type}")
try:
if model_type == "text_completion":
# 文本生成(比如帮用户写奶茶推荐文案)
prompt = kwargs.get("prompt")
response = self.openai.ChatCompletion.create(
model="gpt-3.5-turbo",
messages=[{"role": "user", "content": prompt}]
)
result = response.choices[0].message["content"].strip()
return {"success": True, "data": result, "msg": "文本生成模型调用成功"}
elif model_type == "image_recognition":
# 图片识别(比如识别用户上传的奶茶图片是什么口味)
image_url = kwargs.get("image_url")
response = self.openai.ChatCompletion.create(
model="gpt-4-vision-preview",
messages=[
{"role": "user", "content": [
{"type": "text", "text": "请识别这张图片中的奶茶是什么口味(比如三分糖、全糖、少冰、去冰),并描述配料"},
{"type": "image_url", "image_url": {"url": image_url}}
]}
],
max_tokens=300
)
result = response.choices[0].message["content"].strip()
return {"success": True, "data": result, "msg": "图片识别模型调用成功"}
else:
return {"success": False, "msg": "未知的AI模型类型"}
except Exception as e:
return {"success": False, "msg": f"AI模型调用失败:{str(e)}"}
场景1实战:调用第三方API——查询奶茶店营业状态
假设咱们有一个“商家营业状态API”(这里用模拟API演示,实际开发中替换为真实API即可),奶茶Agent需要调用这个API,判断A店今天是否营业。
# 主程序:调用第三方API查询营业状态
if __name__ == "__main__":
# 初始化工具调用模块
tool_module = ToolCallModule()
# 1. 调用第三方API:查询A店营业状态
print("=== 场景1:调用第三方API查询营业状态 ===")
# 模拟API地址(实际开发中替换为真实API)
api_url = "https://api.example.com/shop/status"
params = {"shop_name": "A店", "date": datetime.now().strftime("%Y-%m-%d")}
headers = {"Authorization": "Bearer your_api_token"} # 真实API可能需要授权
api_result = tool_module.call_tool(
tool_type="api",
api_url=api_url,
method="get",
params=params,
headers=headers
)
if api_result["success"]:
shop_status = api_result["data"]["status"] # 假设API返回{"status": "open/closed", "msg": "..."}
print(f"A店今日营业状态:{shop_status}")
if shop_status == "open":
print(f"营业时段:{api_result['data']['business_hours']}")
else:
print(f"停业原因:{api_result['data']['reason']}")
else:
print(f"查询失败:{api_result['msg']}")
运行结果(模拟API返回):
=== 场景1:调用第三方API查询营业状态 ===
正在调用API:https://api.example.com/shop/status
A店今日营业状态:open
营业时段:09:00-22:00
场景2实战:操作本地文件——保存奶茶购买记录
奶茶Agent每次帮用户买完奶茶后,需要把购买记录(时间、店铺、口味、价格)保存到本地Excel文件,方便后续统计。
# 2. 操作本地文件:保存奶茶购买记录
print("\n=== 场景2:操作本地文件保存购买记录 ===")
# 购买记录数据
purchase_record = {
"time": datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
"shop_name": "A店",
"flavor": "三分糖+珍珠",
"price": 18,
"payment_method": "微信支付"
}
# 写入Excel文件(如果文件不存在会自动创建)
file_result = tool_module.call_tool(
tool_type="file",
operation_type="write_excel",
file_path="奶茶购买记录.xlsx",
content=[purchase_record], # 写入多条记录时传列表
sheet_name="购买记录"
)
if file_result["success"]:
print("购买记录已保存到:奶茶购买记录.xlsx")
# 读取文件验证
read_result = tool_module.call_tool(
tool_type="file",
operation_type="read_excel",
file_path="奶茶购买记录.xlsx",
sheet_name="购买记录"
)
if read_result["success"]:
print("读取验证:", read_result["data"])
else:
print(f"保存失败:{file_result['msg']}")
运行结果:
=== 场景2:操作本地文件保存购买记录 ===
正在操作文件:奶茶购买记录.xlsx(操作类型:write_excel)
购买记录已保存到:奶茶购买记录.xlsx
正在操作文件:奶茶购买记录.xlsx(操作类型:read_excel)
读取验证: [{'time': '2024-05-20 15:30:45', 'shop_name': 'A店', 'flavor': '三分糖+珍珠', 'price': 18, 'payment_method': '微信支付'}]
场景3实战:调用其他AI模型——识别奶茶图片口味
用户拍了一张奶茶图片,发给奶茶Agent,Agent需要调用OpenAI的图片识别模型,判断这杯奶茶的口味和配料。
# 3. 调用AI模型:识别奶茶图片口味
print("\n=== 场景3:调用AI模型识别奶茶图片 ===")
# 图片URL(可以是本地图片上传后的临时URL,或公网图片URL)
image_url = "https://example.com/milk_tea.jpg" # 替换为真实图片URL
ai_result = tool_module.call_tool(
tool_type="ai_model",
model_type="image_recognition",
image_url=image_url
)
if ai_result["success"]:
print("图片识别结果:")
print(ai_result["data"])
else:
print(f"识别失败:{ai_result['msg']}")
运行结果(模拟AI返回):
=== 场景3:调用AI模型识别奶茶图片 ==="
正在调用AI模型:image_recognition
图片识别结果:
这杯奶茶为三分糖甜度,配料包含珍珠和椰果,冰块较少(约1/3杯)。整体外观呈浅棕色,珍珠颗粒饱满,椰果呈半透明状,符合经典珍珠奶茶的特征。
四、工具调用模块的3个关键技巧(避坑指南)
实际开发中,工具调用会遇到各种问题,分享3个最实用的技巧:
1. 处理工具调用失败——重试机制
比如API调用超时、文件被占用、AI模型接口报错,这时候不能直接放弃,需要加“重试机制”:
# 给工具调用加重试机制(修改ToolCallModule的call_tool方法)
def call_tool(self, tool_type, retry_count=3, retry_interval=2, **kwargs):
"""
带重试机制的工具调用
retry_count: 最大重试次数
retry_interval: 重试间隔(秒)
"""
for i in range(retry_count):
try:
# 原工具调用逻辑
if tool_type == "api":
result = self.api_tool.call_api(**kwargs)
elif tool_type == "file":
result = self.file_tool.operate_file(**kwargs)
elif tool_type == "ai_model":
result = self.ai_model_tool.call_ai_model(**kwargs)
else:
result = {"success": False, "msg": "未知工具类型"}
if result["success"]:
return result
else:
print(f"工具调用失败(第{i+1}次):{result['msg']},{retry_interval}秒后重试...")
time.sleep(retry_interval)
except Exception as e:
print(f"工具调用异常(第{i+1}次):{str(e)},{retry_interval}秒后重试...")
time.sleep(retry_interval)
return {"success": False, "msg": f"重试{retry_count}次后仍失败"}
2. 工具参数校验——避免无效调用
比如调用API时少传参数、操作文件时路径错误,这时候需要提前校验参数:
# 给API调用加参数校验(修改APITool的call_api方法)
def call_api(self, api_url, method="get", params=None, headers=None, data=None):
# 参数校验
if not api_url.startswith(("http://", "https://")):
return {"success": False, "msg": "API地址格式错误,必须以http://或https://开头"}
# get请求参数不能为空(如果需要)
if method.lower() == "get" and params is None:
return {"success": False, "msg": "get请求参数params不能为空"}
# 后续原逻辑...
3. 工具结果解析——统一格式
不同工具返回的结果格式不一样(API返回JSON、文件返回字典、AI模型返回文本),需要统一解析成Agent能理解的格式:
# 统一工具结果格式(新增方法)
def parse_tool_result(self, tool_type, result):
"""统一结果格式为:{success: bool, content: 统一格式数据, msg: str}"""
if not result["success"]:
return {"success": False, "content": None, "msg": result["msg"]}
if tool_type == "api":
# API结果保留原始JSON
return {"success": True, "content": result["data"], "msg": "API调用成功"}
elif tool_type == "file":
# 文件结果根据操作类型整理
return {"success": True, "content": result["data"], "msg": result["msg"]}
elif tool_type == "ai_model":
# AI模型结果转换为字符串
return {"success": True, "content": str(result["data"]), "msg": result["msg"]}
五、总结:工具调用模块的核心是什么?
其实工具调用模块的核心很简单:“找到合适的工具→按规则调用→处理结果” 。
- 找到合适的工具:根据任务需求,选择API、文件工具或AI模型;
- 按规则调用:遵守工具的使用规范(参数格式、授权方式、调用频率);
- 处理结果:解析工具返回的数据,转换成Agent能使用的格式,同时处理失败情况。
有了工具调用模块,Agent的能力就不再局限于自身的四大模块,而是可以无限拓展:
- 调用支付API完成付款;
- 调用导航API规划路线;
- 调用邮件API发送报告;
- 调用机器学习模型做预测;
- 甚至调用其他Agent来协作完成复杂任务!
如果觉得这篇文章好懂、实用,别忘了点赞、转发,让更多人一起入门AI~ 有任何问题,评论区留言交流呀!

更多推荐


所有评论(0)