现在最值钱的是什么?毫无疑问是 Agent(智能体) 。
随着 AI 的爆发,Agent 工程师正在刷新传统软件工程师的工资上限。无论是 Cursor、Claude Code,还是豆包、飞书 Cici,这些产品的核心都是 Agent。它们不仅能回答问题,还能读文件、搜网络、写代码、操作电脑。
一个 Agent 有多强,取决于三个核心要素:用了什么大脑(LLM)、装了什么工具(Tool)、拿到了什么信息。
今天,我们就来拆解 Agent 的底层逻辑,并用代码手把手实现一个能查股票的工具。
一、 LLM:被关在茧房里的天才大脑
LLM(大语言模型)是 Agent 的大脑。但必须记住一个核心真相:LLM 只负责“推理”和“生成”,它没有真正的行动能力。
它就像一个被关在信息茧房里的天才,虽然聪明,但无法直接感知外部世界。如果没有工具,AI 只能空想,无法完成自动化任务。
二、 Tool(工具):补齐操作短板
为了让天才走出茧房,我们需要给它递上工具。Tool 是连接 LLM 与外部世界的桥梁。
当用户问“青岛啤酒股价多少?”时,整个 Agent 的工作流是这样的:
- LLM 推理:要回答这个问题,需要调用获取股价的工具。
- LLM 发出指令:调用
get_closing_price函数,传入参数“青岛啤酒”。 - 本地执行:你的代码拿到指令,去查数据库或 API,返回结果“67.92”。
- LLM 总结:拿到结果后,LLM 将其整合成自然语言回复给用户。
这就是 LLM with Tools 的核心机制。
三、 代码实战:让 LLM 准确调用工具
下面我们用 JavaScript 写一个简单的 Agent。要让 LLM 准确使用工具,我们需要向它提供一份“标准说明书”(即 JSON Schema)。
1. 声明工具(Tools)
这是最关键的一步。我们要告诉 LLM:“你有这个工具可用,并且必须按这个格式传参。”
javascript
编辑
1const tools = [
2 {
3 type: 'function', // 告诉 LLM 这是一个函数工具
4 function: {
5 name: "get_closing_price",
6 // 核心:能不能准确使用 tool 的关键!
7 description: "获取指定股票的收盘价",
8 parameters: {
9 type: "object", // 必须是 object 类型
10 properties: {
11 name: {
12 type: "string",
13 // NLP 提示:告诉 LLM 这个参数具体代表什么
14 description: "股票名称,例如:青岛啤酒、贵州茅台"
15 }
16 },
17 required: ['name'] // 声明必填项,防止 LLM 漏传参数
18 }
19 }
20 }
21];
2. 实现具体函数逻辑
LLM 只负责“想”和“说”,真正的“做”要靠我们自己写代码。
javascript
编辑
1// 这里的逻辑可以替换为真实的股票 API 调用
2function get_closing_price(name) {
3 if (name === '青岛啤酒') return "67.92";
4 if (name === '贵州茅台') return "1488.21";
5 return "未找到该股票";
6}
3. 发送消息并处理响应
我们需要把用户的提问发给 LLM,并处理它可能返回的“工具调用”指令。
javascript
编辑
1const send_message = async (messages) => {
2 return await client.chat.completions.create({
3 model: 'deepseek-v4-flash',
4 messages: messages,
5 tools: tools,
6 tool_choice: 'auto', // 让 LLM 自动决定是否调用工具
7 });
8};
9
10const main = async () => {
11 let messages = [{ role: 'user', content: '青岛啤酒的收盘价是多少?' }];
12
13 const response = await send_message(messages);
14 const message = response.choices[0].message;
15
16 // 如果 LLM 决定调用工具
17 if (message.tool_calls) {
18 const tool_call = message.tool_calls[0];
19 const args = JSON.parse(tool_call.function.arguments);
20
21 // 1. 执行本地函数
22 const result = get_closing_price(args.name);
23
24 // 2. 把结果塞回对话历史(role 必须是 "tool")
25 messages.push({
26 role: "tool",
27 content: result,
28 tool_call_id: tool_call.id
29 });
30
31 // 3. 再次请求 LLM,让它基于结果生成自然语言回复
32 const final_response = await send_message(messages);
33 console.log(final_response.choices[0].message.content);
34 }
35};
36main();
四、 💡 新手必记:3 个避坑核心知识点
在上面的代码中,有几个概念是必须死记硬背的,它们决定了你的 Agent 会不会“变傻”:
-
description是 LLM 的“眼睛”name是给底层代码看的,而description是给 LLM 看的。- 如果
description写得太模糊(比如只写“获取数字”),LLM 可能会在你想查温度时也调用这个股票函数。描述越具体,调用越准确。
-
parameters和properties缺一不可- 这是 JSON Schema 的硬性规范。
parameters是信封,properties是里面的表格。 - 致命错误:很多新手会直接写
parameters: { name: { type: "string" } },漏掉了properties这一层。这样写 LLM 是看不懂的,必须严格遵循type: "object"+properties: { ... }的嵌套格式。
- 这是 JSON Schema 的硬性规范。
-
Tool Call 是“分步走”的
- LLM 不会直接给出最终答案,它只会给出“调用指令”。
- 你必须在代码里监听
tool_calls,提取参数,执行函数,再把结果塞回对话历史,然后再次请求 LLM,它才会把冰冷的数据转化为人类能看懂的语言。
掌握了这三个概念,你就掌握了 Agent 开发的底层逻辑。现在,你已经不是只会问问题的用户,而是一个能指挥 AI 干活的工程师了!
如果你觉得这篇文章对你有帮助,欢迎点赞、收藏,也欢迎在评论区交流你在开发 Agent 时遇到的坑!