ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

AI Agent架构拆解:大模型+记忆+RAG+工具调用的协同实战

AI Agent架构拆解:大模型+记忆+RAG+工具调用的协同实战 先抛个结论AI Agent 从来没有那么玄乎它本质上就是“大模型 记忆 RAG 工具调用”这四样东西按一定规则组合起来的执行系统。网上教程一抓一大把但大部分只教你调某个框架的API很少讲清楚这四块是怎么协同的、为什么非这么拼不可、以及真正跑起来之后哪些地方会踩坑。我这篇文章不打算贴一堆框架源码而是围绕 Agent 的架构逻辑把大模型、记忆、RAG、工具调用这四件事逐个拆开再用实际能落地的方案串起来。内容适合正在做 Agent 开发的工程师、想给现有业务接入私有知识库的产品技术负责人也适合那些被新概念绕晕、想建立起完整认知框架的学习者。我会把关键参数、计算思路、选择原因通通交代清楚尽量让读完的你能直接套用到自己的项目里。1. 一张图看懂 Agent 的整体循环1.1 所有 Agent 都在跑同一个循环哪怕换成不同的框架Agent 的内核基本都长这样用户输入 → 任务理解与拆解 → 决定下一步动作 → 执行动作思考 / 检索 / 调用工具 / 查询记忆→ 观察返回结果 → 继续决策 → 直到产出最终答案。这个循环图说出来简单但很多人看架构图时把注意力全放在了“大模型有多强”上忽略了循环本身的设计。一个 Agent 能不能干活不只看模型聪明程度更看循环里每一步是否衔接得顺畅。比如用户问“帮我把最近的线上错误日志总结一下”如果循环里没有“检索日志”这个动作模型再强也只能乱编。所以我画架构图时一定会把 Agent 描述成一个带反馈的闭环而不是一条直线。大模型是闭环里的“决策器”它每次只决定“下一步该干什么”记忆是“档案室”负责把历史信息和偏好保存下来RAG 是“外部书籍”随时把领域知识调出来给模型参考工具调用则是“手脚”让模型真正操作外部系统。1.2 哪些环节决定 Agent 好不好用在实际开发中我认为有三个环节最容易决定 Agent 的体验上限。第一是意图理解与任务拆解。用户一句话进来模型能不能准确判断这是简单问答、需要多步推理、还是必须调外部接口。这一步做不好后面全白搭。第二是上下文组织。每次把哪些历史消息、哪些检索结果、哪些工具返回内容拼进提示词拼错了顺序或塞太多噪声结果会立刻变差。第三是终止条件控制。什么时候该停止调用工具、什么时候该直接回答这个判断经常被忽略但恰恰是 Agent 稳住不跑偏的关键。这里有个挺常见的误解很多人以为 Agent 的所有能力都来自“模型推理”其实推理只是骨架真正让 Agent 适配具体业务的往往是记忆、RAG、工具调用这周围的“辅助模块”。所以架构图里必须把这几块画进去并且明确它们和核心模型之间的数据流向。1.3 图解架构时最容易忽略的“隐藏层”我见过不少漂亮的架构图模型、向量库、工具节点都画得很完整但缺了两样很容易被忽略的东西上下文管理中间层和可观测性组件。上下文管理中间层负责做历史消息截断、摘要压缩、检索结果的重排和评分。不画这一层图上几个模块看起来都在实际跑起来却会碰到“模型上下文塞满”“检索片段互相矛盾”这种问题。可观测性组件则是记录每一次决策日志和工具返回值的地方没有它Agent 出错时你根本不知道它是哪一步决策错了排查起来等于盲人摸象。我在自己的项目里习惯把这两层在架构图里用独立模块标注出来。这样既方便自己和团队理解也方便后续做性能定位。2. 大模型这颗“大脑”怎么选、怎么放2.1 API 调用和本地部署的取舍大模型在 Agent 里的角色是核心推理引擎选型第一件事是决定用云端 API 还是本地部署。这两条路没有绝对好坏只看你的使用场景。云端 API 的优势是省事、模型能力强、推理速度有保障特别适合需要复杂推理、代码生成、多语言理解的任务。劣势也很明显数据要经过第三方接口私有化要求高的业务会直接排除另外如果调用量特别大成本会线性上涨。本地部署则相反数据完全留存在自己的服务器上适合处理敏感数据的企业。而且现在开源模型的能力已经相当能打像 Qwen 系列、Llama 系列在不少任务上已经接近甚至持平前两年的商用闭源模型。但本地部署的隐形成本一点都不低GPU 采购、运维、推理优化都要有人扛。我个人的选型标准是核心链路用成熟闭源 API 保效果涉及私有数据或成本敏感的辅助链路用本地小模型。不要幻想一套方案通吃所有场景Agent 架构里本来就可以混用多个模型。2.2 本地跑模型的具体参数怎么算本地部署最常碰到的问题就是“我的显卡到底带不带得动”这里有一个很简单的估算公式模型显存占用 ≈ 参数量 × 每个参数占用的字节数。以 7B 模型为例FP16 精度下每个参数占 2 字节那最低显存理论值就是 14GB加上推理时的 KV Cache 和其他开销实际建议至少留出 20GB 以上。如果换成 4-bit 量化每个参数大约占 0.5 字节理论值降到 3.5GB 左右实际 6GB 显存的消费级显卡也能跑一跑。这几年我玩得比较顺手的组合是 llama.cpp 配 GGUF 量化模型优点是单机就能部署、依赖少、还能在 CPU 上跑小模型。需要注意一点本地模型对工具调用的原生支持不一定好有些模型需要你在提示词里把工具列表和输出格式写得很细甚至要用特定的模板约束输出。后面第 5 节我会单独讲工具调用。2.3 微调什么时候才该上很多人一上来就问“我要不要微调模型”我的建议是先别。微调的本意是让模型适应特定领域的表达风格、输出格式或私有术语它解决的是“模型不会说人话”的问题。但如果你的业务知识是结构化、事实性的比如产品文档、售后手册RAG 往往比微调更划算因为知识更新只需要换知识库不用重新训练。真正适合微调的场景是模型输出风格或结构需要严格统一的时候。举个例子你要让模型把用户问题转换成内部数据库查询语句RAG 帮不上忙这时候用几百到几千条高质量样本微调一个小模型效果会非常明显。注意控制成本微调不是越多的数据越好样本质量远比数量重要。2.4 上下文长度不是越大越好现在模型动辄支持 128K、200K 上下文听起来很美好但千万不要因此就不管上下文组织了。长上下文有两个隐患一是计算成本和非注意力机制都呈超线性上升二是模型在超长上下文里对中部信息的注意力会明显下降这就是所谓“lost in the middle”问题。所以我的习惯是上下文窗口再大也要做内容的优先级排序。核心指令放最前历史记忆做摘要压缩RAG 检索结果按相关度截断工具返回内容去掉无用字段。这就像整理行李箱箱子再大也要把常用物品放在好拿的位置。3. 记忆机制短期、长期与共享3.1 短期记忆会话窗口管理短期记忆在 Agent 里最直接的体现就是“当前对话的历史消息”通常以消息列表的形式拼进模型输入。实现不难但管理起来有讲究。一个常见实现是维护一个会话窗口比如最近 20 轮对话超过之后就整体丢弃。更讲究一点的做法是把旧对话先让模型生成一段摘要再塞进新上下文这样既保留了关键事实又不会让消息列表无限膨胀。这个方案比简单截断好得多因为它能跨轮次保留重要信息。强调一下短期记忆存储的位置一般是内存或 Redis速度快、生命周期短和后面说的长期记忆有本质区别。3.2 长期记忆向量库与双网络模型落地长期记忆解决的是“Agent 要记住跨会话的信息”比如用户偏好、项目背景、历史结论。技术上有两类实现第一类是用向量库做语义检索把重要信息切片后 embedding 存进去下次来了新问题先做相似度检索第二类是用结构化存储例如用 PostgreSQL 或 Redis 存用户特征和偏好标签。更高级的做法是“双网络记忆模型”简单来说就是把记忆分成两层网络来管理。第一层是核心事实网络存的是经过验证、不容易变化的稳定事实第二层是情境网络存的是短期相关、上下文敏感的临时信息。查询时先走核心网络拿稳定事实再结合情境网络补当前上下文线索。我理解这本质上是对记忆做分层路由能显著减少不相关信息的干扰。说实话大多数人刚开始做 Agent 记忆用不上这么复杂直接用 Redis 存最近状态 向量库做长期检索已经能覆盖 80% 的需求。但理解双网络思路有助于你后期做记忆架构的优化。3.3 多 Agent 共享记忆怎么做多 Agent 协作已经不算新鲜事共享记忆是其中一个非常实际的需求。最简单的实现是多个 Agent 共同访问同一个向量库命名空间通过 collection/namespace 区分不同 Agent 或者不同项目的数据。但直接把所有 Agent 的写入口开在一起很快就会乱套。我建议在写入侧做一道“记忆评估”流程Agent 想把一段信息写进共享记忆前先让另一个评分器模型判断它是否有长期保存价值、是否与已有记忆重复、是否涉及敏感信息。想实现得更稳可以在写入时附带来源 Agent、时间戳、置信度等元数据方便之后溯源。3.4 记忆模块的常见坑数据污染和过期召回记忆模块如果只做加法不做减法最终会把整个系统拖垮。我在项目中遇到过两个比较典型的问题。一是数据污染。某个 Agent 从一次失败的对话里提取了错误结论写进了共享记忆之后所有 Agent 都基于这个错误结论做决策。要解决这个问题记忆写入必须有准入机制不能谁说什么都记下来。二是过期召回。业务变化之后旧知识可能完全失效但向量搜索依然会把过期的内容高相关度地检索出来。我就出现过知识库里的旧版 API 接口文档和最新版本冲突Agent 选择了旧接口导致调用失败的情况。后来我专门加了一个“最后一次更新时间”过滤字段检索时强制要求只返回近 N 天内的内容才把这个坑填上。把记忆当成一个独立的、需要治理的数据系统来看待它才不会成为 Agent 的短板。4. RAG 知识库从普通 RAG 到 Agentic RAG4.1 构建知识库的完整流程RAG 的核心价值是让模型在不重新训练的情况下获取动态、私有的领域知识。完成一个可用的 RAG 知识库大致要经过下面这几步第一步准备文档先把 PDF、Word、HTML、Markdown 等格式统一清洗成纯文本。第二步分块Chunking把长文本切成一个一个语义完整的片段。第三步向量化把每个片段用 embedding 模型转成向量。第四步入库把向量和原始文本一起存进向量数据库。第五步检索增强在 Agent 回答问题时先用问题向量去库里检索 Top K再把结果拼进提示词。第六步质量评估持续检验检索和回答效果并迭代。整个流程里分块和检索阈值的选择是最耗精力的。分块大小建议按内容类型来定。纯描述性文档可以用大块比如 800 到 1000 字粒度更接近完整语义操作性步骤、FAQ 类型建议用小一点的块比如 300 到 500 字防止一块里混杂多个主题。同时建议分块时做过度重叠也就是下一块从上一块结尾往前重叠一小段避免关键信息刚好被拦腰截断。检索阶段有两个参数需要反复调试。一个是 Top K也就是取回多少个候选片段设置太小会漏设置太大会把噪声引进来另一个是相似度得分阈值低于阈值的片段直接丢弃这个阈值不能拍脑袋定要拿历史真实问题做测试慢慢找平衡点。4.2 RAG 评估指标怎么理解最近老有人问我“RAG 知识库到底用什么指标衡量好坏”我统一说下我的理解。先看检索侧最常用的是召回率RecallK意思是正确答案被检索出来的比例。比如知识库里明明有 10 条相关内容检索返回了 8 条那召回率就是 80%。另一个是命中率Hit Rate只有当这 K 个结果里至少出现一条正确内容就算命中单位是“问题级别的成功率”比 Recall 粗一些。还有 MRRMean Reciprocal Rank它会看重正确结果的排位如果正确答案排得越靠前MRR 越高这个指标对“返回 Top K 给模型看”有比较强的指导意义。再看生成侧最有名的是忠实度Faithfulness也就是模型生成内容有没有忠实基于检索到的材料模型有没有开始自己编这个指标在 RAG 场景里格外重要。还有答案正确率这个一般靠人工评测或者用大模型裁判来打分。我建议 RAG 项目上线前至少把这些指标跑一遍形成基线。没有基线你后面改分块参数、换 embedding 模型时根本不知道是变好了还是变坏了。4.3 从固定检索到 Agentic RAG普通 RAG 的逻辑是“用户问题来了 → 固定地从知识库里检索 → 拼装回答”。这在问题比较标准化的场景下没问题但一旦遇到跨领域复杂问题固定检索就不够灵活了。这时候就需要 Agentic RAG。Agentic RAG 的特征是检索过程本身由 Agent 来动态决策。它不再局限于一个预设的向量库检索动作而是可以自己决定先查哪个知识库、要不要做多次检索、先查文档再查表格、要不要调用搜索工具获取外部信息。Agent 还能把一次检索结果当作新的输入继续追问等行为。本质上它是把“检索”从固定步骤升级成可规划的工具和工具调用天然结合在一起。举个例子用户问“上个月的线上故障率趋势以及和哪个版本发布有关”Agent 会先把问题拆成“查故障率统计”和“查版本发布记录”两个子任务再分别去数据表和发布文档两个知识库检索最后综合回答。这就是 Agentic RAG 的威力。4.4 RAG 和模型自身记忆的边界有一次我同事问我“既然模型自己也有知识为什么非要建 RAG”这问题其实问到了模式边界。模型自身记忆是训练时固化下来的有截止日期遇见新知识它就不知道而 RAG 属于运行时动态补充的知识可以做到实时更新。正确姿势是把两者当作互补关系模型自身记忆负责通用推理、常识和语言能力RAG 负责提供业务事实。当用户问的问题涉及已有知识时优先让模型调用常识回答一旦判定问题与内部文档、私有数据相关就去走 RAG 检索。不要把检索结果盲目地每轮都硬塞给模型那样只会无谓地增加成本、拉低响应速度。加一个“是否走 RAG”的判断节点会让整个架构轻量很多。5. 工具调用Agent 的手脚与跟外界握手的方式5.1 Tool / Function Calling 机制拆解工具调用属于 Agent 的“行动层”它让模型不再仅仅输出文字而是输出一个“我要调用某个函数”的结构化指令。以 OpenAI 的 Function Calling 为例流程是把函数名、参数说明、函数描述以 JSON Schema 形式传给模型模型根据用户请求返回“应该调用什么函数、传什么参数”程序再去执行实际函数把返回值再交给模型模型最终生成自然语言回复。这里有个比较关键的认知模型本身并不执行工具它只做“决策”——决定该调哪个工具、参数是什么。真正的执行是由应用代码完成的。这层解耦非常重要它让工具可以无限扩展而模型只需要理解工具的描述。所以工具描述写得清不清楚直接决定了模型会不会用错。务必在函数描述里写清楚“这个工具是干什么的、什么时候该用、什么时候不该用、参数有哪些限制条件”。5.2 本地模型的工具调用配置如果你用的是本地模型比如通过 llama.cpp 部署 GGUF 格式的开源模型工具调用能力不是天然就有的需要做适配。llama.cpp 本身支持对输出做一定程度的结构化约束你可以通过 grammar 或者预定义的 JSON 格式限制模型输出。实操中的一个可行路径是在提示词里把所有可用工具都列出来让模型必须输出一个 JSON 字符串字段包含 tool_name 和 parameters然后用 llama.cpp 的 JSON schema 约束来保证模型输出的是合法 JSON。我在 Qwen 系列的 7B 模型上试过这个方案正确率还可以但比 GPT-4 级别的闭源模型要低不少尤其当工具数量超过 5 个时模型偶尔会把参数名字编错。降低这种错误率有两个野路子把工具名称设计成语义化更强的单词以及在示例里给出两个完整的调用例子。如果你的核心链路非常依赖工具调用准确性请优先考虑闭源 API或者选专门优化过工具调用能力的开源模型或微调模型再搭配本地部署。不要为了省钱牺牲主链路效果。5.3 实战案例通过 ES Rest API 让 Agent 分析日志我拿一个自己做过的例子来演示工具调用如何落地。当时业务方要求“让 Agent 能够分析 ELK 里的错误日志”我不需要把日志数据搬进向量库只让 Agent 通过 Elasticsearch 的 Rest API 查询日志。我定义了这样一个工具search_logs(index, query, time_range, size)其中 index 指定日志索引query 是 ES Query DSLtime_range 是时间范围size 是返回条数。然后把工具的 schema 传给 Agent。当用户问“今天早上 9 点到现在 Nginx 的 5xx 错误有多少”Agent 会自动把问题转成 search_logs 参数去 ES 查询拿回结果后再组织语言做总结。这套方案里还有一个很实用的组合让 Agent 先跑一次 count 统计总数再跑一次聚合查 Top 错误分布最后再写一小段总结。这其实已经把“工具调用 计划能力”串起来了。落地时提醒一句ES 查询语句里有大量嵌套结构工具描述里一定要给 model 一个最小可用的 Query DSL 模板否则它容易产出非法查询。5.4 工具调用设计的原则和防呆工具设计得不好Agent 再聪明也白搭。我总结出几条很基础但要牢记的原则。第一工具职责要单一。一个工具只做一件事让“查询日志”和“发送邮件”分开不要让模型在一堆混合工具里纠结。第二参数要尽量少。能传 3 个参数就不要设计 8 个参数越多模型越容易出错。第三要有明确的返回结构。返回给模型的数据要简洁去掉无关字段否则模型解读时容易犯迷糊。第四所有外部操作类工具必须加确认机制。比如“发送邮件”“删除数据”“执行订单操作”这类有副作用的调用不能直接执行建议在代码层加一个人工确认或者环境标记防止 Agent 一条命令把生产库给改了。真出过事我见过 Agent 把测试环境的数据批量删除接口当成清库工具调用了还好当时在工具层加了 yaml 配置的 allowlist只允许执行只读操作才没酿成大祸。工具层一定要舍得加防护。6. 评估与调试Agent 不是跑通就完事6.1 为什么普通单元测试不够Agent 的最大特点是“非确定性”同一个问题每次跑出来的中间路径可能都不一样。传统单元测试断言特定输入一定返回特定输出在 Agent 场景里很难成立。但这不代表不用测试而是要换一套思路。我建议把 Agent 测试分成三个层级。第一层是模块级测试对单个工具、单个 RAG 检索函数做确定性断言保证输入输出符合预期。第二层是场景级测试设计用户常见问题的标准测试集用 Agent 跑完整流程重点看“是否成功到达终点”“过程中是否调用了正确工具”。第三层是结果级评估对最终输出做人工评分或者用大模型裁判打分评估答案的准确性、完整性和忠实度。测试集来源很关键。不要只拿网上找的通用问题一定要把你线上真实用户的问题脱敏后做成测试集。真实问题才能暴露 Agent 在边界情况下的问题。6.2 从指标到评测集第三方评测工具怎么选现在市面上已经有不少第三方评测工具帮你管理测试集、跑批量评测、输出对比报告。我了解到的有 LangSmith、Langfuse、OpenAI Evals、TruLens 等它们各有侧重。LangSmith 和 Langfuse 偏 LLM 应用的可观测性能记录每一次 trace对定位错误很有帮助。OpenAI Evals 是开源评测框架适合自定义评测逻辑。TruLens 更偏 RAG 质量评估忠实度、上下文相关性这些指标开箱即用。如果你刚起步不需要全家桶先选一个能记录 trace 的工具再配套跑人工标注的评测集就已经非常能打了。评测指标至少要盯住这五个任务完成率、工具调用成功率、平均回答准确率、单次任务延迟、单次任务成本。前两个好理解延迟和成本很多团队上线之后才发现失控最好在设计阶段就制定好预算上限。6.3 结构化复盘把失败 case 沉淀回知识库Agent 评估做完最重要的动作是复盘。每次评测失败我都会把失败案例沉淀下来分成三类一类是工具描述不清晰导致模型理解错那就改工具描述另一类是知识库里缺少内容或内容碎片化那就补知识库并优化分块还有一类是任务本身超出 Agent 当前能力那就必须在架构上增加新的工具或新的处理路径。沉淀回知识库的意思是把每个失败 case 的诊断结论、修正动作和验证结果记录到一张评估清单里下次再评测时直接看这些历史 case 有没有改善。这本质上是在给 Agent 项目做持续集成长期价值远大于一次性优化。7. 常见问题与排错速查表7.1 高频故障与排查思路我把实际项目中遇到过的 Agent 典型问题整理成了一张速查表方便你遇到问题时直接定位现象可能原因排查思路模型不调用工具总是自己硬答工具描述不清、模型版本不支持、代码里没传工具列表先查请求 payload 里有没有带 tools简化工具描述并加示例换更强模型工具参数传错schema 描述不准确、没有给示例、模型本身工具能力弱给每个参数加描述和枚举值示例中补充完整调用片段考虑换工具能力更强的模型历史会话一长回答开始乱七八糟上下文溢出、中间信息被忽略对历史消息做摘要压缩只保留最近 N 轮全量文本RAG 检索出来一堆无关内容分块太大、Top K 太大、embedding 模型不匹配缩小分块尺寸降低 Top K重跑评测看指标对比Agent 陷入工具调用死循环缺少终止条件、工具返回无法验证增加最大轮数上限检查返回结构是否可解析让模型输出一个带“判断完成位”的表单共享记忆被写入错误信息缺写入准入和更新机制加记忆写入评分加来源字段建置信度分级7.2 一些我踩过的坑这里挑几个最典型的展开说说。第一个坑是本地部署模型时只看显存理论值忽略了推理吞吐。当时我部署了一个 13B 模型显存勉强够但推理速度慢到用户等不起整个 Agent 体验彻底崩了。后来换成了 7B 量化模型牺牲一点效果换回来能被接受的响应速度。第二个坑是 RAG 检索结果不做去重和重排。有些知识库里有多个不同文档的相似内容简单向量检索把两份高度重叠的片段都拿回来导致模型回答里出现大量重复表述。加了重排Rerank模型之后这个问题明显改善。第三个坑是评估结果不固定导致的误判。同一批测试集前一天跑完成率 80%第二天跑了 70%一度让我以为 Agent 退化了后来发现是评测环境里原模型灰度上线了一个新版本。后来我强制锁定了评测环境的模型版本所有对比才变得有意义。7.3 排错时的黄金日志策略Agent 排错本质上是一个追踪问题。代码逻辑出错靠堆栈Agent 决策出错只能靠日志。我的黄金日志策略很简单在 Agent 循环的每个关键节点都打印结构化日志包含四个字段步骤 ID、动作类型thinking / tool_call / memory_query / rag_retrieve、输入摘要、输出摘要。工具调用日志要额外记录函数名、参数 JSON、返回值长度和状态码。RAG 检索日志要记录检索 query、候选数量、拉了多少条。记忆写入日志要记录写入内容摘要、来源 Agent、评分结果。有了这套日志当 Agent 出错时你能快速回放它的每一步决策看到底是哪一步开始跑偏的。日志格式保持 JSON Lines每行一个事件后续可以接入 Elasticsearch 或任何日志平台。最后分享一个我自己长期坚持的实操习惯每次接到 Agent 项目需求我会先用一张白纸把“输入 → 判断 → 工具 → 记忆 → 输出”这个闭环画出来再标注每步用到的模型、数据存储和备选方案。画完这张图整体架构基本就清晰了一大半后面写代码只是机械地填坑而已。你如果能亲手画一遍可能比看我写十篇文章更有用。
返回列表