AI Agent长期记忆方案:用Markdown文件实现跨会话记忆
2026/8/26 8:52:16 网站建设 项目流程

很多做过 AI Agent 的开发者都有同一种体验:模型能力很强,任务也能完成,但只要对话窗口一关,Agent 就彻底“失忆”了。用户这次说过的偏好、你上个礼拜整理的结论、项目里已经确定的技术选型,在新会话里全都不存在。你不得不每次重新配置提示词,或者在对话开头反复粘贴历史背景。一旦 Agent 要承担跨天任务、多轮项目推进、周期性信息整理这类真实工作,这种失忆问题会直接把所有效率优势全部抵消。

Basic Memory 就是来解决这个问题的。它不是一个重量级的向量数据库,也不需要自建知识库平台,核心思路很简单:用本地 Markdown 文件承载 Agent 的长期记忆,通过文件结构、标签、链接和语义检索,让 Agent 在对话时能够读取、写入、更新自己的记忆。对于个人 Agent、本地部署场景、中小型工作流来说,这种方案比一上来就接复杂存储系统更透明,也更容易维护。

这篇文章适合已经在用 LangChain、Dify、Coze 或自己写 Agent 编排逻辑的开发者,也适合刚接触 AI Agent 开发、想知道“长期记忆到底怎么落地”的读者。我会先拆解 Basic Memory 的记忆机制,再给出一套从零跑通的流程,包括环境准备、最小闭环、接入工作流、参数配置、常见坑点和长期落地路径。

先给出我的结论:Basic Memory 解决的不是“模型能不能记住”,而是“系统能不能把记忆稳定持久化,并在需要时准确找回来”。它用 Markdown 文件而不是数据库来做存储,这既是它最大的优点,也是你需要注意的边界。

1. 先搞懂 Basic Memory 的长期记忆机制,别急着上向量库

很多开发者在设计 Agent 长期记忆时,第一反应就是向量数据库。要选 embedding 模型、设计分块策略、搭索引、写召回服务,还要考虑数据更新和删除。这一套对超大规模知识库来说是必须的,但如果你只是做一个个人助手、内部运营 Agent、项目跟进机器人,维护成本往往比收益还高。

Basic Memory 换了一种思路:把记忆写成 Markdown 文件。每条记忆可以是一条用户偏好、一个项目背景、一段结论、一个知识点。文件之间通过标签和链接建立关联。Agent 运行时,不是把所有历史对话都塞进上下文,而是先检索相关记忆文件,再把召回内容作为上下文注入当前对话。

这个机制有几个明显优势:

  • 记忆可见。所有记忆都是普通 Markdown 文件,你可以打开目录直接查看、修改、删除。出问题时完全不是黑盒。
  • 记忆可追溯。每个文件都有创建和更新时间。Agent 更新记忆时能知道前后差异,而不是直接覆盖。
  • 记忆可复用。同一份记忆文件可以同时被多个 Agent、多个会话、多个任务读取,不需要每个会话重复输入。

所以,Basic Memory 真正解决的是“上下文从哪里来”的问题。传统 Agent 每次对话只依赖系统提示词和当前窗口,窗口之外全是空白。Basic Memory 把记忆放在 Agent 可以主动访问的地方,相当于给 Agent 加了一个外部长期存储层。

不过边界也要说清楚。它不适合存储百万级文档,也不适合做高并发在线检索服务。更准确的定位是:作为个人知识库和 Agent 之间的记忆层。如果你要处理的是大规模文档库、多人协作知识系统,再考虑向量数据库。

1.1 一套长期记忆系统应该包含哪些内容

从实现角度拆解,长期记忆系统一般可以分四层:

  • 用户记忆层。记录用户偏好、身份信息、历史目标、常用表达方式。
  • 项目记忆层。记录当前任务、过往决策、项目背景、已完成事项和待办。
  • 知识记忆层。记录从对话或文档中提取的事实、概念、经验结论。
  • 交互记忆层。记录用户和 Agent 在不同会话中的交互要点,帮助理解上下文连续变化。

这四层不一定要完全独立。实际使用中,一条记忆可能同时属于多个层。比如用户说“我希望你以后输出简洁风格”,这既是用户偏好,也是后续所有项目任务的默认配置。Basic Memory 通过标签和链接,让同一条记忆可以出现在多个上下文中,而不是复制粘贴到多个位置。

1.2 为什么用 Markdown 而不是数据库

数据库方案看起来更工程化,但有一个隐藏问题:不透明。你很难快速查看数据库里到底存了什么,Agent 更新记忆后也没有办法直接检查。Markdown 方案的好处是,任何会编辑文本的人都能参与记忆维护。你可以手动加一条笔记,也可以写脚本批量导入旧记录,还能用 Git 管理记忆文件的变更历史。

我实测下来,Markdown 方案还有一个额外价值:Agent 写出的记忆在日志排查和代码评审时一眼就能看懂。你不用反查数据库表,直接打开记忆目录,就能判断写入是否成功、内容是否重复、信息是否过期。对长期维护来说,这种透明性非常关键。

2. 环境准备和最小可运行配置,先把链路打通

Basic Memory 的安装和部署并不复杂,但不同系统、不同 Python 环境会有一些差异。新手容易在前置阶段卡住。下面按通用流程整理,你按顺序走一遍,先把最小环境跑起来。

2.1 基础环境清单

建议按以下条件准备:

  • 操作系统:macOS、Linux、Windows 均可。Windows 上需要注意文件路径和符号链接问题。
  • Python 版本:建议 3.10 及以上。旧版本对最新依赖的支持不够好,容易出现版本冲突。
  • 包管理器:pip 或 uv 都可以。建议使用虚拟环境隔离,不要直接装到系统 Python。
  • 基础模型接口:Basic Memory 需要调用大模型做语义读取和记忆写入。建议准备好 OpenAI 兼容接口地址,或本地模型的 API 服务。

如果你的机器没有 GPU,也能跑通。这类系统的算力需求不高,核心依赖模型 API。如果使用本地模型,要先确认模型是否支持工具调用或 function calling,否则 Agent 可能无法正确触发记忆写入流程。

2.2 安装和目录结构

以一个干净的初始化流程为例:

mkdir basic-memory-demo cd basic-memory-demo python3 -m venv .venv source .venv/bin/activate pip install basic-memory basic-memory init

初始化之后会生成默认目录。我建议在正式使用前,先按项目需求整理目录结构,参考如下:

memory/ ├── notes/ │ ├── user-preferences.md │ ├── project-events.md │ └── knowledge-base.md ├── entities/ │ ├── user.md │ ├── project-a.md │ └── project-b.md └── relations/ └── user-project-links.md

这是一个示例结构,不一定要照搬。核心原则是:目录对应记忆类型,文件对应记忆实体。如果项目只有一块业务,一个 notes 目录也够用;如果业务复杂,再按项目、用户、知识领域拆分。

注意:第一次安装时不要急着配置复杂的目录结构。先用默认结构跑通一条记忆的写入和读取,再慢慢调整,否则问题叠加在一起很难排查。

2.3 模型配置

Basic Memory 需要配置模型接口。以 OpenAI 兼容接口为例,核心参数有三个:base_url、api_key、model 名称。

建议你先确认所用的模型服务商是否提供兼容接口。如果本地模型只支持原生接口,可能需要额外写一个适配层,把请求转换为兼容格式。

模型选择上的建议:

  • 如果只是测试,使用你日常用的对话模型即可,重点是验证整条链路是否通。
  • 如果要长期使用,优先选择上下文窗口较大、工具调用稳定的模型。长期记忆系统需要同时处理用户当前输入和检索回来的记忆,上下文窗口太小容易截断。
  • 不建议用超大参数模型处理每一次记忆写入。记忆写入操作本身比较简单,小模型够用时,成本和延迟都会更低。

3. 从零跑通最小闭环:写入、召回、更新

环境就绪后,最关键的是验证三个动作:写入、召回、更新。很多 Agent 项目把记忆系统想得很复杂,最后卡在“写不进去”和“读不到”这两个基础问题上。下面把一次最小闭环拆开讲。

3.1 第一步:让 Agent 把关键信息写入记忆

先写一个最简单的测试:让 Agent 记住用户的名字和输出偏好。核心是验证 Agent 能不能通过工具调用把一段文本写入 Markdown 文件。

从工程角度看,这一步有两个关键点:

  • 触发条件。Agent 不能把所有对话内容都写入记忆,否则记忆文件会无限膨胀。需要明确规则:只有用户表达偏好、给出结论、更新任务状态、提交项目背景时,才触发写入。
  • 写入格式。Markdown 文件应该有固定结构,至少包含标题、内容、标签、时间戳。这样后续读取和检索时,格式统一可解析。

一个简单的记忆文件示例:

--- type: user-preference tags: [user, preference, output-style] created: 2025-06-20 updated: 2025-06-20 --- # 用户偏好:输出风格 - 用户希望回答简洁,直接给结论,不需要冗长背景。 - 涉及步骤说明时,使用编号列表。

3.2 第二步:验证跨会话召回

写入完成后,开启一个新会话,问 Agent:“你还记得我希望你用什么风格回答吗?”

正常情况下,Agent 应该通过 Basic Memory 召回刚写入的偏好,然后按简洁风格回答。

如果 Agent 答不上来,按下面的顺序排查:

  1. 检查记忆文件是否真的写入。打开 notes 目录,确认文件内容完整、格式正常。
  2. 检查模型是否加载了记忆工具。有些模型需要提示词中明确描述工具用途,否则不会主动调用。
  3. 检查召回时的检索范围。有些配置只检索与当前会话直接相关的文件,如果偏好文件没有建立关联,可能搜不到。
  4. 检查路径和标签。Basic Memory 对命名空间、标签大小写可能比较敏感,差异会导致匹配失败。

这一步是整个系统最重要的一环。写入成功不算完成,只有跨会话召回成功,才说明长期记忆逻辑真正闭环了。

3.3 第三步:测试记忆更新

长期记忆系统一定会遇到记忆过期问题。比如用户说“我以后喜欢详细输出”,Agent 需要把之前的“简洁输出”偏好替换掉。这里建议做版本追加,而不是直接删除覆盖。

示例逻辑:

  1. 找到原有偏好文件。
  2. 保留历史记录,或者追加一条新记录。
  3. 更新 updated 字段,并标注“替代旧偏好”。
  4. 后续检索时,优先返回更新时间更近的记录。

不做版本管理的后果是:用户明明改过偏好,Agent 却返回旧信息,导致对话体验倒退。这不是模型问题,而是记忆更新策略设计问题。

4. 进阶:把 Basic Memory 接入 Agent 工作流

如果只是在单次会话里调用 Basic Memory,价值有限。长期记忆真正发挥作用的场景,是把记忆层嵌到 Agent 的完整工作流中:用户输入、意图判断、记忆检索、业务处理、结果输出、关键信息写入。下面介绍两种常见接入方式,你可以按项目阶段选择。

4.1 方式一:在 LangChain 风格流程中封装记忆工具

如果你的 Agent 使用函数调用方式编排,可以把 Basic Memory 封装成两个工具:remember 和 recall。

  • remember:负责写入和更新记忆。
  • recall:负责检索与当前问题相关的历史记忆。

典型流程如下:

  • 用户发起新对话。
  • Agent 先调用 recall,检索当前用户和当前项目的历史记忆。
  • 结合检索到的记忆生成回答。
  • 回答结束后,判断这段对话是否有值得保留的新信息。
  • 如果有,调用 remember 写入或更新对应的 Markdown 文件。

这个流程的好处是工具边界清晰,出问题时可以单独检查某个工具。缺点在于 Agent 是否主动调用工具,取决于提示词设计和模型能力。模型不够稳定时,会漏掉记忆写入。

4.2 方式二:在 Dify 或 Coze 类平台上用节点编排记忆流程

如果你在使用低代码 Agent 平台,不需要自己写代码。核心思路是:在 Agent 工作流中加入“记忆管理”节点。

具体做法依平台而定,但流程类似:

  • 开始节点:接收用户输入。
  • 记忆召回节点:调用外部接口,读取用户历史记忆。
  • 大模型节点:结合当前输入和召回记忆生成回应。
  • 记忆写入节点:判断回应内容中是否有需保留的信息,如有则写入记忆服务。
  • 结束节点:返回最终结果。

在平台化流程中,要特别关注记忆节点的调用频率。如果每条用户消息都同时触发召回和写入,在高并发时会浪费大量资源。建议给记忆节点加触发条件,比如用户消息长度超过阈值,或意图分类为“设置偏好、提交任务、更新项目信息”时才执行。

4.3 分清长期记忆和会话历史的职责

这里必须讲清楚一个容易混淆的点:Basic Memory 不等于会话历史。

  • 会话历史是短期上下文。当前对话窗口里,用户说过的所有话。
  • 长期记忆是跨会话的关键信息,经过筛选后持久化到文件。

两者缺一不可。不能用长期记忆代替会话历史,因为长期记忆只保存筛选后的关键信息,无法还原完整对话过程。也不能只用会话历史,因为窗口关闭后信息全部丢失。

工程上更稳妥的分工是:

  • 短期会话交给 LLM 的上下文窗口。
  • 长期记忆交给 Basic Memory 文件。
  • 系统提示词负责说明两者之间的关系和使用优先级。

这样即使模型上下文窗口有限,也能通过外部记忆保持对话的连续性。

5. 核心配置项、参数和判断标准

接入过程中,有几个配置点直接影响记忆系统的效果。下面用表格列出常见配置项和判断标准,方便你按场景调整。

配置项作用建议做法判断标准
记忆写入触发规则决定哪些内容值得写入用户偏好、项目结论、任务状态、经验总结记忆文件不无限膨胀,每次写入都有明确价值
记忆召回数量每次检索返回多少条记忆3 到 10 条之间召回内容与当前问题相关,不影响主回答长度
记忆文件命名决定检索和归类的准确性使用实体名或主题名前缀同义文件不重复,新旧版本可区分
更新时间戳决定哪条记忆是最新每次更新都刷新 updated 字段检索结果按时间排序,旧记忆不覆盖新记忆
模型接口超时避免记忆调用卡住主流程建议 30 到 60 秒失败时能快速报错,不影响用户会话
记忆关联建立实体之间的关系用标签或双链关联用户和项目跨项目复用记忆时,能找到关联上下文

这些参数不是越复杂越好。初学者使用基础配置就够了。只有当召回不准确、记忆文件混乱、更新不及时时,再针对性增加机制。

5.1 用结构化中间格式统一记忆写入

写入记忆时,尽量不要让模型直接输出一段自由文本。更好的做法是:让模型先输出结构化 JSON,再由代码解析后写入 Markdown。原因是自由文本容易丢失关键字段,后续检索和更新时难以准确定位。

一个可用的中间格式:

{ "type": "user_preference", "user": "user-001", "content": "回答时保持简洁,先给结论,再给原因", "source": "chat-session-2025-06-20", "tags": ["style", "output"] }

通过 JSON 中转,记忆写入器可以统一处理字段校验、去重和时间戳更新。这个设计在后期接入更多数据源时很有用,比如导入聊天记录、周报文本、项目文档时,都能复用同一套写入逻辑。

5.2 记忆去重和冲突处理

长期使用后,一定会出现同一主题多条记忆冲突的情况。例如一条记录写“用户偏好简洁输出”,另一条写“用户要求详细分析”。冲突不处理,Agent 召回时可能随机选取一条,表现极不稳定。

处理策略建议按优先级排序:

  • 以 updated 时间最新的记录为准。
  • 若没有时间戳,以来源更正式的记录为准,例如项目文档优先于普通聊天。
  • 若两条记录都是近期写入,标记为冲突,在后续对话中让用户确认。

这个策略不一定要全部实现,但至少要保证旧记忆不会覆盖新记忆。最简做法就是每次更新保留时间戳,检索时按更新时间倒序。

6. 实际落地中最常见的五个坑

这一节不列空泛的注意事项,只说我实测和常见项目中觉得最容易出问题的点,以及对应的排查链路。

6.1 模型上下文被召回内容塞满

有些开发者把召回门槛设置太低,每次用户提问都注入二十条记忆,结果模型上下文被占满,主任务反而没有空间。表现是回答变啰嗦、跑题、丢失用户当前指令。

排查顺序:

  1. 检查系统提示词中注入的记忆数量。
  2. 检查检索结果和当前话题的相关性。
  3. 如果是数量问题,减少召回条数。
  4. 如果是相关性问题,优化标签体系和检索关键词。

建议方案:只召回与当前用户、当前项目、当前话题直接相关的记忆。不要试图在回答每一个问题前把全部历史都塞进上下文。短期对话能力仍然需要保留足够空间。

6.2 记忆文件越写越乱

不设定归类规则,记忆系统用一个月后就会变成垃圾场。所有偏好、项目结论、临时想法堆在一起,检索时什么都搜到,又什么都搜不准。

避免方法是从第一天就定好规则:

  • 用户偏好单独一个文件或目录。
  • 项目记忆按项目命名。
  • 知识类记忆按领域命名。
  • 临时记录不进入记忆库,只留在会话中。

如果记忆文件已经混乱,不要急着全删。先按类型拆分,再补标签和时间戳,最后让 Agent 验证召回结果。

6.3 多轮会话中的重复写入

同一个用户在同一次对话中反复表达类似偏好,Agent 每次都在新建文件,最后产生大量重复记忆。这会增加检索噪音,也会让用户觉得 Agent 不记得自己说过的话。

解决方法是写入前先查重。如果同一实体、同一内容已经存在,就更新原文件,而不是新建。查重逻辑不复杂,按用户 ID 和偏好类型做一次精确匹配即可。

注意:重复写入看起来像模型问题,实际上多数是提示词里没有说明“先查找、后更新”的执行顺序。要让 Agent 收到新偏好时先调用 recall,再决定是新建还是更新。

6.4 文件权限和路径问题

本地部署时,Agent 进程必须拥有记忆目录的读写权限。这个问题在 Linux 服务器上非常常见,尤其是通过 systemd 或 Docker 运行时。目录权限配置不对,Agent 进程可以正常启动,但写入记忆时静默失败或直接报权限错误。

排查顺序:

  1. 确认记忆文件是否生成。
  2. 确认进程身份是否对目录有写权限。
  3. 查看日志中是否有 PermissionError。
  4. Windows 环境下额外注意路径大小写和符号问题。

6.5 模型不支持工具调用

部分模型不支持 function calling 或工具调用,Agent 无法触发记忆写入。这个问题在接入本地小模型时很常见。如果你发现 Agent 完全没有调用记忆工具的迹象,先不要怀疑 Basic Memory,先检查模型的工具调用能力。

替代方案:如果模型不支持工具调用,可以在提示词中强制模型输出 JSON,再写一个解析层,把 JSON 转成记忆写入指令。虽然不够优雅,但在小模型上可以兜底。

7. 从零到长期使用的落地路径

最后给一条适合大多数个人开发者和中小团队的落地路径。这个路径不是为了显得完整,而是尽可能减少踩坑。

7.1 阶段一:先跑通最小闭环

不要一上来就设计全面的记忆分类体系。先用默认配置跑通三个动作:

  • Agent 能把一条偏好写入文件。
  • 新会话能召回这条偏好。
  • 用户修改偏好后,Agent 能更新原文件。

这一步的目的只有一个:验证链路通不通。

7.2 阶段二:加入业务场景

确认链路通畅后,把真实业务场景加进来。假设你的 Agent 负责运营周报,记忆系统需要记住:

  • 用户所属项目和汇报对象。
  • 本周关键数据和待办。
  • 历史周报的输出风格。

这种场景下,按项目维度建立记忆文件,把每次周报结论追加到对应项目文件中。

7.3 阶段三:逐步处理边界情况

链路和业务场景稳定后,再逐步增加规则:

  • 更新时保留旧版本。
  • 重复内容先查重。
  • 召回结果按时间和相关性排序。
  • 设置记忆容量上限,比如每个用户最多保留多少条偏好。

边界规则不要一次全加。每次加一个,验证一个。否则出了问题,很难定位是哪一个规则影响了 Agent 行为。

7.4 阶段四:接入完整工作流

最后把记忆层接到 Agent 编排平台或自己的服务中。这时要关注的是:

  • 记忆召回是否影响主流程响应时间。
  • 记忆写入失败时是否需要重试。
  • 多用户场景下,是否按用户隔离记忆目录。
  • 是否对记忆文件做备份,比如用 Git 仓库或定时压缩。

跨会话记忆真正稳定的标志,不是第一次写入成功,而是连续使用几天后,Agent 仍然能准确召回最新偏好和项目信息,并且不会因为历史记忆过多而变得混乱。

8. 结尾

Basic Memory 这类文件型长期记忆方案,目标不是替代向量数据库,而是帮你用更透明、更好维护的方式,让 AI Agent 从“每次会话从零开始”变成“带着记忆继续工作”。它特别适合个人知识助手、运营分析 Agent、项目跟进机器人这类场景。

我个人更建议先把单条记忆的写入、更新、召回跑稳,再考虑批量和完整工作流。这个方案真正落地时,最该盯住的不是记忆功能本身,而是输入格式、文件分类、更新时间和管理规则。踩过几次坑之后会发现,很多问题不是工具能力不够,而是前置条件和提示词设计没有做好。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询