导读:当我们看到豆包自动搜索网页、Claude 分析 Excel 表格、甚至 AI Agent 操作 Mac Mini 时,我们往往会惊叹:“AI 难道有自我意识了吗?”
作为开发者,我们需要清醒地认识到:这是一个精心设计的错觉。
那个在显卡里疯狂跑的 LLM,本质上还是个“词语接龙”游戏,是被困在服务器里的“缸中大脑”。它看不见屏幕,摸不到键盘。那么,这个只能预测下一个 Token 的概率模型,是如何突破物理限制,去调用 API、读数据库、操作工具的?
本文将带你深入 Tool Use 的技术内核,并通过一段完整的 DeepSeek 实战代码,彻底搞懂LLM + Tools = Agent的真正含义。
一、 核心认知:工具即语言
在深入代码之前,必须先建立一个核心认知:大模型不懂什么是天气 API,也不懂数据库查询,但它听得懂语言。
Tool Use 的本质,不是让 AI 学会了编程,而是我们将工具降维成了语言。这个过程可以分为三个精密咬合的阶段:
1. 认知植入 (Cognitive Implantation)
在执行任务之前,我们在 System Prompt 或 API 请求中配置 tools 参数时,其实是在做一件非常精妙的事——认知植入。
我们通过 JSON Schema 将复杂的软件接口函数,“翻译”成大模型能理解的使用说明书。例如,一个获取股票收盘价的函数 get_close_price,在大模型眼里只是一段文本描述:
json
编辑
1{
2 "name": "get_closing_price",
3 "description": "获取指定股票的收盘价",
4 "parameters": {
5 "type": "object",
6 "properties": {
7 "name": { "type": "string", "description": "股票名称" }
8 },
9 "required": ["name"]
10 }
11}
在这个阶段,复杂的软件工具被降维成了纯粹的文本约束。LLM 并不执行代码,它只是记住了:“当用户问股价时,我可以输出一段符合上述格式的文本。”
2. 意图识别与“自言自语”
当用户提问“青岛啤酒的收盘价是多少?”时,LLM 的推理引擎开始工作:
- 检索训练语料:发现自己无法直接回答实时股价。
- 回溯认知植入:发现工具列表里有
get_closing_price。 - 生成调用指令:AI 会停止与用户的直接对话,转而开始“自言自语”。它严格按照说明书,生成一段结构化的自然语言(Tool Calls):
json
编辑
1tool_calls: [{
2 type: 'function',
3 function: {
4 name: 'get_closing_price',
5 arguments: "{"name": "青岛啤酒"}"
6 }
7}]
注意:此时 LLM 并没有执行函数!它只是在“赌”这段代码发出后,会有人(Runtime)响应。它依赖的是强大的模式识别和逻辑推理能力,将 API 的精确性转化为语言的概率预测。
3. Runtime 的介入
这是传统软件世界与 AI 世界的交汇点。
- LLM 的职责:决策要调什么工具,传什么参。
- Runtime (Node/Python/Java) 的职责:只管执行,拿到结果。
关键在于:工具执行的结果不是直接返回给用户,而是返回给大模型。大模型将工具返回的结果作为新的上下文(Context),再次进行推理,最终生成人类可读的自然语言回复。
这就是 LLM + Tools = Agent 的完整闭环。
二、 实战复现:从“缸中大脑”到“股票分析师”
下面我们通过一段基于 DeepSeek 的完整代码,在本地复现上述全过程。这段代码展示了新旧范式的融合:既有传统的函数定义,又有 AI 时代的认知植入。
1. 环境准备与工具定义
首先,我们将现实世界的函数“降维”为 JSON Schema:
javascript
编辑
1import OpenAI from 'openai';
2import dotenv from 'dotenv';
3dotenv.config();
4
5// 初始化“缸中大脑”
6const client = new OpenAI({
7 apiKey: process.env.DEEPSEEK_API_KEY,
8 baseURL: process.env.DEEPSEEK_BASE_URL
9});
10
11// 【认知植入】将函数降维为语言描述
12const tools = [
13 {
14 type: "function",
15 function: {
16 name: "get_closing_price",
17 description: "获取指定股票的收盘价", // 描述越清晰,LLM 决策越准
18 parameters: {
19 type: "object",
20 properties: {
21 name: { type: "string", description: "股票名称" }
22 },
23 required: ["name"]
24 }
25 }
26 },
27 {
28 type: 'function',
29 function: {
30 name: 'get_weather',
31 description: '获取指定城市的天气',
32 parameters: {
33 type: 'object',
34 properties: {
35 city: { type: 'string', description: '城市名称' }
36 },
37 required: ['city']
38 }
39 }
40 }
41];
2. 传统软件世界的“手脚”
LLM 做不了的事,由我们的 Runtime 来做:
javascript
编辑
1// 模拟真实的业务逻辑
2function get_closing_price(name) {
3 const stockData = {
4 '青岛啤酒': '67.92',
5 '贵州茅台': '1488.21'
6 };
7 return stockData[name] || '未找到该股票';
8}
3. 核心交互循环(Agent Loop)
这是整篇文章最核心的部分。请注意观察消息列表 messages 是如何在 User、Assistant、Tool 三种角色间流转的:
javascript
编辑
1async function sendMessage(messages) {
2 return await client.chat.completions.create({
3 model: 'deepseek-v4-pro', // 或其他支持 tool use 的模型
4 messages,
5 tools,
6 tool_choice: 'auto'
7 });
8}
9
10async function main() {
11 // 1. 用户发起提问
12 let messages = [
13 { role: 'user', content: '青岛啤酒的收盘价是多少?' }
14 ];
15
16 // 2. 第一次调用:LLM 进行意图识别
17 const response = await sendMessage(messages);
18 const message = response.choices[0].message;
19
20 console.log('🤖 模型首次返回:', JSON.stringify(message));
21
22 // 将模型的决策加入上下文
23 messages.push({
24 role: message.role,
25 content: message.content,
26 tool_calls: message.tool_calls
27 });
28
29 // 3. Runtime 介入:判断是否需要执行工具
30 if (message.tool_calls) {
31 const toolCall = message.tool_calls[0];
32
33 if (toolCall.function.name === 'get_closing_price') {
34 // 解析 LLM 生成的参数
35 const args = JSON.parse(toolCall.function.arguments);
36
37 // 执行传统函数
38 const price = get_closing_price(args.name);
39 console.log(`📊 工具执行结果: ${price}`);
40
41 // ⚠️ 关键步骤:将工具结果反馈给 LLM,而不是直接给用户
42 messages.push({
43 role: 'tool', // 角色标识为 tool
44 content: price, // 工具返回的内容
45 tool_call_id: toolCall.id // 通过 ID 关联之前的调用请求
46 });
47
48 console.log('🔄 更新后的完整上下文:', messages);
49
50 // 4. 第二次调用:LLM 根据工具结果生成最终回复
51 const finalRes = await sendMessage(messages);
52 console.log('✅ 最终回复:', finalRes.choices[0].message.content);
53 }
54 }
55}
56
57main();
三、 总结:如何在脑海复现这节课?
当你下次再看到 AI 调用工具时,请在脑海中运行以下三个画面:
- 配置阶段:想象你在给一个绝顶聪明但被关在黑屋子里的人塞纸条(JSON Schema),告诉他“如果有事找外界,就按这个格式写纸条”。
- 决策阶段:用户提问后,这个人没有直接回答,而是写了一张符合格式的纸条(tool_calls)递出窗口,然后停下来等待。
- 执行与反馈阶段:你(Runtime)在窗外接过纸条,查完数据库后,把结果写在另一张纸条上递回去。这个人看到结果后,才开口对用户说出了最终答案。
Tool Use 不是什么魔法,它是概率模型与传统软件工程的一次伟大握手。 LLM 负责“想”和“说”,Runtime 负责“做”,两者通过标准化的语言协议(JSON)无缝衔接。
掌握了这个底层逻辑,你就掌握了构建 AI Agent 的钥匙。无论是操作电脑、分析表格还是自动化办公,万变不离其宗。
希望这篇文章能帮你彻底打通 Tool Use 的任督二脉。如果你觉得有收获,欢迎点赞收藏,我们下节课见!