基于 MCP 实现持久化记忆
本文是 T 系列的第 03 篇,主要介绍 MCP 如何实现持久化记忆。
T 系列为技术文章翻译系列,加以本人的一些拙见,如有雷同,实属正常,如有不同,欢迎交流。
尽管 LLM 在处理和生成文本方面非常强大,但它们本质上是无状态的。每次 API 调用都被视为一个全新的独立请求,无法保留之前交互的任何记忆。要使 Chatbot 或虚拟助手真正有用,它必须具备记忆能力,能够记住用户的姓名、偏好或多轮对话的上下文。传统方法试图通过将整个聊天历史打包进 LLM 的提示中来解决这一问题,但这种方法效率低、成本高且容易出错。本文探讨了一种更稳健且可扩展的解决方案:利用模型上下文协议(MCP)将记忆实现为外部、可管理的工具。这种方法使 Agent 即使保持无状态,而有状态的工具则提供持久的记忆功能。
Agent 记忆用 MCP 的工具实现:Agent 通过工具调用获取记忆,并通过工具调用更新记忆,从而实现持久化记忆。
对话式记忆的挑战
给 Chatbot 赋予“记忆”的最常见方法,是每次发送新提示时,要传递完整对话历史。这种方法通常被称为“上下文窗口”,但它存在若干重大局限性:
- Token 限制与成本:LLM 具有有限的上下文窗口大小,随着对话内容不断增长,较早的消息必须被截断或摘要化以适应该限制,从而导致信息细节丢失。这也会增加每次生成响应时的 Token 使用量,进而推高 API 使用成本,即使只是简单的回复也不例外。
- 延迟与性能:更大的上下文窗口意味着模型在每次生成响应时需要处理更多的信息,从而导致延迟增加。
- 不一致性与“幻觉”:模型可能误读或“幻觉化”出聊天历史中长期且非结构化的信息,导致对话中出现细微但关键的错误。
传递完整对话历史,存在 Token 限制与成本、延迟与性能、不一致性与“幻觉”等问题。

上述问题表明,提示上下文窗口最适合短期记忆推理,而不适用于持久性的长期记忆。更好的解决方案应该是在模型推理之外,通过外部工具来实现持久化记忆。
MCP:记忆作为工具
MCP 将记忆的范式从隐式的、模型内部的属性,转变为由专用工具管理的显式外部资源。开发者不再要求模型“记住”信息,而是为模型提供一个具有明确定义功能(如 get_fact 和 store_fact)的 memory_tool。这正是构建无状态代理并结合有状态工具记忆的核心所在。Agent 本身保持无状态,仅通过遵循某种协议与外部存储库进行交互。
fact = 事实条目、知识片段、记忆实体
memory_tool 可以是简单的 Redis 缓存,也可以是复杂的知识图谱或向量数据库。这种方法具有以下几大优势:
- 可扩展性:记忆与模型分离。随着用户数量或对话深度的增加,您可以独立于 LLM 来扩展记忆存储。
- 一致性与控制:您可以自主控制存储内容及其检索方式。该工具可设计为存储结构化数据,避免原始文本摘要存在的歧义和不一致问题。
- 安全性:敏感的用户数据可安全地存储在专用数据库中,并具备独立的访问控制机制,而无需反复通过 LLM 再次推理。
- 长期记忆:记忆可在会话之间持久保存。当用户再次访问时,智能体可利用记忆工具检索其历史记录和偏好,从而实现真正个性化的体验。
上述功能,我觉得即使不使用 MCP,一个 Agent 应用也应该符合各特性。本质上说,这其实是一种记忆的存储、检索、共享的方式。
幕后:基于工具的记忆
让我们通过一个具体的例子来说明 MCP Agent 如何使用记忆工具来记住用户的姓名。
我们将称之为 user_data_store 的记忆工具,可以用以下模式定义:
交互流程如下所示:
- 用户输入:用户说:“你好!”
- 初始工具调用:Agent 的首要步骤是检查是否已知用户的姓名。它会生成一个针对
get_fact工具的工具调用:
- 工具结果:该工具返回一个结果。如果未找到名称,结果将为 null。
- Agent 逻辑:Agent 发现名称为空,于是生成新的回复:“你好!你叫什么名字?”
- 用户回复:“我叫 Alex。”
- 第二次工具调用:Agent 的推理在新输入中识别出用户的姓名,并生成一个工具调用以存储该姓名,以便将来使用。
- 最终回复:Agent 接收到工具结果,并利用新存储的事实提供个性化回复:“很高兴认识你,Alex!”
该流程将 Agent 的对话逻辑与记忆管理分开。Agent 无需在自身上下文中保留名称;它只需在需要检索或存储条目时,调用正确的工具即可。这是一种稳健且可扩展的模式,能够避免提示词中记忆的种种弊端。
有感而发
通过 MCP 使用外部工具实现记忆功能,是一种强大且实用的构建复杂 Chatbot 的解决方案。这种方法让我们不再将记忆视为棘手的提示工程问题,而是转向一种专业、架构化的解决方案。这种做法符合现代软件设计原则,例如职责分离和模块化。
虽然一些框架提供了自己的内存模块,但它们通常会隐藏底层机制,这可能使调试和自定义变得困难。相比之下,MCP 方法则更加透明且可审计。每次工具调用及其结果都会被记录,清晰地追踪代理“记忆”是如何被访问和更新的。
潜在的权衡是,由于每次记忆查找都需要额外的工具调用,导致了一定的延迟。然而,与每次请求都发送大量提示词所带来的性能提升相比,这种成本微不足道。真正价值在于由此带来的可靠性增强和可扩展性提升。对于开发生产级助手的开发者而言,能够控制数据持久化并避免状态相关不一致的问题,具有不可估量的价值。这种方法真正赋能了无状态却高度个性化的助手的构建。
这一篇,我觉得有些“强行绑定”的牵强,MCP 在记忆管理中的作用是存储与检索,而对于持久化记忆来说,读者应该更关心:如何结合实际场景展示持久化记忆的技术细节。