工具使用综述
引言
语言模型虽然擅长文本生成和推理,但在精确计算、实时信息获取、代码执行等方面存在固有局限。工具使用(Tool Use)让 Agent 能够调用外部函数和 API,极大地扩展了其能力边界。
符号接地问题(Symbol Grounding Problem)
Harnad(1990)提出:符号系统中的符号如何获得意义?LLM 处理的是 token(符号),但真实世界的操作需要与物理世界和数字系统交互。工具使用是 LLM"接地"的关键途径。
graph LR
subgraph "无工具的 LLM"
A[语言能力] --> B[文本生成]
A --> C[推理]
A --> D[知识回忆]
end
subgraph "工具增强的 Agent"
E[语言能力] --> F[文本生成]
E --> G[推理]
E --> H[知识回忆]
E --> I[工具调用]
I --> J[代码执行]
I --> K[API 调用]
I --> L[数据库查询]
I --> M[浏览器操作]
I --> N[文件读写]
end
发展历程
早期探索
| 时间 | 工作 | 贡献 |
|---|---|---|
| 2021 | WebGPT(OpenAI) | LLM 学会使用搜索引擎 |
| 2022 | LaMDA(Google) | 对话中调用外部工具 |
| 2023.02 | Toolformer(Meta) | LLM 自学何时及如何使用工具 |
| 2023.03 | HuggingGPT | LLM 作为控制器调度 AI 模型 |
| 2023.03 | ChatGPT Plugins | 商业化的工具生态 |
| 2023.06 | Function Calling(OpenAI) | 标准化的函数调用协议 |
| 2023.10 | Gorilla | 大规模 API 调用的微调模型 |
| 2024.03 | Claude Tool Use(Anthropic) | 原生工具使用支持 |
| 2024.11 | MCP(Anthropic) | 模型上下文协议标准 |
Toolformer 的核心思想
Schick et al.(2023)的 Toolformer 让 LLM 自主学习工具使用:
- 对训练文本中可能需要工具的位置插入 API 调用标注
- 执行 API 调用获取结果
- 只保留有用的 API 调用(降低困惑度的那些)
- 用这些数据微调模型
为什么工具如此重要
LLM 的固有局限
| 局限 | 示例 | 工具解决方案 |
|---|---|---|
| 数学计算不精确 | 大数乘法出错 | 计算器/代码执行器 |
| 知识有截止日期 | 不知道最新新闻 | 搜索引擎/API |
| 无法执行操作 | 不能发送邮件 | 邮件 API |
| 无法访问私有数据 | 不知道公司内部信息 | 数据库查询 |
| 多模态能力有限 | 图像生成 | DALL-E/Stable Diffusion API |
工具使用的分类
graph TB
TU[工具使用] --> INFO[信息获取型]
TU --> ACT[行动执行型]
TU --> COMP[计算增强型]
TU --> CREATE[内容创作型]
INFO --> S[搜索引擎]
INFO --> DB[数据库查询]
INFO --> API1[信息 API]
ACT --> EMAIL[发送邮件]
ACT --> FILE[文件操作]
ACT --> DEPLOY[部署服务]
COMP --> CODE[代码执行]
COMP --> CALC[计算器]
COMP --> DATA[数据分析]
CREATE --> IMG[图像生成]
CREATE --> DOC[文档生成]
CREATE --> CHART[图表绘制]
工具使用的基本流程
1. 理解任务 → 2. 规划工具使用 → 3. 选择工具 → 4. 构造参数 → 5. 执行调用 → 6. 解析结果 → 7. 整合到回答
# 基本的工具使用循环
def agent_loop(query, tools, llm):
messages = [{"role": "user", "content": query}]
while True:
response = llm.chat(messages, tools=tools)
if response.finish_reason == "tool_calls":
# LLM 决定调用工具
for tool_call in response.tool_calls:
result = execute_tool(
tool_call.function.name,
tool_call.function.arguments
)
messages.append({
"role": "tool",
"tool_call_id": tool_call.id,
"content": str(result)
})
else:
# LLM 给出最终回答
return response.content
工具描述的重要性
好的工具描述是工具使用成功的关键。LLM 依靠工具描述来决定何时使用什么工具。
# 好的工具描述
good_tool = {
"name": "search_knowledge_base",
"description": "搜索内部知识库。当用户询问公司政策、产品文档或技术规范时使用。不适用于一般性知识问题。",
"parameters": {
"query": {
"type": "string",
"description": "搜索查询,使用自然语言描述要查找的信息"
},
"category": {
"type": "string",
"enum": ["policy", "product", "technical"],
"description": "搜索类别,帮助缩小搜索范围"
}
}
}
# 差的工具描述
bad_tool = {
"name": "search",
"description": "搜索",
"parameters": {
"q": {"type": "string"}
}
}
本章结构
- Function Calling 机制 - 各平台的函数调用协议
- MCP 与工具协议 - 模型上下文协议和工具标准化
- 代码执行与沙箱 - 安全的代码执行环境
- 浏览器与计算机操作 - GUI 交互能力
- API 编排与工具选择 - 工具选择与编排策略
参考文献
- Schick, T., et al. (2023). "Toolformer: Language Models Can Teach Themselves to Use Tools"
- Nakano, R., et al. (2021). "WebGPT: Browser-assisted question-answering with human feedback"
- Shen, Y., et al. (2023). "HuggingGPT: Solving AI Tasks with ChatGPT and its Friends in Hugging Face"
- Patil, S. G., et al. (2023). "Gorilla: Large Language Model Connected with Massive APIs"
- Qin, Y., et al. (2024). "Tool Learning with Large Language Models: A Survey"