
在实际的 AI Agent 开发中最常被吐槽的问题不是模型不够聪明而是 Agent 总是“失忆”。一个基于大模型构建的 Agent无论调用云端 API 还是本地模型本质上都只能在当前会话的上下文窗口里工作。对话轮次一长、任务步骤一多、或者进程一重启早期信息就会丢失。Basic Memory 正是为了解决这个问题出现的方案它把 Agent 的记忆从“上下文窗口”搬到了“本地 Markdown 文件 SQLite 语义检索”的长期存储系统中。本文会从零开始搭建一套 Basic Memory 长期记忆系统并把系统接入 AI Agent让 Agent 可以跨会话记住关键事实、项目偏好和用户特征。在开始之前先明确这篇文章的服务对象正在做 AI Agent 开发、希望让 Agent 记住用户偏好或项目状态的人对 MCPModel Context Protocol集成感兴趣、想把外部工具接入对话模型的人以及正在设计 Agent 架构、需要把记忆层独立出来的开发者。读完本文后你会得到一套可以本地运行的记忆系统能通过命令行写入和检索记忆也能通过 MCP 让 Claude 或其他兼容模型主动调用记忆工具。1. 先理解 AI Agent 为什么会“失忆”以及长期记忆系统要解决什么问题1.1 上下文窗口本身就是一种易失性存储大模型没有“天然记忆”。模型每次回答都只基于当前请求里携带的上下文也就是 system prompt、历史对话、工具返回结果和用户最新输入。这部分内容会被模型当成连续文本处理但一旦请求结束模型内部不会保留任何状态。所以很多 AI Agent 项目会遇到以下现象多轮对话里用户在第 3 轮提到“我不吃辣”第 20 轮再次点餐时 Agent 又问“您有忌口吗”。Agent 执行一个包含 20 个步骤的任务前 15 步产生的结论在后 5 步没有被引用。服务重启后Agent 连上一轮已经完成的配置都记不住只能让用户重新说一遍。为了“记住”上下文开发者把越来越多的历史记录塞进 Prompt最终超过上下文窗口上限。上下文窗口不是记忆它只是“当前任务的工作区”。工作区里的内容会随着请求结束被清空也会因为 token 长度限制被截断。即使模型支持很长的上下文把全部历史都塞进 Prompt 也不是好方案查询成本变高、响应变慢、无效信息还会干扰生成质量。1.2 长期记忆系统需要承担四类职责要解决“失忆”需要把记忆从上下文窗口外部化形成独立的记忆系统。这个系统至少要解决四个问题写入哪些信息值得保存保存成什么格式。存储文本、结构化字段、向量索引分别放在哪里。检索在需要时如何快速找到与当前问题相关的那部分记忆而不是把所有记忆都返回。管理记忆文件如何更新、删除、去重、备份以及如何避免隐私泄露。这四个问题缺一不可。很多 Agent 项目只做了“把对话记录写进 JSON 文件”但没有检索能力结果 Agent 依然无法从大量历史里找到关键信息。也有项目只做了向量数据库却忽略可读性用户和开发者都不知道记忆里到底保存了什么。1.3 Basic Memory 的定位透明、本地、可编辑的长期记忆层Basic Memory 是一个基于 Markdown 文件构建的本地记忆系统。它吸收了笔记工具的理念每条记忆是一份可读的 Markdown 文件用户可以用 Obsidian、VS Code 或其他编辑器直接查看和修改。系统会解析这些文件把内容分块后生成向量索引存储在本地 SQLite 数据库中。查询时Basic Memory 根据语义相关性返回匹配的记忆片段。这套设计有几个关键好处记忆不藏在黑盒里文件写在哪里、内容是什么都一目了然。Markdown 文件天然适合版本管理可以用 Git 备份和追溯。语义检索可以解决“关键词对不上”的问题比如记忆里写的是“用户偏好 Rust”查询“后端技术栈”时也能命中。本地存储降低了隐私风险关键知识不需要全部上传到第三方数据库。对于个人知识库、单人使用的 Agent、本地自动化任务、以及需要调试记忆内容的项目Basic Memory 的复杂度比完整向量数据库方案低很多适合作为 Agent 长期记忆系统的起步方案。2. Basic Memory 的核心机制Markdown 文件、SQLite 与语义检索如何配合2.1 信息写入链路从自然语言到可检索索引当你在命令行执行basic-memory add 用户偏好后端开发喜欢 Rust时系统并不是简单地把这句话存进数据库。更合理的理解是它执行了下面这条链路接收自然语言文本。把文本归类并生成 Markdown 文件保存在笔记目录中。对 Markdown 内容做分块处理避免一条长记忆在向量化时被压缩成模糊的整体。把文本块交给模型生成向量embedding。把向量和文本内容一起写入 SQLite 数据库。写入阶段的关键决策是“既要保留原始文本又要生成可检索的索引”。原始文本保证人可读、可修改向量索引保证 Agent 能按语义搜索到它。如果只存向量丢失了可读性如果只存 Markdown失去了语义检索能力。Basic Memory 把两者放在同一套本地目录和数据库里既降低了运维成本也保证了数据一致性。2.2 信息查询链路从自然语言问句到相关记忆片段查询时Basic Memory 不会直接对 SQLite 做关键词 LIKE 查询而是走语义检索链路接收查询文本例如“用户常用的编程语言是什么”。生成查询文本的向量。在 SQLite 保存的向量索引中寻找与查询向量相似度最高的记忆块。结合元数据、标签、相关性分数做排序和过滤。返回匹配的 Markdown 内容或结构化字段。这种方式的优势在于查询词和存储词不需要完全一致。传统全文检索要求“Rust”和“后端技术栈”在字符层面有关联而语义检索可以理解概念之间的关系。当然语义检索不等于万能它对 embedding 模型质量、文本分块粒度、查询表达方式都有依赖。后面排错章节会专门讲检索不相关的问题。2.3 为什么选 Markdown 和 SQLite而不是只用一个向量数据库先看 Markdown 的价值。记忆系统的核心使用者有两类Agent 和人类。Agent 需要高效检索人类需要理解和纠正。纯向量数据库里存的是一堆二进制向量和切碎的文本块人类很难直接判断“模型到底记住了什么”。Markdown 文件则提供了可读、可编辑、可版本控制的中间层。用户发现某条记忆写错了直接编辑文件即可不需要写 SQL 或调用向量库管理接口。再看 SQLite 的价值。很多 Agent 项目一上来就引入独立的向量数据库服务但在个人项目或中小型 Agent 场景中这往往是不必要的复杂度。SQLite 单文件、零服务、易备份适合作为 Agent 记忆的本地存储层。Basic Memory 在这种方案里只用一套本地工具就能完成文本读取、向量存储和查询管理。容易误解的点是“向量数据库一定比 SQLite 好”。实际上方案选型取决于数据规模、并发访问和部署环境。如果你的 Agent 每天产生数十万条记忆、需要多机共享访问那么独立向量数据库更合适如果场景是个人助手、本地上班自动化、开发调试那么 Basic Memory 这样的轻量方案更易维护。3. 环境准备与安装在本地跑通 Basic Memory3.1 环境要求和前置检查Basic Memory 是 Python 编写的命令行工具和 MCP Server。安装前建议确认以下环境项检查项推荐要求说明操作系统macOS / Linux / Windows WSL涉及本地目录和命令执行原生 Windows 要注意路径处理Python 版本3.10 或更高依赖部分异步和类型特性版本太低会导致安装失败pip已安装并能访问 Python 包源网络环境如使用内网源需要确认包名可用包管理器pip 或 uv本文以 pip 示例模型 API Key已准备可用的模型服务密钥生成 embedding 和回答问题时需要调用模型服务检查本机 Python 版本一条命令即可python --version如果输出类似Python 3.9.18建议先升级 Python 或使用 pyenv 安装新版本。很多安装失败问题并不是包本身有问题而是 Python 版本不满足依赖要求。3.2 安装 Basic Memory推荐在虚拟环境中安装避免污染系统 Python 环境。下面以常见流程为例mkdir -p ~/agent-memory-demo cd ~/agent-memory-demo python -m venv .venv source .venv/bin/activate pip install --upgrade pip pip install basic-memory如果网络环境使用国内镜像可以临时指定索引源pip install -i https://pypi.org/simple basic-memory安装完成后确认命令可用basic-memory --help如果执行后提示command not found说明虚拟环境未激活或者 Python 的 Scripts/bin 目录没有加入 PATH。在虚拟环境下需要先执行source .venv/bin/activate。3.3 初始化记忆库和目录结构Basic Memory 通常需要先初始化本地配置、数据目录和笔记目录。以大多数版本的流程为例basic-memory init初始化命令会完成以下几件事创建配置目录和配置文件。创建笔记目录用于存放 Markdown 记忆文件。创建 SQLite 数据库文件保存向量索引和元数据。初始化完成后建议检查生成的文件结构ls -la ~/.basic_memory/ find ~/.basic_memory -maxdepth 2 -type d | sort不同版本的默认路径可能不同常见结构如下~/.basic_memory/ ├── config.json ├── memory.db └── notes/其中config.json保存记忆库配置memory.db是 SQLite 数据库notes/是 Markdown 笔记目录。注意初始化后的默认路径和文件名称会随版本迭代变化。落地前先执行basic-memory init并查看输出里的实际路径不要凭旧教程写死路径。4. 配置模型参数与常用命令先学会手动读写记忆4.1 配置 API Key 和模型服务Basic Memory 需要调用模型服务来生成向量和回答问题。常见做法是通过环境变量传入 API Key。以 Anthropic 风格的服务为例export ANTHROPIC_API_KEYyour-api-key-here也可以把 API Key 写入项目的.env文件或者按版本要求写入config.json。无论哪种方式都要注意密钥不能提交到 Git生产环境建议使用密钥管理服务。配置完成后先验证 Key 是否被读取env | grep ANTHROPIC如果输出为空说明环境变量没有设置成功。注意某些终端里export只在当前 shell 会话生效重启终端后需要重新设置。4.2 手动写入一条记忆运行add子命令把一条记忆写入系统basic-memory add 用户偏好后端开发喜欢 Rust希望项目采用模块化架构命令执行后可以打开笔记目录查看生成的 Markdown 文件cat ~/.basic_memory/notes/*.md不同版本的命名规则可能不同但文件内容应该包含可供人类阅读的文本。比如一条清晰记忆可能长这样--- title: 用户偏好 type: note tags: - 偏好 - 技术栈 created: 2026-01-01 --- 用户偏好后端开发喜欢 Rust希望项目采用模块化架构。这里的 YAML frontmatter 是记忆的元数据正文是记忆内容。Basic Memory 在解析文件后会把正文分块并索引。4.3 手动检索记忆写入后用search子命令查一下basic-memory search 用户的编程语言偏好返回结果里应该包含刚才写入的记忆以及相关度或来源信息。如果结果为空先检查文本内容是否真的写入了再检查 embedding 调用是否成功。ask子命令则更适合“直接问”的场景basic-memory ask 根据记忆用户喜欢什么编程语言它会把检索到的相关记忆作为上下文交给模型生成回答。区别是search更接近“检索工具”返回原始片段ask更接近“问答工具”返回模型整理后的答案。查看所有笔记basic-memory notes该命令会把本地 Markdown 文件列出方便确认记忆库里有什么。如果某些笔记是手动创建的也可以通过该命令检查是否被正确读取。4.4 常用命令速查表命令作用典型使用场景basic-memory init初始化配置、笔记目录、数据库第一次搭建basic-memory add 文本写入一条自然语言记忆Agent 任务结束后保存结论basic-memory search 查询按语义检索相关记忆片段召回相关事实basic-memory ask 问题基于相关记忆生成回答直接询问模型basic-memory notes列出所有 Markdown 笔记检查记忆库内容basic-memory mcp启动 MCP Server集成到模型客户端5. 与 AI Agent 集成通过 MCP 让模型主动使用记忆工具5.1 为什么要用 MCP 而不是直接拼 PromptMCPModel Context Protocol是一个让模型客户端与外部工具交互的开放协议。接入 MCP 后模型不需要知道工具内部实现细节只需要按协议发现工具、传入参数并读取结果。如果没有 MCP开发者通常会把记忆内容直接拼到 System Prompt 里。这种方式的缺点是每次对话都会把全部记忆塞给模型token 成本高并且记忆越长有效信息占比越低。用 MCP 工具的方式模型先判断“回答这个问题需要查记忆”再主动调用工具只把匹配片段带到上下文里。Basic Memory 提供 MCP Server意味着你可以把它接到 Claude Desktop、Cursor、以及其他支持 MCP 的客户端。在自研 Agent 中也可以用 MCP 客户端库启动basic-memory mcp进程。5.2 在 Claude Desktop 中配置 Basic Memory如果你的 Agent 使用 Claude Desktop 或类似客户端需要修改客户端的 MCP 配置文件。以常见 JSON 结构为例{ mcpServers: { basic-memory: { command: basic-memory, args: [mcp], env: { ANTHROPIC_API_KEY: your-api-key-here } } } }配置完成后重启客户端再打开 MCP 工具列表应该能看到 Basic Memory 提供的记忆相关工具。不同客户端配置文件路径不同建议查看对应官方文档。5.3 在自研 Python Agent 中调用 MCP 工具自研 Agent 可以使用 Python 的mcp库与 Basic Memory 通信。下面是一个最小示例用于列出 Basic Memory 暴露的工具import asyncio from mcp import ClientSession, StdioServerParameters from mcp.client.stdio import stdio_client async def main(): server_params StdioServerParameters( commandbasic-memory, args[mcp], env{ANTHROPIC_API_KEY: your-api-key-here}, ) async with stdio_client(server_params) as (read, write): async with ClientSession(read, write) as session: await session.initialize() tools await session.list_tools() for tool in tools.tools: print(tool.name) print(tool.description) print(- * 40) if __name__ __main__: asyncio.run(main())运行前确保已经安装 MCP 依赖pip install mcp执行后屏幕上会打印出 Basic Memory 提供的工具名称和描述。不同版本工具名可能不同通常会包含“写入记忆”“搜索记忆”“读取笔记”等语义。拿到工具名后就可以在 Agent 的 tool-use 循环中让模型调用这些工具。5.4 在模型提示词中声明记忆工具即使接入了 MCP也要在提示词里给模型足够的使用指引。模型不是默认知道什么时候该查记忆的你需要教会它在回答用户问题前如果问题涉及历史对话、项目状态、用户偏好请先调用 search_memory 查询相关记忆。 如果用户要求记录某条信息请调用 write_memory 保存并尽量使用清晰准确的表述。通过这种声明模型会形成稳定行为查记忆优先写记忆主动。这也是 AI Agent 开发中“技能化”的关键一步——把记忆访问能力封装成可复用的工具而不是写死在业务流程里。6. 运行验证从写入到检索的完整闭环6.1 准备一组模拟 Agent 产生的记忆为了验证系统是否真的可用建议先模拟一组真实信息。比如 Agent 在一次任务后产生了三条记忆basic-memory add 项目 demo-agent 使用 FastAPI 构建端口 8000接口文档在 /docs basic-memory add 用户希望部署在 Docker 容器中并配置健康检查 basic-memory add 用户偏好使用 PostgreSQL 存储业务数据这三条记忆分别对应“技术栈”“部署偏好”“数据存储选择”是 Agent 在真实项目里最容易丢失的信息类型。6.2 用不同表述方式检索记忆写入后用与原文不同的措辞查询basic-memory search API 文档地址 basic-memory search 数据库选型 basic-memory search 用户对部署方式有什么要求如果语义检索生效即使查询词不是原文完全一致也能召回相关记忆片段。然后使用问答basic-memory ask 用户可以接受什么数据库预期回答会引用被写入的 PostgreSQL 记忆。如果ask没有返回相关内容优先检查检索结果是否正确而不是责怪模型。6.3 验证记忆文件是否可编辑记忆系统的价值在于“可被人类修正”。手动打开 Markdown 文件修改一条记忆的错误内容vi ~/.basic_memory/notes/xxx.md修改后再次搜索检查结果是否更新。注意有些版本会在文件变更后自动重建索引有些版本需要重新执行索引命令。如果你修改了文件但检索结果没有变化大概率是索引没有重建。解决方法是参考版本帮助寻找 rebuild 或 reindex 相关命令。6.4 验证 MCP 集成是否正常在自研 Agent 场景下运行上面的 Python MCP 客户端脚本确认工具列表能被列出。接着在 Agent 的对话中触发一次工具调用观察日志是否有请求和返回记录。完整的验证闭环应该包括数据从命令行写入 Markdown 文件。数据能通过语义检索被找到。数据能通过ask生成回答。数据文件可被人工修改。修改后索引能更新。MCP 工具能被外部 Agent 调用。只有这六步全部通过Basic Memory 才算真正接入到 Agent 工作流中。7. 常见问题排查从现象倒推原因7.1 安装失败或命令找不到现象pip install basic-memory报依赖冲突或安装完成后basic-memory命令不存在。检查顺序which python python --version which pip pip --version如果是命令不存在先检查虚拟环境是否激活source .venv/bin/activate which basic-memory如果输出为空检查安装日志里有没有报错。常见原因是 Python 版本过低、虚拟环境未激活、或者操作系统的 PATH 没有包含 Python 包的 bin 目录。7.2 API Key 配置不生效现象写入或查询时提示 API Key 缺失、401 Unauthorized、或模型服务返回鉴权失败。检查方式env | grep -i anthropic如果环境变量没有输出说明 Key 没导入当前 shell。如果输出有值但程序仍报错需要查看config.json里是否要求填写其他配置项或者是否将 Key 放在了 MCP 配置的env字段而不是全局环境变量中。注意不要把真实 API Key 写进博客或公开代码仓库。在本地测试时优先使用环境变量注入。7.3 检索结果不相关或为空现象已经写入了记忆但search返回空结果或者返回内容与问题无关。处理顺序先确认记忆文件存在ls ~/.basic_memory/notes/。再确认数据库索引存在重新执行索引重建命令。再检查文本分块粒度如果一条笔记太长语义会被稀释可以考虑拆成多个主题更单一的文件。再检查查询表达方式语义检索对问题措辞敏感尽量使用完整问题而不是单个关键词。最后检查 embedding 调用是否成功如果 embedding 生成失败索引可能为空。7.4 MCP 连接失败现象客户端显示 Basic Memory 工具加载失败或 Python MCP 脚本无法初始化会话。排查重点command是否为绝对路径。如果basic-memory不在客户端能捕获的 PATH 里需要写成完整路径。args是否包含mcp。写错参数会导致进程启动后直接退出。是否设置ANTHROPIC_API_KEY环境变量。MCP 子进程继承的环境变量配置错了工具调用也会失败。查看客户端日志通常能看到Failed to initialize或进程退出原因。7.5 常见问题速查表问题现象常见原因检查方式处理建议command not found虚拟环境未激活或 PATH 缺失which basic-memory激活虚拟环境或补全 PATH初始化目录不存在权限不足或路径配置错误ls -la ~/.basic_memory检查父目录权限重新初始化API 鉴权失败Key 未设置或设置错误env | grep ANTHROPIC重新导出 Key检查配置文件检索无结果索引未建立或模型 API 调用失败查看命令执行日志重建索引确认 embedding 调用成功手动改文件后检索不变索引未更新检查是否有 reindex 命令执行索引重建或重新写入MCP 工具加载失败命令路径或环境变量错误查看客户端 MCP 日志把 command 改成绝对路径检查 env8. 最佳实践与扩展方向让长期记忆系统真正可用8.1 记忆内容的结构化设计不要在记忆里只写“用户说喜欢 Rust”。更好的写法是包含主语、属性、时间和背景。示例--- title: 用户技术偏好 type: note tags: - 用户偏好 - 技术栈 created: 2026-01-01T10:00:00 --- 用户在后端开发中偏好 Rust短期内希望继续使用 Rust 构建 API 服务。 项目约束团队已有 Rust 基础设施模块化架构优先。这样的结构在检索时更容易被匹配到也方便人工维护。记忆不是越详细越好而是“关键事实 时间 上下文背景”三者都具备。8.2 写入时机和幂等设计Agent 不应该在每轮对话都写记忆否则记忆库会充满噪音。推荐在以下时机写入用户明确表达了偏好或约束。一个任务完成产生了关键决策和结果。用户在对话中纠正了之前的信息。跨任务复用的状态发生变化。如果你在自研 Agent 中封装写记忆工具还要考虑幂等。例如重复写入同一份项目技术栈时理想表现是更新已有笔记而不是生成多份重复文件。可以在写入前先做一次语义检索如果已有高度相似的内容就更新原文件而不是新增文件。8.3 生产环境使用注意事项本地单用户场景和线上多 Agent 场景对长期记忆系统的要求完全不同。生产环境至少要考虑关注点本地开发生产环境API Key本地环境变量密钥管理服务数据备份手动复制文件定时备份notes和 SQLite 数据库日志终端输出结构化日志记录写入、检索、失败原因权限默认本机限制目录访问避免敏感信息泄露异常处理手动看堆栈捕获 API 超时、索引失败、网络异常版本兼容当前版本验证固定依赖版本升级前测试如果多个 Agent 共享一套记忆库还要设计命名空间或标签体系。不同项目、不同用户的数据不能混在一个大池子里否则检索时会产生严重的串扰。一个简单做法是在 Markdown frontmatter 里增加project或namespace字段并在查询时按元数据过滤。8.4 从 Basic Memory 延伸多 Agent 协同和技能化Basic Memory 适合作为个人 Agent 或小团队的长期记忆层。当项目发展到多 Agent 协同场景时记忆系统的设计通常会有两种演进方向在现有 MCP 工具之上增加路由层让不同 Agent 使用不同命名空间的记忆。把记忆访问封装成“技能开发”的一部分每个 Agent 技能只读取它关心的记忆子集。多 Agent 协同的难点不是“能否共享数据库”而是“如何不让彼此的记忆互相污染”。一个常见做法是把记忆分成全局共享和安全隔离两类全局共享用于项目状态、团队约定隔离数据用于个人偏好、敏感信息。Basic Memory 的 Markdown 文件天然支持这种分层你可以在文件夹层面做权限控制也可以在检索时增加命名空间过滤。8.5 一套可复用的落地清单最后把本文涉及的关键检查点整理成清单适合在项目里直接复用环境检查清单Python 版本满足要求。虚拟环境已激活。basic-memory --help可执行。API Key 已通过环境变量或配置文件注入。初始化清单查看初始化输出中的实际目录。确认config.json、SQLite 数据库、笔记目录存在。手动执行一次add确认 Markdown 文件生成。检索验证清单使用与原文不同表述的查询语句。确认检索结果包含预期记忆。手动修改记忆文件确认索引更新机制。MCP 集成清单MCP 工具列表能看到记忆工具。客户端日志无初始化错误。Agent 实际调用一次记忆工具并得到有效返回。生产上线清单数据和备份定期同步。API Key 不落到仓库。写入记录有日志可查。敏感信息明确隔离。长期记忆不是大模型“打开开关”就能有的能力而是一个需要主动设计的系统。Basic Memory 的取舍在于用可读的 Markdown 和轻量 SQLite 换取了透明性和易维护性非常适合作个人 Agent 和中小项目的记忆层。下一步最值得投入的方向不是继续增加存储维度而是把记忆的写入时机、更新策略、冲突处理和多 Agent 隔离做好。把这些工程细节补齐Agent 才能真正从“总会忘事”变成“越用越懂你”。