工具调用(Tool Use)
先说结论
Tool Use 是指 LLM 根据用户请求,生成结构化的工具调用指令(如 JSON 格式的函数名和参数),从而与外部系统交互以完成语言模型自身无法独立完成的任务。
QUESTION 面试高频:LLM 为什么需要工具调用?有哪些方法论? LLM 的能力边界在于:不能访问实时信息、不能执行计算、不能操作外部系统、不能访问私有数据。工具调用突破了这些限制。主要方法论有五种:Function Calling(结构化 API 调用)、ReAct(推理+行动交替)、Toolformer(模型自学调用)、Act-as-Tool(自然语言描述)、Code-as-Action(生成代码执行)。
方法论对比
| 方法 | 核心思想 | 代表工作 | 优势 | 劣势 |
|---|---|---|---|---|
| Function Calling | LLM 输出结构化 JSON 调用工具 | OpenAI/Anthropic API | 接口规范,易集成 | 依赖平台支持 |
| ReAct | 交替执行推理(Thought)和行动(Action) | Yao et al., 2022 | 可解释,减少幻觉 | 步数多,延迟高 |
| Toolformer | 模型自学插入 API 调用 | Schick et al., 2023 | 无需人工标注 | 仅限特定 API |
| Act-as-Tool | 用自然语言描述工具,LLM 自行编排 | Prompt-based | 零训练成本 | 不可靠 |
| Code-as-Action | 生成代码来执行操作 | CodeAct, OpenInterpreter | 灵活性极高 | 安全风险大 |
ReAct 循环详解
用户问题
↓
Thought(推理):我需要先查找当前的天气信息
↓
Action(行动):调用 weather_api(city="北京", date="2025-04-19")
↓
Observation(观察):北京今日晴,气温 22°C
↓
Thought(推理):现在我有了天气数据,可以回答用户了
↓
Answer(回答):北京今天是晴天,气温 22°C
QUESTION 面试高频:ReAct 和 Chain-of-Thought 有什么区别? CoT 是纯推理——模型只在"脑子里想",不与外界交互。ReAct 是推理+行动——模型在每一步都可以调用工具获取外部信息,再基于新信息继续推理。ReAct = CoT + Tool Use。关键优势:ReAct 可以通过工具验证自己的推理,减少幻觉。
训练方法
| 训练阶段 | 方法 | 说明 |
|---|---|---|
| SFT | 在 (查询, 工具定义, 正确调用) 三元组上训练 | 建立基础工具调用能力 |
| 拒绝采样 | 生成多条轨迹,筛选成功轨迹用于微调 | 提高成功率 |
| RLHF/RLAIF | 以任务成功为奖励信号优化 | 提升复杂多步工具使用 |
| 课程学习 | 从单工具简单任务逐步增加复杂度 | 稳定训练过程 |
| 蒸馏 | 从大模型蒸馏工具调用能力到小模型 | 降低部署成本 |
SFT 微调配置
- 方法:LoRA / QLoRA 降低显存需求
- 典型配置:rank=64, alpha=128, 学习率 2e-5
- 数据量:通常 10K-100K 条
- 训练轮次:2-3 epoch
工具设计最佳实践
QUESTION 面试高频:如何设计好的工具描述?
工具描述要素
{
"name": "search_database", # 清晰、动词开头
"description": "在客户数据库中搜索匹配条件的记录。
支持按姓名、邮箱、订单号搜索。
返回最多10条匹配记录。", # 功能、限制、返回值
"parameters": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "搜索关键词,可以是姓名、邮箱或订单号"
},
"field": {
"type": "string",
"enum": ["name", "email", "order_id"],
"description": "指定搜索字段"
}
},
"required": ["query"]
}
}
常见工具类型与设计要点
| 工具类型 | 设计要点 | 常见错误 |
|---|---|---|
| 搜索工具 | 明确搜索范围、返回格式和限制 | 描述太模糊,返回格式不明确 |
| 计算工具 | 明确输入输出单位和精度 | 未指定单位导致误解 |
| 数据库工具 | 明确查询能力边界和权限 | 暴露过多内部结构 |
| 代码执行工具 | 必须沙箱化、超时控制 | 未限制执行时间和资源 |
| API 调用工具 | 明确错误处理和重试逻辑 | 未处理 API 限流和超时 |
设计时真正要权衡什么
- 强制调用 vs 自主决策:强制调用保证执行但丧失灵活性;自主决策更自然但可能漏调用
- 工具数量:10-20 个是舒适区,超过需要先做路由筛选
- 严格 Schema vs 宽松描述:严格 Schema 保证可解析但描述能力受限
- 单步 vs 多步执行:单步简单可控但能力有限;多步能解决复杂问题但引入累积错误
- 安全沙箱 vs 开放执行:代码执行必须在沙箱中,但沙箱限制功能
安全考量
| 风险 | 说明 | 缓解措施 |
|---|---|---|
| Prompt 注入 | 恶意输入操纵工具调用 | 输入验证、参数校验 |
| 权限滥用 | 调用超出预期权限的工具 | 最小权限、审批流程 |
| 数据泄露 | 工具调用泄露敏感信息 | 数据脱敏、输出过滤 |
| 代码注入 | 通过代码执行工具执行恶意代码 | 沙箱隔离、白名单 |
| 成本攻击 | 大量调用消耗资源 | 调用频率限制、预算上限 |
前沿趋势(2024-2025)
- 并行工具调用:一次生成多个独立工具调用,减少延迟
- 复杂工具编排:多步工具链的规划和执行(Workflow Agent)
- 工具发现与学习:模型自动理解新工具的用法
- 多模态工具:支持图像、音频、视频输入输出的工具
- Agentic 框架整合:与 LangChain、AutoGen、OpenAI Agents SDK 深度整合
如果要对外讲,可以怎么概括
"Tool Use 是 LLM 从'只能说话'到'能做事'的关键能力跃迁。核心机制是通过在请求中注入工具的 JSON Schema,让模型在推理时判断是否需要调用工具,并生成结构化的函数调用。ReAct 框架进一步将工具使用与推理过程结合,通过 Thought-Action-Observation 的循环实现了可解释的智能体行为。在训练层面,业界通常采用 SFT 建立基础能力、再用拒绝采样或 RL 提升成功率。工程落地中最大的挑战是工具描述的质量和错误处理的鲁棒性——一个描述不清的工具有如盲人摸象,而缺乏防御性解析的系统在生产环境中会频繁崩溃。"
最后记几条
- 工具描述是第一优先级:模型对工具的理解完全依赖描述文本
- ReAct = 推理 + 行动的交替循环:不是简单"调用工具"
- 10-20 个工具是舒适区:超过此数量需要先做路由筛选
- 并行调用是性能关键:无依赖的工具应并行执行
- 安全是底线:任何有副作用的工具调用必须有确认和回滚
参考资料
- Yao, S. et al. "ReAct: Synergizing Reasoning and Acting in Language Models" (ICLR 2023)
- Schick, T. et al. "Toolformer: Language Models Can Teach Themselves to Use Tools" (NeurIPS 2023)
- Patil, S. et al. "Gorilla: Large Language Model Connected with Massive APIs" (2023)
- Qin, Y. et al. "ToolLLM: Facilitating Large Language Models to Master 16000+ Real-world APIs" (ICLR 2024)
- OpenAI Function Calling: https://platform.openai.com/docs/guides/function-calling