Agent开发实战:给LLM配齐五件套,告别只会空谈的嘴炮大模型
文章目录
P.S. 无意间发现了一个巨牛的人工智能教程,非常通俗易懂,对AI感兴趣的朋友强烈推荐去看看,传送门https://blog.csdn.net/HHX_01
前言
读完这篇,你会明白为什么 Claude Code、Cursor、Manus 本质上干的是同一件事
💡 先讲个真事。上周我让 ChatGPT 帮我查一下公司上个季度的销售数据。它说:“根据我的知识,建议你去 CRM 系统里查一下。” 我说:“那你倒是查啊!” 它说:“抱歉,我没有访问权限。” 你看,这就是典型的"嘴炮王者"——知道一切,啥也干不了。就像一个考了 CPA 但连 Excel 都不会打开的人,理论满分,实操零分。我当场就想给它颁个"最佳建议奖",奖杯上刻四个字:“你行你上”。
后来我想明白了。
LLM 这玩意儿,本质上就是一个刚毕业的天才研究生。脑子好使,口若悬河,但你让它去打印个文件?不好意思,工牌没有,电脑没有,连公司 WiFi 密码都不知道。
💡 我打个比方。LLM 就像你朋友圈里那个"什么都懂"的朋友。你问他:“我电脑蓝屏了怎么办?” 他能从操作系统内核讲到内存管理,从驱动冲突分析到注册表修复,滔滔不绝讲了半小时。你问:“那你能帮我修一下吗?” 他说:“我不会啊,我只是理论比较扎实。” 这就是 LLM 的现状——知识渊博,动手能力为零。Agent 要做的,就是给这个"朋友圈懂王"配一台电脑、一个螺丝刀、一个维修手册,让他从"懂王"变成"修王"。
Agent 是干嘛的?就是给这个天才研究生配齐装备,让它从"实习生"转正为"正式员工"。
A g e n t = L L M + M e m o r y + T o o l + R A G + M C P + S k i l l s Agent = LLM + Memory + Tool + RAG + MCP + Skills Agent=LLM+Memory+Tool+RAG+MCP+Skills
Claude Code、Cursor、Manus 这些现在最值钱的 AI 产品,本质上干的都是同一件事——给 LLM 补装备。
💡 这就好比你去 4S 店买车。 salesman 跟你说:“先生,我们这辆车发动机是 LLM,但刹车、方向盘、轮胎、导航、座椅加热都是选装件。” 你说:“那裸车能开吗?” 他说:“能开,但只能直线加速,不能转弯,不能刹车,不能导航,座椅还是木板。” 你问:“那我要这些选装件多少钱?” 他说:“加在一起,就是 Agent。” 你看,Agent 不是换了一辆车,而是给同一辆车配齐了所有选装件。裸车是 LLM,配齐选装件就是 Agent。Claude Code 是顶配版,Cursor 是运动版,Manus 是豪华版——但发动机都是 LLM。
一、LLM 有五大"先天残疾",每个模块都是精准补丁
很多人以为 Agent 的模块是"越多越好"的堆料。错了。
这五个模块不是凑数的,每一个都精准对应 LLM 的一个天生缺陷。就像你近视配眼镜、腿骨折打石膏——哪里不行补哪里。
💡 我见过有人做 Agent,一上来就加了二十几个模块。我问他:“你加这么多干嘛?” 他说:“显得高级。” 我说:“你这就好比一个人感冒了,你给他同时吃感冒药、胃药、降压药、维生素、钙片、益生菌——药是挺多的,但只有感冒药对症,其他的都是心理安慰。Agent 的五个模块是精准的’对症下药’,不是’药越多越好’。”
| LLM 的缺陷 | 具体表现 | 为啥致命 | 补丁模块 |
|---|---|---|---|
| 无状态 | 上周聊的事,这周全忘。每次对话都是"初次见面,请多关照" | 没法积累上下文,永远从零开始,跟它处不出感情 | Memory |
| 无执行能力 | 能告诉你"应该怎么做",但自己不动手。就像健身教练只动嘴,自己不举铁 | 永远停留在"建议"层面,无法产生实际价值 | Tool |
| 无私有知识 | 训练数据里没有你公司的 API 文档、业务规范、代码库 | 通用能力强,一碰到具体业务就开始"编" | RAG |
| 知识有截止日期 | 预训练数据有 cutoff,不知道今天的新闻、实时股价、刚发布的库 | Chat 场景可以用搜索弥补,但 Agent 场景需要结构化数据 | MCP |
| 无法编排长任务 | 做 PPT、分析股市并自动买卖——单轮问答的粒度太粗 | 真实工作都是多步骤、多轮次的,它只会"一问一答" | Skills |
💡 这五个缺陷是"互斥且穷尽"的,用咨询行业的话说叫 MECE。记不住 → Memory;动不了 → Tool;不知道内部知识 → RAG;不知道新信息 → MCP;做不了长任务 → Skills。五个补丁,五个洞,不多不少,刚好够用。就像你买手机壳,摄像头、屏幕、充电口、音量键、电源键,每个孔位都精准对应,多一个孔是浪费,少一个孔是缺陷。我见过有人给 iPhone 套了个安卓手机壳,摄像头孔对不上,充电口对不上,还硬说"能用"。这就是模块不匹配的后果——看着像那么回事,实际用起来全是bug。
所以有个很强的推论:
如果你对面坐的是一个真正的 Agent,那么它背后一定以某种形式实现了这五个模块——缺少任何一个,它就会在对应的场景里"露馅"。
就像你面试一个人,他说自己是全栈工程师,但一问数据库就眼神闪躲——那肯定有问题。Agent 也一样,五个模块缺一不可。
💡 我举个例子。有个产品号称自己是 Agent,但一查发现没有 Memory。我问它:“我叫什么名字?” 它说:“我不知道。” 我说:“五分钟前我告诉过你。” 它说:“抱歉,我没有记忆功能。” 这就像一个服务员,你刚点了菜,五分钟后他问你要点什么——这不是服务员,这是金鱼。金鱼的记忆只有七秒,这个 Agent 的记忆是零秒。没有 Memory 的 Agent,就像没有记忆的金鱼,永远活在"第一次"的循环里。
二、零件配齐了,怎么组装?核心是 LLM 自己当调度中心
有了公式,只是知道了"要装什么零件"。
更关键的问题是:这些零件怎么配合?你总不能把发动机、轮胎、方向盘往地上一扔,说"这是一辆车"吧?
💡 我见过最离谱的 Agent 实现,是把五个模块各自独立运行,然后用一个 if-else 脚本硬拼接。用户说"查一下销售数据",脚本先查 Memory,再查 RAG,再调 Tool,再调 MCP,最后跑 Skills——不管用户需不需要,全部跑一遍。这就像你去餐厅点菜,服务员不管你要什么,先把菜单上所有菜都上一遍。你说"我就想吃个炒饭",他说"不行,我们流程是先上前菜、再喝汤、再吃主菜、再上甜点、最后上咖啡"。这哪是 Agent,这是流水线工厂。真正的 Agent 应该像一个好服务员,你点炒饭,他直接给你炒饭,不会顺便给你做个满汉全席。
2.1 整体工作流:LLM 自己当项目经理
Agent 的调度中心不是外部规则引擎,就是 LLM 自己。
整个流程大概是这样的:
- 用户扔过来一个复杂任务(Prompt)
- LLM 开始 Planning / Reasoning——拆解子任务
- LLM 自己判断:需要加载 Memory 吗?(历史上下文、用户偏好)
- LLM 自己判断:需要调用 Tool 吗?(可能多个,可能多轮)
- LLM 自己判断:需要走 RAG 吗?(检索内部知识,拼进 Prompt)
- 组装最终 Response,返回给用户
💡 注意啊,每一步"判断"都不是硬编码的 if-else,而是 LLM 基于任务内容自主做出的。这就好比你让一个人工智能去厨房做饭,它不是按死板的菜谱走,而是自己看冰箱里有什么、用户爱吃什么、今天心情如何,然后决定做什么菜。当然,如果 description 和 schema 写得像天书,那 LLM 的判断就会像喝了两瓶二锅头——随机且离谱。我见过有人写 schema 的时候,字段名叫 “a”、“b”、“c”,然后问 LLM 为什么传参总是错。我说:“你给你家狗起名叫’狗’,它都知道你在叫它;你给字段起名叫’a’,LLM 怎么知道这是文件路径还是用户ID?”
2.2 最核心的机制:Tool 调用的完整闭环
在所有模块中,Tool 是最关键的——因为它是 LLM 从"能说"变成"能做"的分水岭。
没有 Tool,LLM 就是一个"嘴强王者"。有了 Tool,它才能真的动手干活。
💡 Tool 对 LLM 的重要性,就像手对人类的重要性。没有手的 LLM,只能"动嘴";有了手的 LLM,才能"动手"。你可以想象一下,如果人类没有手,只有嘴,那我们能干什么?能说话、能吃饭、能唱歌——但没法打字、没法做饭、没法修东西。LLM 没有 Tool,就像人没有手,只能当"评论员",不能当"运动员"。评论员和运动员的区别是什么?评论员说"这个球应该传右边",运动员说"我这就传右边"——然后真的传了。Tool 就是把 LLM 从评论员变成运动员的那双手。
第一层:Tool 本身的结构
一个 Tool 由两个互不重叠的部分组成:
// Tool = 处理函数(干活的) + 描述对象(让 LLM 知道什么时候调的)
const readFileTool = tool(
// 第一层:处理函数(async,真正干活的)
async ({ filePath }) => {
const content = await fs.readFile(filePath, 'utf-8');
console.log(`[工具调用] read_file(${filePath}) 成功读取 ${content.length} 字节`);
return content;
},
// 第二层:描述对象(LLM 靠这个判断"调不调")
{
name: 'read_file',
description: '用此工具来读取文件内容。当用户要求读取文件、查看代码、分析文件内容时,调用此工具。',
schema: z.object({
filePath: z.string().describe('要读取的文件路径'),
}),
}
);
从这个结构可以直接推导出三条设计约束:
- 处理函数必须是 async:读文件、调 API、查数据库都是耗时操作,同步阻塞会让整个 Agent 卡死。就像你点外卖,不可能让厨师炒完一盘再炒下一盘,肯定是并行出餐。
- description 决定准确率:LLM 靠 description 判断调用时机,场景覆盖越全,误判越少。写得太模糊,LLM 就会像选择性失忆——该调的时候不调,不该调的时候乱调。
- schema 是调用契约:LLM 必须按 schema 约定的参数格式传参,zod 做校验。契约不清晰,调用必失败。就像你让快递员送货,地址写"那个小区",他肯定找不到。
💡 我见过有人写 Tool 的 description 就一句话:“这是一个文件工具。” 然后 LLM 每次调用都传错参数,报错信息堆成山。这就好比你给 GPS 输入"带我去个好地方"——它当然不知道你想去哪。描述写得越具体,LLM 越像老司机;描述写得越模糊,LLM 越像刚拿驾照的新手,上路就慌。我还见过更离谱的,description 写的是"此工具用于处理各种文件相关操作"。我问:“什么叫’各种’?” 他说:“就是所有跟文件有关的。” 我说:“那创建文件、删除文件、复制文件、移动文件、重命名文件、读取文件、写入文件、压缩文件、解压文件——这些算’各种’吗?” 他说:“算啊。” 我说:“那 LLM 怎么知道什么时候该调哪个?” 他沉默了。这就是典型的"描述模糊综合征",病状是 description 写得像哲学命题,LLM 调得像随机抽奖。
第二层:Tool 的调用流程——LLM 的"自知之明"
这是整个 Agent 机制中最精妙的一环。
LLM 具有"自知之明"——当它判断需要调用 Tool 时,它不会硬编答案,而是停下来,生成 tool_calls 列表,声明"我需要调这些工具"。
// 给模型绑定工具
const modelWithTools = model.bindTools(tools);
const messages = [
new SystemMessage('你是一个代码助手。用户要求读文件时立即调用 read_file,等待结果后分析代码。'),
new HumanMessage('请读取 tool.mjs 文件内容并解释代码'),
];
// 第一次 invoke:LLM 不生成文本,而是返回 tool_calls
let response = await modelWithTools.invoke(messages);
// response.tool_calls = [{ id, name: 'read_file', arguments: { filePath: 'tool.mjs' } }]
messages.push(response);
// 运行时执行 Tool,用 tool_call_id 把结果和调用一一对应
if (response.tool_calls && response.tool_calls.length > 0) {
for (const toolCall of response.tool_calls) {
const toolResult = await readFileTool.invoke(toolCall.args);
messages.push(new ToolMessage({
content: toolResult,
tool_call_id: toolCall.id, // ← 关键:id 是关联调用和结果的唯一标识
}));
}
// 第二次 invoke:LLM 拿到工具结果,生成基于结果的最终回复
const finalResponse = await modelWithTools.invoke(messages);
console.log('[最终回复]', finalResponse.content);
}
这个流程的关键点:
- 第一次 invoke:LLM 不输出文本,而是输出 tool_calls——这是它的"自知之明",承认自己不知道,需要查资料。
- 运行时执行:外部系统根据 tool_calls 执行实际的 Tool 函数,拿到结果。
- tool_call_id 关联:用 id 把调用和结果一一对应,防止 LLM 把"读 A 文件"的结果当成"读 B 文件"的结果——那就成张冠李戴了。
- 第二次 invoke:LLM 拿到真实结果,生成基于事实的最终回复,而不是瞎编。
💡 这个机制最妙的地方在于:LLM 知道自己不知道。它不会硬撑面子说"根据我的知识,tool.mjs 的内容是……“,而是老老实实说"我先查一下”。这就好比你去相亲,对方问你月薪多少,你说"我先查一下工资条"——诚实,但靠谱。相反,如果 LLM 不查直接编,那就是相亲时说"我月薪十万",结果一查是税前、含公积金、还加了年终奖平均——典型的"嘴炮翻车"。我见过最离谱的,LLM 没查文件直接编了一段代码,用户复制粘贴运行,报错满屏。用户问:“这代码怎么跑不通?” LLM 说:“抱歉,我编错了。” 你看,它自己都承认是"编"的。没有 Tool 调用闭环的 Agent,就像没有查重系统的论文——看着像那么回事,一查全是编的。
三、为什么这个公式足够?因为它覆盖了 LLM 从"聊天"到"干活"的全部缺口
很多人问:Agent 的模块会不会越来越多?以后是不是要加第六个、第七个?
我的看法是:这五个模块已经覆盖了 LLM 从"聊天"到"干活"的全部能力缺口。就像一辆汽车,发动机、变速箱、轮胎、方向盘、刹车,五个核心部件配齐了,就能上路。你再加个车载冰箱、座椅按摩,那是锦上添花,不是雪中送炭。
💡 当然,如果你非要给 Agent 加个"情感陪伴模块",让它在你加班到半夜时给你讲个笑话——那也不是不行。但那是增值功能,不是基础能力。就像 iPhone 的灵动岛,有它更好,没它也能打电话。五个核心模块是"打电话"的能力,其他都是"灵动岛"。我还见过有人想给 Agent 加"自我怀疑模块",让 LLM 在每次回答前都先质疑自己:“我说的对吗?要不要查一下?” 我说:“你这不叫自我怀疑,这叫强迫症。LLM 本来就有’自知之明’,不需要额外加个模块来怀疑自己。再说了,如果 LLM 每次回答前都要怀疑三分钟,那用户体验就像等外卖——饿死了还没送到。”
所以回到开头那个问题:为什么 Claude Code、Cursor、Manus 本质上干的是同一件事?
因为它们都在做同一件事——给 LLM 这个"天才研究生"配齐五件套,让它从"知道一切但啥也干不了",变成"知道该干啥、能动手干、记得你上次说啥、能查公司内部资料、还能自动完成复杂流程"的正式员工。
Agent 不是 LLM 的升级版,而是 LLM 的"补完计划"。 它补的不是智商,而是执行力、记忆力、知识面和任务编排能力。智商 LLM 已经有了,缺的是把智商转化成实际产出的桥梁。
💡 最后讲个段子收尾。有人说:“LLM 这么聪明,为啥还需要 Agent?” 我反问:“爱因斯坦这么聪明,为啥还需要实验室、助手、图书馆和经费?” 答案是一样的——脑子好使是一回事,把想法变成现实是另一回事。Agent 就是 LLM 的实验室、助手、图书馆和经费。没有这些,爱因斯坦也只能在纸上写公式;有了这些,他才能造出原子弹——当然,希望我们的 Agent 只用来写代码,不要用来造原子弹。我还想到一个更接地气的比喻:LLM 是厨子,Agent 是厨房。厨子再厉害,没有锅、没有刀、没有食材、没有灶台,也只能干瞪眼。Agent 就是给厨子配齐了整套厨房,让他从"会做菜"变成"能做菜"。 Claude Code 是米其林厨房,Cursor 是家庭厨房,Manus 是中央厨房——但厨子都是 LLM。
完。
P.S. 无意间发现了一个巨牛的人工智能教程,非常通俗易懂,对AI感兴趣的朋友强烈推荐去看看,传送门https://blog.csdn.net/HHX_01
更多推荐


所有评论(0)