Appearance
62. 工具使用模式(Tool Use Pattern)
难度 P1 高频 · 岗位 应用 · 频率 ★★★★☆ · 预计阅读 8 min 公司 OpenAI · Anthropic · Google 相关题 Q61 反射模式 · Q63 ReAct 模式 · Q22 Function Calling
本题阅读地图
- 面试场景还原 — 1 min
- TL;DR 速记 — 30 sec
- 图解 — 30 sec
- 详细解析 — 5 min
- 4.1 LLM 的两大死穴:知识冻结与不能行动
- 4.2 工具使用模式的核心机制
- 4.3 工具定义与调用流程详解
- 4.4 常见工具类型与适用场景
- 4.5 工具设计最佳实践
- 常见踩坑与反例 — 1 min
- 面试官可能继续追问 — 1 min
面试场景还原
👔面试官:Agent 和普通 LLM 有什么区别?为什么 Agent 能做事而 LLM 只能说话?
🙋♂️我:Agent 可以调用工具,比如搜索、查数据库。
�面试官:对,但这只是表象。你知道 LLM 本质上只能输出文本,它自己其实不能「调用」任何东西。那工具使用模式到底是怎么工作的?模型和执行的关系是什么?
🙋♂️我:模型生成调用指令,然后代码去执行?
👔面试官:很好。那具体流程是什么样的?模型怎么知道该调哪个工具?工具返回的结果怎么回到模型继续处理?工具设计有哪些要点?
🙋♂️我:呃……
👔面试官:工具使用模式 的核心是「模型决策,代码执行」。关键是:1)模型只输出调用意图(JSON),真正的 HTTP 请求是代码发的;2)工具描述(description)是模型选择工具的唯一依据,要写清楚;3)返回结果要结构化,模型才能继续推理。
TL;DR 速记
- 是什么:让 LLM 调用外部工具扩展能力的基础模式
- 解决痛点:知识冻结(训练数据有截止日期)+ 不能行动(只能输出文本)
- 核心机制:模型输出调用决策(JSON),宿主代码执行实际调用
- 关键设计:清晰的工具描述、明确的参数定义、结构化的返回结果
- 模型与执行:模型是大脑(决策),代码是手脚(执行)
图解
图 1:工具使用模式的决策-执行分离架构
图 2:普通 LLM vs 工具增强 Agent
详细解析
LLM 的两大死穴:知识冻结与不能行动
要理解工具使用模式的价值,先看 LLM 不借助工具时的根本局限:
死穴 1:知识冻结 LLM 的知识完全来自训练数据,而训练数据有截止日期。你问它「今天的天气」「最新的股价」,它完全不知道。就像一个人毕业之后不再看新闻,对世界的新变化一无所知。
死穴 2:不能行动 LLM 本质上是一个文本生成器,所有输出都是一串文字。它不能发送邮件、不能查询数据库、不能执行代码。哪怕它给你写了一封完美的邮件正文,「点击发送」这个动作它是做不了的。
这两个局限决定了:纯 LLM 只能做「问答」类任务,稍微复杂一点、需要与外部世界交互的任务它就无能为力。
工具使用模式就是来解决这两个问题的。
工具使用模式的核心机制
工具使用模式的核心设计是**「决策与执行分离」**:
模型负责决策
- 理解用户意图
- 判断是否需要工具
- 如果需要,选择哪个工具、填什么参数
- 以结构化格式(通常是 JSON)输出调用意图
宿主代码负责执行
- 解析模型的输出
- 如果是工具调用,实际执行 HTTP 请求/数据库查询/代码运行
- 获取结果后返回给模型
- 模型基于结果继续推理或输出给用户
关键认知:模型自己不会发 HTTP 请求,它只是告诉你「我想调用天气接口,参数是北京」。真正发送请求、处理响应的是你的代码。这个分工是理解工具使用模式最重要的点。
工具定义与调用流程详解
完整的工具调用流程分为五步:
第一步:工具定义(Tool Definition) 开发者定义可用的工具,包括:
- 工具名称(name):唯一标识
- 工具描述(description):告诉模型这个工具是干嘛的
- 参数定义(parameters):参数名、类型、是否必填、描述
json
{
"name": "get_weather",
"description": "获取指定城市的当前天气情况",
"parameters": {
"type": "object",
"properties": {
"city": {
"type": "string",
"description": "城市名称,如\"北京\"、\"上海\""
}
},
"required": ["city"]
}
}第二步:模型决策(Model Decision) 用户提问后,模型判断是否需要调用工具:
- 分析用户意图
- 匹配可用的工具描述
- 如果匹配成功,生成工具调用请求
第三步:调用执行(Execution) 宿主程序解析模型输出,执行实际调用:
python
# 模型输出
function_call = {
"name": "get_weather",
"arguments": {"city": "北京"}
}
# 宿主代码执行
result = weather_api.get_weather(city="北京")第四步:结果回传(Observation) 工具执行结果返回给模型:
工具返回:{"temperature": 25, "condition": "晴天", "humidity": 45}第五步:最终输出(Response) 模型基于工具结果生成最终回答:
北京今天天气不错,晴天,25°C,湿度45%。常见工具类型与适用场景
| 工具类型 | 典型用途 | 示例 |
|---|---|---|
| 搜索引擎 | 获取实时信息、最新资讯 | Google Search、Bing API |
| 数据库查询 | 查询结构化数据 | SQL 查询、MongoDB 查询 |
| 代码执行器 | 执行代码、复杂计算 | Python 解释器、沙箱环境 |
| 文件操作 | 读写文件、处理文档 | 文件系统 API |
| 外部 API | 调用第三方服务 | 天气、地图、支付、邮件 |
| 向量数据库 | 语义检索、知识库查询 | Pinecone、Milvus |
场景 1:知识问答增强 用户问最新信息时,先调用搜索引擎获取结果,再基于结果生成回答。
场景 2:数据分析 用户上传 CSV,Agent 调用代码执行器读取、分析数据,生成图表和结论。
场景 3:业务流程自动化 用户说「帮我订一张明天去上海的机票」,Agent 调用航班查询、预订、支付等一系列工具完成闭环。
工具设计最佳实践
工具设计的好坏直接影响 Agent 的调用准确率:
1. 工具描述要清晰具体
❌ 差的描述:"搜索工具"
✅ 好的描述:"互联网搜索引擎,用于获取实时信息、最新新闻、当前事件。当用户询问今天/本周/今年的信息时使用。"2. 参数说明要完整
json
{
"name": "send_email",
"description": "发送邮件给指定收件人",
"parameters": {
"to": {
"type": "string",
"description": "收件人邮箱地址,如\"user@example.com\""
},
"subject": {
"type": "string",
"description": "邮件主题,简明扼要概括邮件内容"
},
"body": {
"type": "string",
"description": "邮件正文内容"
}
},
"required": ["to", "subject", "body"]
}3. 返回结果结构化 工具返回应该是结构化的(JSON/XML),而不是纯文本。这样模型更容易理解和使用。
4. 错误处理标准化 工具出错时返回统一的错误格式:
json
{
"error": true,
"error_type": "API_TIMEOUT",
"message": "请求超时,请稍后重试"
}5. 工具数量控制 单次请求挂载的工具不要太多(建议 5-10 个),否则模型选择困难、延迟增加。可以动态挂载相关工具。
常见踩坑与反例
踩坑 1:以为模型自己在执行工具
错误描述:「Agent 自己去访问网络、查数据库」
问题:模型本质是文本生成器,它不会发 HTTP 请求。
正确理解:模型只输出调用意图(JSON),真正的网络请求是宿主代码发的。模型是「大脑」做决策,代码是「手脚」做执行。
踩坑 2:工具描述写得模糊
错误做法:
json
{
"name": "search",
"description": "搜索功能",
"parameters": {"query": "搜索词"}
}问题:模型不知道这个「搜索」是搜互联网、搜本地文件还是搜数据库,不知道该什么时候调用。
正确做法:描述要写清楚工具的能力边界和适用场景。
踩坑 3:工具返回非结构化文本
错误做法: 工具返回一大段纯文本,没有结构。
问题:模型难以从中提取关键信息。
正确做法:返回结构化 JSON,明确字段含义。
踩坑 4:没有权限控制和安全边界
错误做法:
- 工具可以任意访问文件系统
- 敏感操作(删除、支付)不需要确认
正确做法:
- 最小权限原则:工具只能访问必要的资源
- 敏感操作需要人工确认
- 工具执行在沙箱环境中
踩坑 5:工具调用失败后没有处理
错误做法: 工具调用失败直接把错误抛给用户。
正确做法:
- Agent 应该能感知工具失败
- 分析失败原因(参数错?服务不可用?)
- 尝试修复或换工具重试
- 实在不行才告知用户
面试官可能继续追问
追问 1:工具使用模式和 Function Calling 有什么关系? 答题要点:Function Calling 是模型层面的能力(输出结构化调用请求),工具使用模式是应用层面的设计(如何定义、调用、管理工具)。Function Calling 是工具使用模式的技术基础。
追问 2:模型怎么决定调哪个工具? 答题要点:模型基于工具描述(description)和用户意图做匹配。描述写得越清晰,模型选择越准确。可以引导模型在思考过程中先列出候选工具再决定。
追问 3:工具调用的延迟怎么优化? 答题要点:1)并行调用多个独立工具;2)缓存常用工具结果;3)异步调用,边执行边返回进度;4)工具预加载和连接池。
追问 4:工具使用模式和多智能体有什么区别? 答题要点:工具是被动的(被 Agent 调用),多智能体是主动的(Agent 之间协作)。工具通常没有智能,只是执行特定功能;智能体有自己的推理和决策能力。两者可以结合:智能体 A 调用工具,智能体 B 审查结果。
面试总结
工具使用模式是 Agent 从「会说话」进化到「能做事」的核心能力。面试时强调三点:
- 核心价值:解决 LLM 知识冻结和不能行动的两大局限
- 核心机制:模型决策(输出 JSON),代码执行(实际调用),决策与执行分离
- 设计要点:工具描述要清晰、参数要明确、返回要结构化、安全要有边界
记住:模型永远不会自己发 HTTP 请求,它只是告诉你该调什么。真正执行的是你的代码。这个「大脑-手脚」的分工是理解工具使用模式的关键。