上个月帮朋友排查一个 Agent 项目现象很典型对话到第十几轮模型开始失忆前面确认过的用户偏好、刚算完的中间结果全被它丢得干干净净。加长上下文窗口换了 200K 的模型成本直接翻倍该忘的还是忘。后来我给他补了一套记忆分层 MCP 工具的方案问题才算真正解决。其实这段时间只要在搞 Agent几乎都绕不开两件事记忆和工具。记忆决定了 Agent 能不能跨轮次、跨会话地用得上历史信息工具决定了 Agent 能不能从只会生成文本进化成真的能干活。而这两条线最终会在同一个话题上汇合——MCPModel Context Protocol。这篇就顺着上下文窗口这个起点把 Agent 记忆体系的搭建思路、工具接入方案以及我踩过的坑完整梳理一遍。内容偏实战适合已经在写 Agent、但觉得只靠提示词堆功能越来越别扭的开发者。1. 先想清楚一件事Agent 要记住什么我见过不少团队上来就奔着记忆功能做开发结果做完了发现用户根本不买账。不是技术不行而是没想明白Agent 需要的记忆和聊天记录根本不是一回事。1.1 Agent 记忆不是聊天记录聊天记录是我说了什么、你回了什么的原始流水账。而 Agent 的记忆是它为了完成任务需要长期保存和随时调用的信息状态。举个例子你让 Agent 帮你整理一份行业调研报告它需要记住你的目标读者是谁、你偏好的报告结构、上一步检索到的关键数据出处、还没完成的子任务清单。这些信息一部分来自对话但更重要的部分来自任务本身的结构。如果只是把聊天记录堆进上下文模型很快就会被无关噪声淹没——这就是为什么很多人没有上下文窗口写爆了Agent 反而开始表现得像个傻子。我在实际项目里的判断标准很简单凡是这次对话结束以后还要用的信息就该进记忆系统凡是只在这一轮推理里用一下的信息留在上下文窗口就够了。这个区分听起来容易做起来需要刻意设计因为你得先给 Agent 定义清楚哪些是短期状态当前任务的临时变量哪些是长期事实用户画像、知识沉淀、历史决策。1.2 按生命周期拆解记忆的类型记忆系统设计我习惯按生命周期拆成四层工作记忆Working Memory相当于 Agent 当前任务里的草稿纸。包含当前的子任务目标、已经拿到的中间结果、接下来几步的计划。它不需要跨会话保留但必须在一次任务执行过程中随时可读可改。情景记忆Episodic Memory记录过去发生过什么。比如用户上次要求 Agent 用表格形式输出Agent 上次在某个 API 调用上失败了用户对某个回答明确表达过不满。情景记忆让 Agent 能基于历史经验调整行为。语义记忆Semantic Memory沉淀用户是谁、世界是什么样的稳定知识。比如用户的工作领域、常用术语偏好、项目背景资料、经过验证的行业知识。这类信息变化频率低价值密度高。程序记忆Procedural Memory记住某类任务应该怎么做。比如 Agent 总结出的处理客服工单必须先查知识库再回复生成周报时要先汇总数据源再动笔这类流程经验。程序记忆做得好Agent 才能真正越用越顺手。这个分层思路借鉴了认知科学里对人类记忆的分类方式用到 Agent 上非常好理解。后面我讲的实现方案本质上就是给这四类记忆分别找合适的存储介质和管理策略。1.3 记忆缺失到底会造成什么后果没有记忆系统的 Agent最直观的问题就是反复问已经问过的问题。用户第一轮明确说我只要结论不要过程第二轮 Agent 又给了一长篇推理过程。用户觉得它蠢其实不是模型能力不行是上下文里那个偏好指令早就被任务噪声挤掉了。更隐蔽的问题是身份一致性崩塌。一个销售场景的 Agent用户上周已经确认了公司名称、产品线、目标客户画像这周再来Agent 完全不记得上来重新问一遍用户信任感瞬间归零。这在 ToB 场景几乎是灾难级别的体验。还有一类问题容易被忽略记忆缺失会推高 Token 成本。没有外部记忆时为了防止遗忘开发者只能把历史消息一股脑塞进上下文窗口越用越满API 费用随之暴涨响应延迟也在增加。而设计良好的记忆系统,只需要把其中高价值的部分提取出来保存重建上下文时按需注入成本和效果都能兼顾。所以做 Agent 第一件需要达成的共识就是记忆不是聊天记录的备份而是和模型能力、工具能力并行的第三根支柱。2. 上下文窗口一切记忆的起点也是最大的瓶颈记忆系统再复杂它服务的第一现场永远是上下文窗口。所以想要理解 Agent 记忆必须先弄明白上下文窗口是怎么工作的它为什么会不够用。2.1 窗口的本质是临时货架用一个超市的类比上下文窗口就是模型工作台上的临时货架。货架大小是有限的比如 128K token模型每次推理时能看到的只有货架上的东西。对话历史、系统提示词、工具返回结果、检索出的参考文档全部要摆到这个货架上货架满了新的放上去旧的就只能被挤下去。这个比喻能解释很多现象为什么 Agent 聊着聊着就忘了最早的需求不是模型故意忘而是那些早期内容在超长对话中物理上被挤出了窗口。为什么给 Agent 塞一大堆文档它反而表现变差因为货架被无关文档占据真正关键的指令放不进去了。大模型的注意力机制决定了它对窗口内不同位置的关注度并不均匀——通常是开头和结尾的内容更容易被记住中间部分容易迷失。这也是为什么不让 Agent 处理超长文档时你要把结论放在最前面细节往后放。2.2 窗口用完了到底会发生什么上下文窗口用完不同的模型和框架表现不一样但本质上无非三种结果第一种静默遗忘。框架按顺序截断最旧的消息但模型不会告诉你我把前面的内容忘了。它还在继续回答只是回答质量肉眼可见地下降因为你在第一轮设定的任务目标、用户偏好早就被截掉了。第二种显式报错。超出模型允许的最大上下文长度API 直接返回 429 或 context_length_exceeded 错误,整轮任务直接中断。这种情况在自动化流程里会让 Agent 丢失整个会话状态重跑的成本很高。第三种质量和延迟同步恶化。即便没到硬上限随着窗口占用量增加模型每次推理要处理的 token 数变大响应延迟变高输出质量也会有波动而费用还在直线上升。很多 Agent 项目优化到后期瓶颈根本不是模型能力而是每次请求都在给整个聊天历史付钱。2.3 窗口用完了常用的四种处理策略既然窗口会满就得有策略。我实际用下来比较成熟的方案有四种策略一截断Truncation。最粗暴也最不安全。直接把最老的消息删除保留下文。优点是实现简单、几乎不消耗额外时间缺点是可能丢掉任务初期定义的关键目标和约束。这个方案只适合任务极短、历史无关紧要的场景。策略二摘要Summarization。窗口快满时让模型把早期对话压缩成一段结构化摘要替代原始消息注入上下文。这是目前用得最多的方案但要注意两个坑一是摘要本身要花钱花时间高频触发时成本反而更高二是摘要会丢失细节比如数字、名字、精确参数所以关键数据不能只靠摘要还要有外部存储兜底。策略三关键信息抽取Key Information Extraction。不是所有历史都需要被完整保留。实际做法是定期从对话里抽取用户偏好、任务目标、已完成步骤、未完成事项形成结构化的记忆条目写入外部存储。下次对话时直接注入这些结构化信息而不是把整段历史都带进去。这个思路正是从上下文管理走向记忆系统的分水岭。策略四外部化 按需检索Externalization Retrieval。把任何可能用到的知识、历史、事实放到外部向量库或数据库中构建上下文时只把和当前任务相关的片段检索出来。这个策略配合向量检索是解决长时记忆的主流方案。实测下来摘要和检索不是互斥的生产环境经常是摘要打底、检索补细节的组合。2.4 上下文工程里的几个关键参数做上下文管理有几个参数是需要认真调的保留窗口Keep Window始终保留在上下文里的系统消息、用户核心指令、安全约束。这部分不被截断建议控制在 2000~4000 token 以内。摘要触发阈值Summarize Threshold当上下文占用超过总窗口的 70%~80% 时触发摘要或压缩。设得太早压缩频繁浪费成本设得太晚容易爆窗。最大回答 Token 数Max Tokens给生成输出预留空间同时防止模型一次输出失控。一般至少留出总窗口的 20%~30% 给回答。在真实项目里我会再加一条经验所有框架级别的上下文策略都必须跑在可观测的基础上。每次请求前记录上下文占用、截断了什么、摘要了什么、检索出什么否则系统出问题时你根本不知道是哪一环把关键信息丢了。3. 把记忆搬出上下文向量检索与长短期记忆设计上下文窗口再大也是有限的而记忆应该是大得接近无限的。所以真正可靠的 Agent 记忆系统核心思路只有一个把记忆从上下文窗口里搬出去存进外部存储需要时再捞回来。3.1 为什么要把记忆写进仓库而不是塞进口袋试想一下你的手机通讯录如果只能记住当前屏幕上显示的那几行联系人那它就不是通讯录而是最近通话记录。上下文窗口就是那个最近通话记录它只能装当前正在处理的信息。而记忆系统要做的是通讯录——把联系人固化下来你想找谁的时候能精准搜到。把记忆外部化之后获得的最大收益是上下文窗口的释放模型每次只处理当前任务相关的记忆片段而不是全部历史这让它可以专注于真正重要的信息。同时外部存储意味着记忆可以跨会话、跨设备、甚至跨不同的 Agent 实例共享——这正好对应了很多人关心的换账号/换电脑后记忆怎么迁移的问题答案是记忆只要在外部迁移就只是搬存储的问题。3.2 向量检索把记忆变成可模糊匹配的索引外部存储不等于直接堆数据库。你面对的历史信息是自然语言自然语言没有固定的 Schema你不能指望用 SQL 精确匹配用户上次对什么不满。所以现在主流方案是用嵌入Embedding向量给记忆建索引。嵌入向量本质上是一个把文本映射到高维空间的坐标。语义相近的文本在向量空间里的距离也近。比如用户说报价太贵和价格不合预期虽然是不同的话但向量距离很近。检索时把你当前的问题也转成向量然后在库里找最近的几条记忆——这就实现了模糊语义匹配。具体选型上我常用这么几类存储方案特点适用场景Chroma / FAISS轻量、本地部署方便、嵌入快单机项目、原型验证Qdrant / Milvus支持分布式、过滤条件丰富、并发高生产环境、大规模记忆库pgvector直接挂在 PostgreSQL 上事务和检索一体已有数据库体系、需要强一致性的场景Redis 向量模块低延迟、适合热数据需要快速读写短期记忆的场景嵌入模型的选择也有讲究。通用场景我倾向于用 bge / m3e 这类中文友好的模型如果记忆内容偏代码或技术文档OpenAI 的 text-embedding-3-small 或者 Cohere embed 也不错。有一个容易被忽略的点嵌入模型和主模型可以不同但嵌入模型一旦上线尽量不要换否则之前写入的向量全都要重算。3.3 长短期记忆的分层设计前文提到记忆分四类实际落地时我会把它们压缩成经典的长短期记忆两层结构来用**短期记忆层Short-term Memory**对应工作记忆和最近的情景记忆。用 Redis 或内存缓存实现保存当前会话的关键状态TTL 一般设置为几小时到一天会话结束或任务完成就清理。这一层要求读写快、延迟低给 Agent 提供当前正在做什么的连续感。**长期记忆层Long-term Memory**对应语义记忆和沉淀后的情景记忆。用向量库 结构化数据库组合保存用户画像、已验证的知识、历史事件的关键结论。写入时机是信息稳定之后比如用户明确表达了偏好或者一个任务成功收尾后把关键信息总结成记忆条目入库。短期和长期之间需要一个**记忆固化Consolidation**机制。我的做法是每次任务结束时跑一个记忆提炼的步骤用一个小模型把本轮的临时状态梳理成值得长期保存的事实写入长期库。这个步骤很像人脑把白天的经历在睡眠中转化成长期记忆的过程所以我也管它叫睡眠阶段。3.4 记忆召回的质量控制记忆不是存得越多越好。召回时如果塞进去一堆不相关或过时的记忆对 Agent 的危害比没有记忆还大——它会一本正经地参考错误信息给出答案。我在生产项目里做了三道质量闸门第一道相关性重排。向量检索召回 TopK比如 20 条后用一个重排模型Reranker按当前任务相关性精细打分只保留前 5~8 条。别把 TopK 直接全塞给模型Too many irrelevant context 是 Agent 胡说八道的头号原因。第二道时效性过滤。记忆条目带上时间戳检索结果里加入时间衰减权重。用户的偏好、项目状态都可能变化半年前的用户想要 A很可能现在已经是 B 了。第三道冲突消解。如果检索出的记忆条目互相矛盾比如一条说用户偏好中文另一条说用户偏好英文需要有一个规则或模型来判断哪条是最新、最可信的。最简单的做法是给每条记忆一个置信度分数发生冲突时取置信度高且更新时间近的同时对旧条目标记待用户确认。这三道关卡做完记忆系统才算是可用的而不是能跑的。4. MCP让 Agent 从会聊天变成会干活记忆解决了Agent 知不知道的问题而工具解决的是Agent 能不能做的问题。自打大模型开始具备调用能力工具接入的方式就一直在演化早期是开发者写死的函数调用Function Calling各家大厂各玩各的协议不互通后来演进到 OpenAI 的 Tool Calling生态有所统一但仍局限于单一平台。直到 2024 年底 Anthropic 开源了 MCPModel Context Protocol这个局面才真正被打破。4.1 MCP 是什么解决什么问题MCP 是一个开放协议它定义了大模型应用与外部工具、数据源之间标准化的通信方式。你可以把它理解为 AI 世界的USB-C 接口过去每个外设厂商都要给自己的设备做专属连接线而现在只要设备支持 USB-C就能连到任何终端上。在 MCP 之前开发者为每个 Agent 框架接入工具基本都要写定制代码。比如你要让 Agent 查数据库、操作文件、调用内部 API得为每个工具单独写一套提示词模板 解析函数 错误处理。换个框架这套代码几乎全部作废。MCP 的愿景是工具提供方只需实现一次 MCP Server任何支持 MCP 的客户端都能直接使用。这带来的直接好处有三点工具接入的复用性大幅提升Agent 与工具之间的数据格式统一为结构化 JSON-RPC安全管控上更清晰每个工具都暴露明确的接口边界。4.2 MCP 的三层架构MCP 协议里最核心的三个角色是Host宿主也就是客户端应用比如 Claude Desktop、Cherry Studio、Cursor、自己开发的 Agent 程序。Host 负责发起连接、管理会话、把 Llama 模型或 API 的调用请求转发给 MCP Client。Client客户端运行在 Host 内部负责与 Server 建立连接、发现服务端可用的工具列表、发送调用请求。通常由 MCP SDK 封装好你只需要配置连接参数。Server服务端实际上是独立运行的进程或服务它把自己拥有的工具能力暴露出来。比如一个文件系统 Server 提供 read_file、write_file、list_directory 这些工具一个数据库 Server 提供 query、execute 这些工具。Server 与 Host 之间通过标准协议通信传输方式可以是本地 stdio也可以是远程 HTTP/SSE。这套架构最妙的地方在于工具的具体实现和 AI 应用彻底解耦。你可以在一个地方开发好工具放到任何支持 MCP 的客户端里去用也可以在一个客户端里同时挂多个 Server让 Agent 一站搞定文件、数据库、API 等各种资源。4.3 手把手给 Agent 配一个 MCP 工具很多项目里最常见的工具需求就是读文件 写文件下面拿本地文件系统 Server 举例看一眼真实配置长什么样。假设你用的是 Claude Desktop 或 Cherry Studio 这类支持 MCP 的客户端配置集中在 JSON 文件里Claude Desktop 是claude_desktop_config.json{ mcpServers: { filesystem: { command: npx, args: [ -y, modelcontextprotocol/server-filesystem, /Users/me/workspace, /Users/me/documents ] } } }这段配置声明了一个名为 filesystem 的工具服务启动命令是用 npx 运行官方文件系统 Server并把两个目录作为允许访问的根目录。启动后 Client 会通过 stdio 与这个 Server 通信Agent 在对话中被问到帮我看看 workspace 里有什么文件就会自动调用 list_directory 这个工具把结果返回给模型。如果你自己在写 Agent 代码需要把 MCP Server 接进来用官方 Python SDK 的思路大概是from mcp import ClientSession, StdioServerParameters from mcp.client.stdio import stdio_client # 1. 定义要启动的 MCP Server server_params StdioServerParameters( commandnpx, args[-y, modelcontextprotocol/server-filesystem, /Users/me/workspace] ) # 2. 建立连接并拿到客户端 async with stdio_client(server_params) as (read, write): async with ClientSession(read, write) as session: # 3. 初始化握手 await session.initialize() # 4. 获取该 Server 暴露的工具列表 tools await session.list_tools() for tool in tools.tools: print(tool.name, tool.description) # 5. 调用具体工具 result await session.call_tool( list_directory, arguments{path: /Users/me/workspace} ) print(result)这段代码的核心逻辑就五步定义服务、建立连接、握手、发现工具、调用工具。里面最重要的两个方法是list_tools和call_tool——前者让 Agent 知道你现在有什么工具可用后者真正执行具体动作。Agent 的推理循环会先看工具列表再根据用户需求决定调用哪个、传什么参数。4.4 工具不是越多越好边界、安全与授权MCP 让接工具变得异常简单结果我见到不少项目走上另一个极端一口气挂二十个 MCP ServerAgent 反而不知道用哪个了。工具也是上下文的一部分工具列表越长模型选择的准确率越低而且每次工具调用返回的 Token 也会吃掉预算。我的建议是按任务必需和高频复用两个原则控制工具数量。一个客服类 Agent 需要的是知识库查询、订单系统查询不需要给它接一个代码执行器一个代码生成 Agent 需要的文件读写、终端执行也不需要接天气查询。工具和记忆一样要克制。安全是另一个必须提前设计的点。MCP Server 暴露的工具本质上是Agent 的手权限越大风险越大。至少要做到几下几点最小权限原则文件系统 Server 只开放指定目录数据库 Server 只给只读账号API 工具只授权必要的操作。敏感操作二次确认对删除、写入、转账这类不可逆或高影响操作Agent 必须先向用户申请确认再执行。这层逻辑应该是框架级的不能完全指望模型自觉。工具调用审计留痕所有工具调用记录入日志包括时间、参数、返回结果、由哪个 Agent 发起方便事后回溯。有些开发者在 MCP 生态里做了很多有意思的方向比如把调试器能力封装成 MCP Server、把设计软件的接口封装成 MCP Server。这说明 MCP 的生态外沿还在快速扩展。但无论工具怎么丰富连接什么、给什么权限始终是开发者自己的责任不能甩给协议或者模型。5. 一个能落地的 Agent 记忆 工具整体方案前面把上下文、记忆、MCP 分开讲清楚了但真实项目里这三者是配合工作的。这里给出一个我在业务项目里验证过的整体设计照着这个骨架改能省很多弯路。5.1 整体分层架构我当时跑通的方案是四层应用层面向用户的交互界面网页、IM、命令行负责收集用户输入、展示 Agent 输出。Agent 核心层负责推理和决策。它持有系统提示词、当前任务状态通过计划-执行-观察循环推进任务。需要记忆时访问记忆服务需要干活时通过 MCP Client 调用工具。记忆服务层包含短期缓存Redis、长期向量库Qdrant、结构化数据库PostgreSQL。记忆写入和检索的逻辑都封装在这一层Agent 核心层不直接操作存储。工具服务层所有 MCP Server 独立进程部署按领域拆分为文件工具、数据库工具、HTTP 请求工具、内部业务工具。通过 MCP 协议与核心层通信。这个分层最大的好处是每一层都能独立替换今天用 Qdrant明天换 Milvus只改记忆服务层今天工具部署在本机明天迁到远程服务器只动 MCP Server 的连接配置Agent 核心层几乎不用改。5.2 一次真实任务的数据流拿用户让我写一个周报并发送到企业微信群这个任务举例看看数据是怎么流的用户发来一句话帮我整理本周项目进展发到群里。Agent 核心层先把这句话写入短期记忆Redis记录当前任务目标。Agent 决策需要用户信息和历史周报格式于是向记忆服务发检索请求向量库里捞回用户偏好简洁风格上周周报格式为三段式两条记忆注入上下文。Agent 通过 MCP Client 发现有两个可用工具read_workspace_files 和 send_webhook_message。Agent 调用 read_workspace_files 读取本周的项目文档拿到原始材料。Agent 基于原始材料 用户偏好记忆生成周报内容。在发送前Agent 走到敏感操作二次确认关卡向用户展示最终周报内容请求确认。用户确认后Agent 调用 send_webhook_message 发送成功。任务结束后记忆提炼机制运行把用户偏好三段式周报风格固化到长期向量库。短期记忆中的临时状态被清理。这一步走完你会发现记忆让 Agent 更懂用户工具让 Agent 真的把事情做完而上下文窗口始终只承载当前这一步所需的信息没有被历史拖垮。5.3 框架选型参考表市面上的 Agent 框架很多和记忆、工具相关的侧重点不完全一样。我整理了一张选型参考表方便你按项目情况快速判断框架记忆能力工具接入适合场景LangChain / LangGraph内置 Memory 模块支持向量库接入原生支持 MCP也有 Tool Calling 封装流程固定的知识库问答、多步任务编排LlamaIndex侧重 RAG检索和记忆结合紧密MCP 适配逐步完善文档密集型应用、知识管理类 AgentCrewAI多 Agent 协作记忆按 Agent 维度隔离通过 Tool 类接入已有 MCP 适配需要角色分工、多智能体协同的项目AutoGen会话驱动的多智能体记忆偏会话层支持函数调用和 MCP 扩展研究探索、多轮对话型 Agent自研框架最灵活记忆和工具完全可控按需实现 MCP Client 或 SDK生产级、定制化要求高的核心系统个人经验是原型期可以用重量级框架加速生产期尽量把记忆和工具调度逻辑沉淀到自己的服务层。框架再方便它也很难覆盖你业务里那些记忆什么时候写、从哪一层写、写多细的定制需求。5.4 双网络记忆模型思路这里单独聊一下搜索引擎热词里频繁出现的双网络记忆模型。简单说它借鉴了人类大脑的海马体-新皮层双系统理论一个快速、容量有限、负责当前上下文绑定的短期系统另一个慢速、容量巨大、负责语义归纳的长期系统。在 Agent 里对应的实现就是在线记忆网络负责快速读写最近交互状态离线记忆网络定期把高价值信息归纳压缩、写入长期知识库。这个思路的价值在于它解决了写入太频繁导致长期库垃圾信息过多的问题。实际操作时我会设定一个批处理节奏每完成 5 个任务或积累 20 条短期记忆才触发一次离线归纳任务用一个大模型把短期记忆里的信息去重、合并、提炼生成高质量长期记忆条目。这个批处理的成本比你每轮对话都写长期库低得多也更容易保证长期库的整洁度。6. 常见问题排查与避坑实录最后这部分整理一下我做 Agent 记忆和 MCP 接入时反复遇到的典型问题每一条都是实际案例里跑出来的值得收藏。6.1 上下文窗口用完了怎么办速查版如果你的 Agent 频繁出现越聊越笨或者直接报 context_length_exceeded按下面顺序排查第一步确认是不是历史消息全量注入。很多框架默认把所有对话历史都塞进上下文这是爆窗的最大元凶。改成系统提示 抽取后的记忆 最近的 N 轮消息。第二步确认系统提示词有没有被顶掉。有些项目在任务执行中会动态插入大量内容导致核心指令被挤出窗口。给系统提示加不可截断保护。第三步检查单次工具返回内容。一个大文件一次性读进上下文可能直接吃掉几十 K token。给文件读取工具加行数限制超长文件分段读取。第四步如果你的场景确实需要全部历史分组摘要。每 10 轮对话生成一次摘要历史轮次只保留摘要 最新几轮原文。6.2 MCP 连接经常失败怎么排查我在给项目接 MCP Server 时遇到最多的报错就是Client closed或者Tool not found。按照这几层来查进程层检查 Server 的启动命令是否正确。用 npx 启动时经常遇到的是 npx 需要下载包导致首次启动超时可以先手动执行一次 npx 命令把包缓存好再接入。协议层stdio 通信时Server 端的日志和 Client 端的日志混在同一管道会导致解析失败。确保 Server 的日志输出到独立文件不要打印到 stdout。工具发现层Agent 明明配置了 MCP Server却总是说没有可用工具。这种情况先直接调 list_tools看有没有返回工具列表。如果返回为空大概率是 Server 的初始化握手有问题或者工具注册时抛了异常被吞掉了。6.3 Agent 记忆串线、答非所问怎么处理记忆串线是说 Agent 把过去的、属于另一个任务或另一个用户的信息错误地用在了当前任务里。绝大多数时候是召回环节松了。我碰到过一个案例Agent 在一个通用助手里突然用去年的项目预算回答用户今年新的预算问题。查下来是检索的 TopK 值设得太大旧记忆混进上下文模型又缺乏区分新旧的能力就直接采用了。解决办法就是前面说的那三道质量闸门相关性重排 时效性过滤 冲突消解。除此之外检索时加上 metadata 过滤比如按用户 ID、按任务类型过滤是最有效的硬隔离手段。6.4 记忆和工具使用中的成本黑洞记忆写得太多、向量检索每次都要查一遍成本会悄悄变高。有一个非常典型的场景Agent 每轮对话都去检索长期记忆库查出来的结果还都注入上下文结果每一轮都带着四五条历史记忆跑Token 消耗直接涨了三成。我的建议是检索不是每轮必须做的。可以用一个轻量判断规则——当前用户提问是否需要外部知识只有需要时才触发检索。另外短期记忆里已有的信息就不要重复检索长期库。这个优化做完之后Token 成本能降下来不少而且回答质量没有下降因为减少了不相关的上下文干扰。6.5 Agent 安全红线最后说几句安全。MCP 让 Agent 的能力边界大大扩展但能力越大责任越大。三个红线不要踩第一不要把生产环境的写权限直接暴露给 Agent。给工具用的数据库账号权限必须细化到表和操作级别能只读就只读。第二敏感工具调用必须有用户确认。不管是删文件、发消息、执行代码、还是转账付款这类操作的确认逻辑必须是用户无法跳过的环节不能只靠 Agent 提示一句我可以执行吗就真的执行了。第三定期清理记忆库中的隐私数据。记忆库里存了大量用户对话一旦泄漏就是事故。设计阶段就要考虑哪些信息可以进长期库用户要求删除记忆时怎么执行这些不是事后补救而是架构设计的一部分。这套 Agent 记忆加工具的方案我前后迭代了差不多两三个月才稳定下来。踩过最深的坑就是早期把记忆当作把历史塞进窗口后来才明白记忆是一个独立的基础设施它的设计目标是让 Agent 在有限注意力下做更聪明的选择性关注。现在每次接入新业务我都会把上下文管理、记忆分层、工具边界三件事放到一起去想而不是各自为政。如果你现在也在搞 Agent建议从最小闭环开始先把 MCP 工具接上让 Agent 真正能干活再逐步叠记忆分层让它越用越懂你。这两步走稳了Agent 的水平会上一个明显的台阶。