Agent工具使用
工具使用能力是Agent突破LLM固有局限的关键。通过工具,Agent可以获取实时信息、 执行计算、操作文件、调用外部服务,极大地扩展了Agent的能力边界。 本文将深入探讨工具定义、选择策略和执行机制。
预计阅读时间:55分钟·难度:中级
工具使用概述
为什么需要工具
大语言模型虽然具备强大的语言理解和生成能力,但存在固有局限:
- 知识截止:训练数据有时间截止点,无法获取最新信息
- 计算能力弱:复杂计算容易出错,不适合精确数学运算
- 无外部交互:无法直接访问网络、文件系统、数据库等
- 幻觉问题:可能生成不准确或虚构的信息
- 无执行能力:只能生成文本,无法执行实际操作
工具使用(Tool Use)正是解决这些局限的关键机制。通过工具,Agent可以:
工具带来的能力扩展
- 获取实时数据(天气、新闻、股价等)
- 执行精确计算和数据处理
- 访问和操作文件系统
- 调用外部API和服务
- 执行代码和脚本
- 与数据库交互
- 发送邮件、消息等通知
- 控制物理设备(通过API)
工具带来的能力
| 能力类别 | 示例工具 | 应用场景 |
|---|---|---|
| 信息获取 | 搜索引擎、知识库查询 | 实时新闻、事实核查 |
| 数据处理 | 计算器、数据分析 | 财务计算、统计分析 |
| 文件操作 | 文件读写、格式转换 | 文档处理、代码编辑 |
| 外部服务 | API调用、数据库操作 | 业务系统集成 |
| 代码执行 | Python执行器、Shell | 自动化脚本、数据处理 |
工具定义
定义规范
工具定义需要遵循特定规范,使LLM能够理解工具的功能和正确使用方法。 主流LLM平台(OpenAI、Claude等)都采用类似的定义格式。
OpenAI Function Calling 格式
{
"type": "function",
"function": {
"name": "get_weather",
"description": "获取指定城市的当前天气信息。当用户询问天气相关问题时使用此工具。",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称,如'北京'、'上海'"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "温度单位,默认摄氏度",
"default": "celsius"
}
},
"required": ["city"]
}
}
}Claude Tool Use 格式
{
"name": "get_weather",
"description": "获取指定城市的当前天气信息",
"input_schema": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称"
},
"unit": {
"type": "string",
"enum": ["celsius", "fahrenheit"],
"description": "温度单位"
}
},
"required": ["city"]
}
}参数设计
参数设计原则
- 必要的设为必填:执行工具必须的参数设为required
- 提供默认值:可选参数提供合理的默认值
- 使用枚举限制:限定取值范围的参数使用enum
- 描述要清晰:每个参数都需要清晰的description
- 避免过度复杂:参数结构尽量简单,避免深层嵌套
- 考虑验证需求:设计时考虑参数验证的便利性
复杂参数示例
{
"name": "search_products",
"description": "搜索商品信息",
"parameters": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "搜索关键词"
},
"filters": {
"type": "object",
"description": "筛选条件",
"properties": {
"price_range": {
"type": "object",
"properties": {
"min": { "type": "number", "description": "最低价格" },
"max": { "type": "number", "description": "最高价格" }
}
},
"category": {
"type": "string",
"description": "商品分类"
},
"brand": {
"type": "string",
"description": "品牌名称"
}
}
},
"sort_by": {
"type": "string",
"enum": ["price_asc", "price_desc", "rating", "sales"],
"description": "排序方式"
},
"limit": {
"type": "integer",
"description": "返回结果数量",
"default": 10,
"minimum": 1,
"maximum": 100
}
},
"required": ["query"]
}
}工具类型
搜索类工具
搜索工具是Agent最常用的工具类型之一,用于获取实时信息和知识。
常见搜索工具
- 网络搜索:Google/Bing搜索API、DuckDuckGo
- 知识库搜索:向量数据库检索、全文搜索
- 文档搜索:PDF解析、网页内容提取
- 数据库查询:SQL生成与执行
计算类工具
计算工具用于执行数学计算、数据处理等需要精确性的任务。
计算工具类型
- 基础计算器:四则运算、数学函数
- 代码执行器:Python解释器、沙箱环境
- 数据分析:统计分析、可视化
- 单位转换:货币、度量衡、时区
文件类工具
文件操作工具示例
# 文件读取工具
{
"name": "read_file",
"description": "读取文件内容",
"parameters": {
"type": "object",
"properties": {
"path": { "type": "string", "description": "文件路径" },
"encoding": { "type": "string", "default": "utf-8" }
},
"required": ["path"]
}
}
# 文件写入工具
{
"name": "write_file",
"description": "写入内容到文件",
"parameters": {
"type": "object",
"properties": {
"path": { "type": "string", "description": "文件路径" },
"content": { "type": "string", "description": "文件内容" },
"mode": {
"type": "string",
"enum": ["write", "append"],
"default": "write"
}
},
"required": ["path", "content"]
}
}API类工具
API工具用于调用外部服务和系统,是Agent与外部世界交互的主要方式。
API工具分类
- REST API:HTTP请求,支持GET/POST/PUT/DELETE
- GraphQL:灵活的查询语言,按需获取数据
- SDK封装:将第三方SDK封装为工具
- 数据库API:ORM操作、原生SQL
工具选择策略
选择流程
Agent选择工具的过程是一个推理决策过程,通常包括以下步骤:
工具选择流程
1. 分析任务需求 ↓ 2. 匹配工具描述 - 遍历可用工具列表 - 将任务需求与工具description匹配 ↓ 3. 选择最合适的工具 - 可能有多个候选工具 - 根据上下文选择最佳匹配 ↓ 4. 构造参数 - 从上下文中提取参数值 - 验证参数类型和约束 ↓ 5. 执行工具调用 ↓ 6. 解析返回结果
选择优化
提高工具选择准确性的方法
- 优化工具描述:清晰描述工具的用途和使用场景
- 工具分类:按功能分类,减少选择范围
- 示例驱动:提供工具使用的示例
- 上下文增强:在提示中提供更多上下文信息
- 反馈学习:记录选择错误,持续优化
工具执行机制
执行流程
完整执行流程
# Agent工具执行循环
while not task_complete:
# 1. LLM分析当前状态,决定下一步行动
response = llm.generate(
messages=conversation_history,
tools=available_tools
)
# 2. 检查是否需要调用工具
if response.tool_calls:
for tool_call in response.tool_calls:
# 3. 验证工具和参数
tool = get_tool(tool_call.name)
validated_params = validate(
tool_call.arguments,
tool.parameters_schema
)
# 4. 执行工具
try:
result = tool.execute(validated_params)
except ToolExecutionError as e:
result = {"error": str(e)}
# 5. 将结果添加到对话历史
conversation_history.append({
"role": "tool",
"name": tool_call.name,
"content": serialize(result)
})
else:
# 没有工具调用,返回最终答案
return response.content错误处理
常见错误类型
- 参数错误:缺少必填参数、类型不匹配、值超出范围
- 执行错误:网络超时、服务不可用、权限不足
- 结果错误:返回格式异常、数据为空、结果不符合预期
- 超时错误:执行时间超过限制
错误处理策略
def execute_with_retry(tool, params, max_retries=3):
"""带重试的工具执行"""
for attempt in range(max_retries):
try:
# 参数验证
validated = validate_params(params, tool.schema)
# 执行工具
result = tool.execute(validated)
# 结果验证
if validate_result(result):
return {"success": True, "data": result}
else:
return {"success": False, "error": "Invalid result"}
except ValidationError as e:
return {"success": False, "error": f"参数错误: {e}"}
except TimeoutError:
if attempt < max_retries - 1:
continue # 重试
return {"success": False, "error": "执行超时"}
except Exception as e:
return {"success": False, "error": str(e)}安全考虑
输入验证
严格验证所有工具输入,防止注入攻击。 特别是文件路径、SQL语句、Shell命令等高风险参数。
权限控制
为工具设置最小必要权限。限制可访问的文件、目录、API端点。
敏感信息保护
不在工具调用日志中记录敏感信息。 对API密钥、密码等进行脱敏处理。
执行隔离
代码执行应在沙箱环境中进行,限制系统资源和网络访问。
代码示例
LangChain工具定义示例
from langchain.tools import tool
from pydantic import BaseModel, Field
# 使用Pydantic定义参数模型
class SearchInput(BaseModel):
query: str = Field(description="搜索关键词")
num_results: int = Field(default=5, description="返回结果数量")
# 使用装饰器定义工具
@tool("search_web", args_schema=SearchInput)
def search_web(query: str, num_results: int = 5) -> str:
"""
搜索互联网获取最新信息。
当需要查询实时数据、新闻、具体事实时使用此工具。
"""
# 实际搜索逻辑
results = perform_search(query, num_results)
return format_results(results)
# 使用工具
from langchain.agents import create_openai_functions_agent
from langchain_openai import ChatOpenAI
tools = [search_web]
llm = ChatOpenAI(model="gpt-4-turbo")
agent = create_openai_functions_agent(llm, tools)最佳实践
1. 提供清晰的工具描述
工具描述应该明确说明功能、使用场景和限制, 帮助LLM正确选择和使用工具。
2. 设计合理的参数结构
参数应该直观易懂,避免过度复杂。 提供合理的默认值和清晰的描述。
3. 实现完善的错误处理
对所有可能的错误情况进行处理, 返回有意义的错误信息,帮助Agent调整策略。
4. 控制工具数量
避免一次提供过多工具。工具过多会增加选择难度, 建议按场景分组提供,或使用工具选择机制。
5. 记录和分析工具使用
记录工具调用日志,分析使用模式, 持续优化工具定义和选择策略。