你有没有遇到过这样的情况:你的 AI 助手在同一个对话里记得你叫什么、喜欢什么,但只要关掉窗口,再次打开,它就完全不认识你了。更让人抓狂的是,今天你花了一下午教会它理解某个项目的背景,明天它又像个新人一样,问你同样的问题。
这其实是当前 AI Agent 开发中最常见也最头疼的问题——Agent 没有长期记忆。大语言模型天然是“无状态”的,每一次对话结束后,所有上下文都会丢失。而真正的智能体,或者说我们期望中的智能体,必须能够在多次交互中“记住”用户偏好、项目背景、决策历史和教训。今天这篇教程,就围绕一个非常实用的开源方案——Basic Memory,从零开始教你如何给 AI Agent 搭建一套基于 Markdown 文件的长期记忆系统。
本文适合用 Claude Code、Cursor、或者其他支持 MCP 协议的 AI 编程工具的开发者,也适合正在做 AI Agent 应用但苦于“记忆不持久”的开发者。读完你不仅能理解长期记忆系统的设计思路,还能亲手搭建一个可以跨会话、跨项目使用的记忆系统。
1. 为什么 AI Agent 总是“失忆”?
在动手搭建之前,我们先要搞清楚一个底层问题:为什么 AI Agent 会失忆?如果你跳过原理直接写代码,后面排查问题时会非常痛苦。
1.1 大语言模型的“无状态”本质
无论是 GPT、Claude 还是国产的 DeepSeek、通义千问,这些大语言模型本质上都只是一个“函数”:给定一段输入文本,预测下一段输出文本。模型内部虽然有数以千亿计的参数,但这些参数在模型部署之后是静态的,不会因为你的一次对话就发生变化。
举个例子,你和模型说“我的名字叫张三,我喜欢用 Python 写后端”。这句话会被计入当前对话的上下文窗口(Context Window),模型能在这段对话里记住张三和 Python 的偏好。但当你关闭对话,下一次重新开启时,模型拿到的是一个全新的、空的上下文,它当然不记得你叫什么。
1.2 会话隔离与上下文窗口限制
在实际应用中,还有两个加剧“失忆”的因素:
- 会话隔离:大多数 AI 产品每次会话都独立运行,甚至多个项目、多个用户之间完全隔离。这是一种安全设计,但也意味着信息无法自然流动。
- 上下文窗口有限:即使你在同一个会话里,模型也不能无限地记住内容。通常窗口长度在几万到几十万个 token,一旦超出,最古老的信息就会被“挤出”。如果对话过长,模型甚至可能忘记你最开始交代的重要背景。
1.3 “记忆缺失”在真实项目中的表现
以我实际做 AI Agent 项目时遇到的场景为例:
- 我在一个项目里反复告诉 AI:“后端使用 Spring Boot 3.x,数据库连接串在 nacos 里,不要写死。”但每次新开会话,它还是会在代码里写死 localhost。
- 团队希望 Agent 能记住项目的代码规范,比如“Controller 层禁止直接写 SQL”“异常必须统一封装”,但 Agent 每次都是从头理解。
- 用户使用 AI 客服产品,今天反馈了“我是上海的用户,工作日晚上 8 点后才有空”,明天再问 AI,它完全不记得,重新问一遍。
这些问题的根源就是缺少一个能持久化存储关键信息的记忆层。
1.4 长期记忆系统要解决什么
一个合格的长期记忆系统,至少要满足:
| 能力 | 说明 |
|---|---|
| 持久化 | 信息写入后,跨会话甚至跨项目存在 |
| 可检索 | 对话时能快速找到和当前问题相关的记忆 |
| 可更新 | 记忆不是一次性的,可以修改、删除、补充 |
| 可控制 | 用户可以查看记忆内容,决定哪些信息让 Agent 记住 |
| 低成本 | 不能每轮对话都把所有记忆塞给模型 |
思考下来你会发现,这不就是一个本地的、可供 AI 读写的外部数据库吗?是的,长期记忆系统的核心,就是给 AI 增加一个“外挂大脑”。而 Basic Memory 正是这种思路的极简实现。
2. Basic Memory 是什么?核心设计理念
2.1 定义:Markdown 即记忆
Basic Memory 是一个开源的、基于 Markdown 文件的本地知识库系统,专门用于给 AI 助手提供持久化记忆。它把“记忆”定义为一个个 Markdown 文件,存放在本地项目中,通过 MCP(Model Context Protocol,模型上下文协议)暴露给 AI 工具。
它的设计理念非常朴素:
人类是用笔记管理记忆的,AI 也可以。
当 AI 与用户对话时,如果需要记住某个信息,它会调用 Basic Memory 相关工具,把信息写成一个 Markdown 文件。下次对话时,AI 可以搜索这些 Markdown 文件,找到历史记忆,从而“想起来”。
这和你自己在 Obsidian 里写笔记没有任何区别,唯一不同的是,这是 AI 主动写入、主动检索的。
2.2 为什么选择 Markdown 而不是向量数据库
你可能会有疑问:既然做长期记忆,为什么不用向量数据库(比如 Chroma、Milvus,或者更轻量的 FAISS)?向量数据库不是更适合语义检索吗?
这个问题的答案,恰恰是 Basic Memory 最值得学习的地方:
- 可读性:Markdown 文件是人类可读的。你可以直接用编辑器打开、修改、删除一条记忆。向量数据库里存的是向量,出了问题你根本不知道里面是什么。
- 可版本控制:Markdown 是纯文本,天然适合 Git。你可以对记忆做版本管理,误删了也能回滚。
- 可移植性:如果你换了一个 AI 工具,记忆文件还在。它们不绑定任何特定模型或平台。
- 低成本:不需要额外部署数据库服务,也不需要维护向量索引。对个人开发者和中小团队,成本几乎为零。
- 可控性:AI 写的记忆质量不一定好,而 Markdown 让你能随时人工干预。
当然,它也有缺点。纯 Markdown 的检索方式偏关键字和轻量语义,对海量记忆(比如超过几十万条)的高效语义检索不如向量数据库。但对于绝大多数个人项目和中小型 Agent 应用,这个方案完全够用。
2.3 工作原理:写记忆、找记忆、用记忆
Basic Memory 可以抽象成三个动作:
- 写记忆(Memorize):AI 根据对话内容,把需要记住的信息转成 Markdown 文件。
- 找记忆(Search):AI 收到新的问题时,先从已有的 Markdown 中检索相关记忆。
- 更新记忆(Update):如果信息有变化,修改对应的 Markdown 文件,而不是重新新建一条。
整个过程对 AI 来说,本质上就是“用工具读写本地文件”。但这种设计把“记忆行为”结构化,让 AI 的读写有了统一的目录和组织规则,从而保证记忆是可用的。
3. 环境准备与安装
下面进入实操环节。我们的目标是在本地搭建一个 Basic Memory 环境,并验证 AI 能跨会话记住信息。
3.1 环境要求
Basic Memory 基于 Node.js 生态,使用前需要确认环境:
| 组件 | 建议要求 |
|---|---|
| 操作系统 | macOS / Linux / Windows(WSL 更佳) |
| Node.js | 18 或以上版本 |
| npm | 随 Node.js 一起安装 |
| Git | 可选,但强烈建议,用于记忆版本管理 |
| AI 工具 | 支持 MCP 的客户端,如 Claude Code、Cursor 等 |
如果你不确定本机 Node.js 版本,可以执行:
node -v npm -v如果返回的版本低于 18,建议先升级 Node.js。Windows 用户建议使用 WSL2 环境,避免文件路径解析问题。
3.2 安装 Basic Memory
使用 npm 全局安装:
npm install -g basic-memory安装完成后,验证是否成功:
basic-memory --version如果控制台输出了版本号,说明安装成功。
注意:实际的包名和命令格式可能随版本迭代调整。如果你安装时遇到
package not found,请去 Basic Memory 官方仓库确认最新安装方式。本文示例重点演示配置思路,版本以你实际安装的为准。
3.3 初始化知识库目录
Basic Memory 的核心是“笔记目录”。你可以创建一个专门的目录来存放记忆:
mkdir -p ~/agent-memory cd ~/agent-memory git init建议把记忆目录初始化成 Git 仓库,这样每条记忆都有历史记录,方便回滚。
执行git init后,目录结构现在看起来像这样:
~/agent-memory/ └── .git/接下来需要告诉 Basic Memory 这个目录就是它的知识库根目录。通常在首次执行相关命令时,Basic Memory 会引导你完成配置,或者在配置文件中指定路径。我们下面来看核心配置。
4. 核心配置与原理说明
4.1 配置文件
Basic Memory 常用的配置文件路径为~/.basic-memory/config.yaml或~/.basic-memory/config.json,具体取决于版本。以下是一个典型配置示例,你需要根据实际情况调整:
# 文件路径:~/.basic-memory/config.yaml memory: path: ~/agent-memory # 知识库根目录,也可以是绝对路径 mcp: port: 8000 # MCP 服务监听端口,根据实际版本可能不需要配置这里最核心的是memory.path,它告诉 Basic Memory 把记忆文件存到哪里。
4.2 MCP 协议:Agent 与记忆之间的大门
MCP(Model Context Protocol)是 Anthropic 提出的一种开放协议,用于让 AI 应用与外部工具、数据源进行标准化通信。你可以把它理解为 AI 世界的“USB 接口”:只要设备和电脑都支持 USB 标准,插上就能用。
Basic Memory 通过一个 MCP 服务器(默认命令为basic-memory mcp)对外提供三类能力:
- memory/save:保存一条记忆。
- memory/search:搜索相关记忆。
- memory/list:列出最近的记忆记录。
AI 工具通过 MCP 客户端连接到这个服务器后,就能在对话中调用这些工具,实现记忆读写。
4.3 记忆文件的组织方式
Basic Memory 在知识库目录中,会把记忆组织成有规律的文件结构。下面是一个示例结构:
~/agent-memory/ ├── projects/ │ ├── backend-api.md # 某项目的背景信息 │ └── frontend-app.md ├── people/ │ ├── zhang-san.md # 某个用户的偏好 │ └── li-si.md └── topics/ ├── coding-standards.md # 代码规范 └── deployment.md文件名通常包含语义信息,便于人类和 AI 快速定位。文件内容则是普通的 Markdown:
# 用户:张三 - 名字:张三 - 语言偏好:Python - 后端框架:Spring Boot 3.x - 工作习惯:工作日晚上 8 点后在线 - 最后一次沟通日期:2025-06-20之所以采用这种结构,是因为它让记忆具有确定性。AI 不再需要在海量的向量切片中“猜”哪段相关,而是直接按照主题目录去查找,命中率更高,也更容易调试。
4.4 检索机制:先目录后内容
当 AI 需要回忆起某个信息时,它有两种方式:
- 列出目录:通过
memory/list查看当前记忆库中有哪些主题,快速缩小范围。 - 关键词搜索:通过
memory/search传入关键词,在 Markdown 内容中匹配。
因为 Markdown 本身就是结构化文本,Basic Memory 可以做一个简单的全文索引,不需要复杂向量化,响应速度非常快。如果后续记忆量增大,可以再接一个向量检索插件作为补充。
理解这套机制之后,我们进入实战。
5. 完整实战案例:让 AI 跨会话记住你的项目信息
下面我们用一个小项目来完整演示:让 AI Agent 记住“这是一个使用 Spring Boot 3 的后端项目,数据库连接信息保存在 Nacos,禁止在代码中写死数据库密码”。然后我们关闭对话,重新打开,再让 AI 根据记忆回答“这个项目的数据库连接信息一般怎么管理”。
5.1 创建项目记忆目录
假设我们当前的业务项目位于~/work/demo-backend,我们把它接入 Basic Memory 知识库。
先确认知识库目录存在:
ls ~/agent-memory如果还没有创建,执行:
mkdir -p ~/agent-memory/projects5.2 启动 Basic Memory MCP 服务
在终端启动 MCP 服务:
basic-memory mcp如果一切正常,终端会显示服务已启动,并监听在配置的端口上。
注意:这个进程需要保持运行。你可以把它放在后台,或者配置为系统服务,让 AI 工具随时可以访问。
5.3 连接 AI 工具
不同的 AI 工具接入 MCP 的方式不一样。以 Claude Code 为例,你可以在初始化时添加 MCP 服务器配置,或者在配置文件中指定。
配置片段(思路示意,具体字段以你使用的 AI 工具官方文档为准):
{ "mcpServers": { "basic-memory": { "command": "basic-memory", "args": ["mcp"], "env": {} } } }配置完成后,在 AI 工具内测试连接。如果工具支持“列出 MCP 工具”功能,你应该能看到memory_save、memory_search等工具已经可用。
5.4 写入第一段记忆
在 AI 对话中输入:
请记住:这个项目是 demo-backend,后端使用 Spring Boot 3.x,数据库连接配置统一放在 Nacos,不要在代码中写死数据库密码。AI 会调用 Basic Memory 的保存工具,把这段信息写入一个 Markdown 文件。你的~/agent-memory/projects/目录下会多出一个文件,内容类似:
# demo-backend 项目信息 - 项目名称:demo-backend - 后端框架:Spring Boot 3.x - 数据库配置:统一放在 Nacos - 规范:禁止在代码中写死数据库密码5.5 模拟“关闭会话再重开”
这一步是关键。关闭当前 AI 对话窗口,重新打开一个新的会话。
在新会话中,不要做任何额外说明,直接输入:
demo-backend 项目的数据库连接信息一般是怎么管理的?正常情况下,AI 会先调用memory_search,检索到上一步保存的记忆,然后回答:
根据之前的记忆,demo-backend 项目的数据库连接配置统一放在 Nacos 中,规范要求禁止在代码中写死数据库密码。如果它真的能说出这句话,恭喜你,一个最简单的长期记忆系统已经搭建成功了。
5.6 更新记忆
记忆不是一成不变的。假设后来项目升级到 Spring Boot 3.2,你可以让 AI 更新记忆:
项目 demo-backend 的后端框架升级到了 Spring Boot 3.2,请更新记忆。AI 应该会修改对应的 Markdown 文件,而不是新建一条互相冲突的记忆。这很重要,因为它保证了记忆库的一致性。
5.7 用 Python 脚本绕过 AI 直接读写记忆
有时候我们可能不需要 AI 工具,而是想在自己写的 Python Agent 中调用 Basic Memory。一种简单思路是直接读写 Markdown 文件。
下面是一个最小示例,核心演示思想,不绑定特定 SDK:
# 文件路径:~/work/demo-backend/memory_client.py ```python import os import glob from pathlib import Path MEMORY_ROOT = Path.home() / "agent-memory" def save_memory(category: str, title: str, content: str): """把记忆保存为 Markdown 文件""" folder = MEMORY_ROOT / category folder.mkdir(parents=True, exist_ok=True) # 文件名用语义化的短横线命名 safe_title = title.lower().replace(" ", "-").replace("/", "-") file_path = folder / f"{safe_title}.md" file_path.write_text(content, encoding="utf-8") print(f"已保存记忆: {file_path}") return file_path def search_memory(keyword: str): """在记忆中查找关键词""" results = [] for md_file in MEMORY_ROOT.rglob("*.md"): text = md_file.read_text(encoding="utf-8") if keyword.lower() in text.lower(): results.append({"file": str(md_file), "content": text}) return results if __name__ == "__main__": # 保存一条测试记忆 save_memory("projects", "demo-backend", "# demo-backend 项目信息\n\n- 项目名称:demo-backend\n" "- 后端框架:Spring Boot 3.x\n" "- 数据库配置:统一放在 Nacos\n" "- 规范:禁止在代码中写死数据库密码\n") # 搜索 result = search_memory("Nacos") print("命中条数:", len(result)) for r in result: print("文件路径:", r["file"])运行:
python memory_client.py预期输出类似:
已保存记忆: /home/user/agent-memory/projects/demo-backend.md 命中条数: 1 文件路径: /home/user/agent-memory/projects/demo-backend.md这个脚本虽然不是通过 MCP 协议调用 Basic Memory,但演示了最核心的思想:记忆就是本地的 Markdown 文件,任何程序都可以读写。如果你的 Agent 是用 Python 写的,完全可以直接操作这些文件,不需要经过复杂的外部服务。
6. 常见问题与排查思路
在实际搭建和使用 Basic Memory 的过程中,我最常遇到的问题有以下几类,整理成表格供你排查。
6.1 问题排查速查表
| 问题现象 | 常见原因 | 解决思路 |
|---|---|---|
| 安装 basic-memory 时报错 | Node.js 版本过低 | 升级 Node.js 到 18 或更高版本 |
| MCP 服务启动失败 | 端口被占用 | 检查端口,或修改配置里的监听端口 |
| AI 工具连不上 MCP | 配置字段错误 | 对照 AI 工具的官方 MCP 配置文档检查字段名 |
| 保存记忆成功,但搜索不到 | 检索目录配置错误 | 确认memory.path指向的知识库目录是否跟实际写入目录一致 |
| 记忆文件中文乱码 | 终端编码问题 | 建议使用 UTF-8 编码,终端执行chcp 65001(Windows) |
| AI 回答时没有使用记忆 | 工具没有被调用 | 在对话中明确要求“先搜索记忆”,或者优化提示词 |
| 多个项目记忆互相干扰 | 没有按目录隔离 | 用projects/、people/、topics/等目录做分类 |
6.2 排查记忆不生效的通用流程
如果你遇到“AI 明明保存了记忆,但下次回答还是不知道”的情况,按这个顺序排查:
- 看记忆文件是否存在:打开知识库目录,确认 Markdown 文件已经生成,内容是否正确。
- 看 MCP 服务是否在运行:很多情况下,AI 工具与 MCP 服务之间已经断连,但 AI 不会主动报错,只是不调用记忆工具。
- 看检索关键词是否正确:AI 搜索时用的关键词可能和你记忆里写的不完全一致。比如记忆里写的是“Nacos”,但你问的是“配置中心”,可能匹配不到。解决方案是记忆文件里多写几个同义的关键词。
- 看提示词是否需要调整:有些 AI 工具默认不会主动去调用记忆工具,除非提示词里要求“回答前先搜索历史记忆”。
6.3 关于“AI 没调用记忆工具”的补充
这是我在实际使用中踩过最大的坑。你以为接上了 MCP,AI 就会自动使用记忆吗?不一定。很多 AI 工具在长对话中,会依赖上下文窗口里的信息直接回答,不会主动去检索外部记忆,除非当前上下文里没有相关信息,或者用户的提示词强制它去搜索。
解决思路有两个:
- 在系统提示词(System Prompt)里明确写:“你在回答用户问题时,必须先调用 memory_search 工具检索与问题相关的记忆。”
- 在知识库的根目录放一个
AGENTS.md或MEMORY.md文件,里面写清楚这个项目有哪些记忆文件,AI 在每次对话开始时会自动读取这个索引文件,从而知道“自己应该有记忆”。
# 项目记忆索引 本目录存放 AI Agent 的长期记忆。每次对话开始时,请先浏览 projects/ 目录, 如果有与当前任务相关的项目记忆,请主动阅读并作为回答背景。这种做法成本极低,却能让 AI 的记忆命中率大幅提升。
7. 最佳实践与工程建议
一个能用的记忆系统和好用的记忆系统,中间隔着很长的距离。下面是我在把 Basic Memory 用在真实项目后总结的几条经验。
7.1 给记忆分级
不是所有信息都值得写入长期记忆。我们可以把信息分成三层:
| 层级 | 内容 | 示例 | 是否写入 |
|---|---|---|---|
| 临时信息 | 当前对话内的中间思考 | “刚才那行代码报错是因为少了个分号” | 不写 |
| 会话信息 | 本次会话需要但下次不一定有用 | “今天修改了登录接口的参数命名” | 可选 |
| 长期信息 | 跨会话必须一致的事实 | “数据库连接配置放 Nacos”“用户偏好 Python” | 必须写 |
滥用记忆系统,会让记忆库变成垃圾场,检索时混入大量无效信息。建议在提示词里向 AI 强调“只有用户明确要求记住,或者信息属于长期事实时,才调用保存工具”。
7.2 使用 Git 做记忆版本管理
我在前文就建议过,知识库目录最好初始化成 Git 仓库。这样做有几个好处:
- 每次记忆变更都能看到 diff,审计 AI 做了什么。
- 如果 AI 误删或误改了一条重要记忆,可以快速回滚。
- 可以把记忆库推送到远程仓库,实现多设备同步。
建议在记忆库目录下创建一个.gitignore,忽略不需要纳入版本管理的文件(如果有的话)。
7.3 定期人工整理记忆
AI 写的记忆不会自动变得结构化。时间一长,可能同一个主题下出现多个文件,内容互相矛盾。我建议:
- 每周花 10 分钟浏览一遍新增的记忆文件。
- 合并重复文件。
- 修正不准确的表述。
- 删除过期信息。
记住,Basic Memory 只是一个文件系统,记忆质量取决于整理的人。
7.4 敏感信息与安全边界
这条非常重要。长期记忆系统意味着 AI 会把一些用户隐私、项目敏感信息写入本地 Markdown 文件。你要注意:
- 不要把密钥、密码、令牌写入记忆。我见过有人让 AI 把数据库密码写到记忆里,这在本地单机环境下看似没事,但只要记忆库同步到 Git 远程仓库,密码就泄露了。
- 知识库目录要设置好权限。特别是多用户机器上,不要让其他系统用户能读取你的记忆目录。
- 如果是团队共用记忆库,需要约定写入规范和敏感信息过滤规则。比如用脚本扫描记忆库,禁止出现
password、secret、api_key等字段。
7.5 在 Agent 架构中的定位
最后说一个工程视角。Basic Memory 不是万能的,它只是“外部记忆层”的一种实现。在完整的 AI Agent 架构里,你可能还需要:
- 对话历史库(存储每一次原始对话)。
- 工作流状态存储(比如用 Redis 保存 Agent 当前执行到哪一步)。
- 向量数据库(海量知识语义检索)。
- 短期记忆(当前任务上下文)与长期记忆(跨任务持久信息)。
Basic Memory 更适合承担“长期事实记忆”这一块,它简单、可读、可维护,并且不会把你锁在某个特定平台上。“用 Markdown 做记忆”这个设计,我非常喜欢,因为它让 AI 的记忆变得透明。你知道它记住了什么,知道怎么改,也知道怎么迁移。
8. 总结:从“能用”到“好用”
现在把这条完整的搭建路线再回顾一遍:
- AI Agent 失忆的根本原因是模型无状态,外部记忆层是必要的补充。
- Basic Memory 用 Markdown 文件充当记忆载体,通过 MCP 协议与 AI 工具通信。
- 安装过程很简单:npm 全局安装,初始化知识库目录,配置 MCP,连接 AI 工具。
- 验证记忆是否生效:写入一条项目信息,重开会话,看 AI 能否检索出来。
- 排查思路要清晰:先看文件是否存在,再看 MCP 服务是否运行,最后看提示词是否引导 AI 使用记忆。
如果你只是在个人项目里自己用,这套方案完全足够了。如果想在团队里推广,建议再加上 Git 协同、记忆分级、人工review 机制和敏感信息扫描,把记忆库当作团队的知识资产来管理。
下一步你可以继续研究的方向包括:基于 MCP 协议的更多记忆插件、把 Basic Memory 和向量数据库结合做混合检索、或者用 LangChain/LangGraph 在 Agent 中封装一个“记忆管理器”,在每次对话前后自动调相关工具。等你熟练之后,你会发现所谓“智能体”,其实就是会合理使用外部记忆和工具的大模型。
动手试试吧。与其抱怨 AI 记不住,不如用半个小时,亲手给它装一个“外挂大脑”。