Llmem:用本地明文文件实现AI编程工具的持久记忆
很多人在用 AI 编程工具时都有一个类似的感受:单次对话里,它非常聪明;一旦关掉窗口隔天再开,它就完全不记得昨天你让它遵循的目录结构、命名规范和业务约束。你反复强调过的东西,它在下一次会话里又全部还给了你。这个问题不是模型变笨了,而是 AI 编码工具长期以来缺少一种可靠的本地持久记忆机制。最近在技术社区看到一个很有意思的项目 Llmem,它的思路和主流做法很不一样:不引入向量数据库,不做 embedding,只靠本地文件把 AI 编码的上下文真正存下来。这篇文章我想聊聊这个项目背后的设计逻辑,以及它对 AI coding 工具链可能带来什么影响。
先说判断:Llmem 并不是一个复杂的系统,但它切中了一个真实痛点——AI 编程工具的上下文没有跨会话的长期记忆,导致开发者反复解释需求、反复纠正低级错误。它用最朴素的“明文文件 + 符号标记”方式,把记忆成本降到极低,同时把“AI 记住什么”的控制权还给开发者。这种设计在当下 AI coding agent 越来越重的趋势下,反而显得清醒且实用。
如果你最近也在用 Cursor、Claude Code 或 Copilot 这类工具,并且被“会话失忆”折磨过,这篇文章值得看完。我会从持久记忆的基本概念讲起,拆解 Llmem 的架构思路,然后给出一套可以直接落地的本地记忆方案,包括代码示例、验证方式和工程建议。看完你至少能回答一个问题:在不需要 embedding 的前提下,AI 编程工具的持久记忆到底能做到什么程度。
1. 为什么“记忆”成了 AI 编码工具的下一个瓶颈
过去两年,AI 编程工具能力的提升主要围绕三个方向:基础模型变强、上下文窗口变大、Agent 能调用的工具变多。但很多开发者发现,真正限制 AI 编码体验的,往往不是某一个模型的单次回答质量,而是它在长时间、多任务、多会话的协作过程中能不能记住关键信息。
举个具体场景:你在一个 Python 后端项目里让 AI 帮忙重构一个模块,你在第一轮对话里明确告诉它“不要改动api/目录下的接口签名”,它确实照做了。但当你继续让它处理第三个、第四个任务,把对话上下文撑得很长之后,它开始“忘记”这个约束,擅自修改了接口字段。更令人头疼的是,你在同一个项目里开了新会话之后,AI 对项目的历史决策、约定和偏好一无所知,你必须把这些背景重新粘贴一遍。
这里真正的问题不是模型的推理能力,而是架构层面的记忆缺失。对话窗口只是短期工作记忆,它承载的信息在会话结束或上下文被截断后就消失了。在 AI coding agent 越来越常见的今天,Agent 需要在一个项目上持续工作几天甚至几周——相当于一个不会下班的协作者——如果它每次启动都是“失忆”状态,那协同效率就会被严重拉低。
行业里不是没有解决方案,常见的做法是把对话历史或项目摘要喂给模型,也就是叫“上下文工程”的技术方向。但很多人误以为只要把更多历史内容拼接到 prompt 里就能解决问题,结果上下文窗口被塞满,模型的理解效率反而下降,费用也上去了。
于是出现了一个新的需求:要不要给 AI 编程工具配一个类似人脑长期记忆的组件?如果配,用什么存储、什么检索、什么更新策略?这个问题的答案,直接决定 AI coding 工具能不能从“单次对话助手”进化为“长期协作 Agent”。
2. 三种 AI 记忆方案对比,为什么 no embeddings 值得关注
站在技术选型的角度,给 AI 编程工具做持久记忆,目前大概有三条路线:纯 Prompt 注入、Embedding 语义检索、结构化明文持久化。理解这三条路线的差异,就能理解 Llmem 为什么选择“no embeddings”。
第一条路线:纯 Prompt 注入
把项目摘要、规则文件、历史决策记录直接拼接到每次请求的 prompt 里。这种方式最简单,但问题很明显:上下文窗口是有上限的。一个中型项目的规则文件可能有几百个条目,全部塞进去既浪费 token 又干扰模型对当前任务的理解。所以它只能承载最核心、最精简的约束,做不到完整记忆。
第二条路线:Embedding 语义检索
这是 RAG 方案的常用形态。把历史记忆切块,交给 embedding 模型转成向量,存到向量数据库里;查询时把用户输入转成向量,做相似度检索,把最相关的记忆片段取出来拼进 prompt。这种方式适合“我不知道自己不知道什么”的场景,比如知识库问答。但用在 AI 编程的记忆场景时,有一个结构性矛盾:语义相似不等于上下文相关。模型算出“当前的报错信息”和“上个月的某段代码注释”向量距离很近,但它未必知道这段注释对应的模块已经废弃了。
另外,embedding 和向量数据库引入的复杂度是实打实的。你至少要多维护一个 embedding 服务或模型、一个向量索引、一套数据同步机制。对一个只想让 AI “记住项目约定”的场景来说,这个成本偏重。
第三条路线:结构化明文持久化
用文件存储记忆,每一条记忆有明确的键、类型、内容和作用域;读取时按规则加载,不依赖模糊匹配。Llmem 走的就是这条路线。它的核心观点是:编程场景里的记忆,大部分不是“模糊联想”,而是“精确引用”。你要让 AI 记住项目的 Python 版本、测试命令、目录规范、某个库的选择原因,这些根本不需要语义检索,只需要一个可靠的、可检索的本地存储。
我比较认同这个判断。编程记忆和通用知识问答不同,它更像是团队里的“项目 Wiki”或“架构决策记录(ADR)”,重要的是结构、权责和时效性,而不是语义相关性。Llmem 用本地明文文件解决“会话失忆”问题,本质上是在构建一个 AI 可读的项目记忆库,而不是做一个迷你搜索引擎。
3. 本地持久记忆的工作机制与使用边界
在深入代码之前,有必要先理清一个概念:Llmem 所说的“持久记忆”是指什么。
它指的是一种独立于会话上下文的数据存储,AI 编程工具可以在需要时读取和写入。这种记忆有几个特性:跨会话存在、可被程序解析、可被开发者审计和编辑。它跟模型自身的参数记忆完全不是一回事,后者是训练阶段固化的知识,前者是协作阶段动态产生的项目知识。
Llmem 的设计可以理解为“给 AI 编码助手开了一个记事本”。这个记事本不追求存储海量信息,重点记录的是:你希望 AI 长期遵循的规范、你做出的关键决策、你不想重复解释的背景信息。每条记录都以结构化、明文形式保存,方便直接在编辑器里查看和修改,也方便 AI 工具在合适时机精确加载。
从工作机制上看,本地持久记忆一般分三块:
第一,记忆的写入。开发者或 AI 在完成某个任务后,把关键结论、约束和决策写入记忆文件。写入的时机很重要,最好在任务刚结束时记录,否则过后容易遗漏细节。
第二,记忆的存储。文件按项目维度组织,可以是单个 Markdown 文件、JSON 文件或者一组按主题拆分的文件。Llmem 这样的工具往往会定义一组轻量规则,比如用特定标记标注“必须遵守的规范”和“仅供参考的背景信息”,这样 AI 读取时可以区分优先级。
第三,记忆的读取与注入。新会话开始时,AI 工具先读取记忆文件,把其中高优先级的条目注入到系统提示或初始上下文中。这个过程要克制,不能把整个记忆库都塞进去,而是按当前任务选择加载哪些条目。
这样的设计有一个天然优势:一切都可以被审计。开发者随时可以查看 AI 到底记住了什么,发现偏差可以直接编辑文件,而不是对着黑盒向量库做无头排查。这也是本地明文方案在“信任感”上优于 embedding 方案的地方。
当然,这种方案也有边界。如果项目积累的记忆达到数百条,人工维护和选择加载的成本就会上升;如果任务是开放式的“帮我找一下代码里所有跟支付相关的逻辑”,纯文本结构化记忆不如语义检索高效。所以,把它理解为“编码协作的长期备忘”,比理解为“项目的语义搜索引擎”更准确。
4. 环境准备与安装
既然要动手实践,我们先准备环境。Llmem 这类工具通常是轻量级的 Python CLI 程序,不依赖专门的数据库或服务,因此部署成本很低。下面是一套通用的安装准备过程,版本信息请以实际项目为准,这里重点演示整体思路。
操作系统与运行时
建议在 Linux、macOS 或 Windows WSL 环境中运行。本地持久记忆的核心是文件操作,对操作系统没有特殊要求,但 Unix 风格环境处理文件路径和权限更顺手。
Python 版本建议使用 3.10 及以上,方便使用较新的类型注解和路径操作 API。如果你电脑里同时存在多个 Python 版本,可以提前确认:
python3 --version获取工具代码
Llmem 的安装方式一般是从 Git 仓库获取源码后,用 pip 安装依赖。本示例使用占位符<repository-url>表示项目仓库地址,具体地址可以从项目的开源主页获取。
git clone <repository-url> llmem cd llmem pip install -r requirements.txt如果项目提供打包好的 PyPI 包,也可以用更简洁的方式安装:
pip install llmem验证基础命令
安装完成后,先运行一次帮助命令,确认命令行入口可用:
llmem --help如果输出中包含init、add、query、list这样的子命令,说明工具已经就绪。不同项目可能使用不同的子命令名称,核心能力是一致的。
工作区目录结构规划
本地记忆工具一般会在当前项目里创建一个隐藏目录来保存记忆文件。从设计上看,建议的记忆目录结构像这样:
my-ai-coding-project/ ├── .llmem/ │ ├── memory/ │ │ ├── project.md │ │ ├── coding-style.md │ │ └── decisions/ │ │ └── 2026-08-01-keep-api-stable.md │ └── config.json ├── src/ └── tests/这个结构有几个好处:记忆数据跟项目代码放在一起,天然支持 Git 版本管理;project.md放项目全局信息,coding-style.md放编码规范,decisions/目录按日期记录架构决策。这种拆分让 AI 在读取时只加载相关文件,而不是一上来把所有记忆全部吞下去。
5. 核心流程拆解:从零搭建本地持久记忆
这一步我们把“AI 编码工具的本地持久记忆”按流程走一遍。即使你不准备使用 Llmem 这个具体项目,这套流程也可以迁移到你自己的工具链里,因为关键点在于存储结构和读取逻辑,而不是某个特定命令。
5.1 初始化记忆库
进入项目目录,初始化记忆库。这一步通常会创建.llmem/目录和基础配置文件。
cd my-ai-coding-project llmem init执行后检查目录是否生成:
ls -la .llmem/一个正常的初始化结果应该能看到至少一个配置文件和一个记忆文件夹。如果初始化失败,优先检查当前目录是否有写权限,以及是否已经存在一个旧的.llmem目录。
配置文件config.json的内容可能类似这样:
{ "project_id": "my-ai-coding-project", "memory_dir": ".llmem/memory", "max_tokens_per_inject": 2000, "default_priority": "high" }max_tokens_per_inject控制每次最多向 prompt 注入多少 token 的记忆内容,这是防止上下文被记忆撑爆的关键配置。建议不要设得太大,给当前任务留足空间。
5.2 写入第一条持久记忆
初始化完成后,把项目最重要的约束写进去。这里以“保持 API 签名稳定”为例,这是后端项目里最高频、最容易被 AI 遗忘的约束之一。
llmem add --type rule \ --title "API 签名稳定性" \ --content "修改 api/ 目录下的任何接口签名前,必须先向开发者确认影响范围,不得自行变更字段名或删除参数,除非开发者明确要求。" \ --priority high对应的记忆文件内容可能是这样:
# API 签名稳定性 - 类型: rule - 优先级: high - 创建时间: 2026-08-01 修改 api/ 目录下的任何接口签名前,必须先向开发者确认影响范围,不得自行变更字段名或删除参数,除非开发者明确要求。这里的--type rule表示这是一条“必须遵守的规则”,--priority high表示注入时优先加载。为什么要区分类型?因为 AI 在编码时需要区分“硬性约束”和“背景信息”,如果把两者混在一起,模型可能无法判断哪些是必须执行的指令,哪些只是参考。
5.3 查询与回顾记忆
记忆写入后,需要有能力在需要时取回。Llmem 类的工具通常提供按标题、标签或类型查询的能力。
llmem query --type rule llmem query --keyword "API"查询结果会列出匹配的记忆条目。这一步虽然看起来简单,但在工程上是一个重要设计:它不依赖向量相似度,而是依赖规则匹配和开发者定义的结构化字段。好处是结果可控、可预测,不会出现“查到一堆语义相关但实际无关”的干扰项。
5.4 将记忆注入 AI 编码工具
记忆存储本身不是目的,真正关键的是让 AI 在会话开始时读到这些记忆。这里的实现方式取决于你使用的工具。
如果你在用 Claude Code 这类支持自定义系统提示的终端工具,可以通过脚本把记忆文件拼接到系统提示中:
llmem export --format text --priority high > /tmp/llmem-memory.txt然后在工具的配置文件中指定加载这个文件,或者手动把它粘贴到会话开头。更进阶的做法是写一个一次性初始化脚本,让它在每次启动 AI 编码会话时自动执行:
#!/usr/bin/env bash # 文件路径: scripts/ai-session-start.sh echo "=== 项目记忆注入 ===" llmem export --format text --priority high echo "=== 项目记忆加载完成 ==="这种方式适合手动控制力强的开发者。如果你希望更自动化,可以考虑使用支持 API 的 AI 编码工具,通过 Python 脚本读取记忆文件,再作为上下文发送给模型。
# 文件路径: scripts/load_memory.py # 演示用,实际 API 以你使用的工具为准 import json from pathlib import Path memory_dir = Path(".llmem/memory") context_parts = [] for md_file in memory_dir.rglob("*.md"): content = md_file.read_text(encoding="utf-8") if content.strip(): context_parts.append(content) context = "\n\n".join(context_parts) # 这里只是演示如何把记忆内容组装成后续的 prompt 上下文 # 实际使用时,需要把 context 作为 system prompt 传入你的 AI 编程工具 API print(f"已加载 {len(context_parts)} 个记忆文件,共 {len(context)} 字符")这个脚本的核心价值是演示“如何把记忆文件变成 prompt 的一部分”,而不是绑定某个具体的 API。你可以根据自己的工具链把它改造成合适的形态。
5.5 多 Agent 协同的共享记忆
最近关于 AI coding 的讨论里,多 Agent 协同是一个高频话题。多个 Agent 同时在一个项目里负责不同模块,很容易出现“左手不知道右手在干什么”的问题。Llmem 这类本地持久记忆很适合作为 Agent 之间的共享信息层。
思路是:给每个 Agent 分配一个独立记忆文件或命名空间,同时保留一个公共目录存放跨 Agent 共享的约定。
.llmem/memory/ ├── shared/ │ ├── project.md │ └── conventions.md ├── agent-frontend/ │ └── memory.md └── agent-backend/ └── memory.md每个 Agent 只能读写自己的目录和读取共享目录。这样设计的好处是,共享目录作为“团队共识”存在,Agent 隐私目录存储各自的任务进度,避免上下文互相干扰。公共记忆文件的更新需要通过明确的工具调用,而不是每个 Agent 随意改写,可以减少冲突。
在多 Agent 场景下,文件的版本管理变得非常重要。强烈建议把.llmem/目录纳入 Git 管理,每次记忆更新都会留下提交记录,相当于给 AI 的“长期记忆”做了审计日志。一旦某个记忆条目导致错误行为,可以直接回滚到之前的版本,定位问题也方便很多。
6. 运行结果与效果验证
写完记忆并接入 AI 工具后,怎么确认这套机制真的生效了?这里给一套可执行的验证路径。
第一步,确认记忆文件已生成并且内容完整
cat .llmem/memory/project.md llmem list预期输出中应该能看到刚才写入的“API 签名稳定性”条目,且内容、优先级、创建时间都是正确的。
第二步,确认导出内容可以被正确加载
llmem export --format text --priority high预期输出中应该只包含高优先级的记忆条目,而且格式清晰,能直接作为系统提示的一部分。如果导出结果为空,说明优先级字段或者导出参数设置有误。
第三步,使用真实 AI 编码工具做测试
启动一个新的编码会话,故意提出一个与记忆条目冲突的请求。比如记忆里写的是“不得修改 API 签名”,你就要求 AI 帮忙把一个接口的字段名改掉。观察 AI 的反应:如果它回复“根据项目约定,修改前需要确认影响范围,请确认是否继续”,说明记忆注入生效;如果它直接就改了,说明记忆没有被正确加载。
值得强调的是,这个测试不是多此一举。很多 AI 编码工具的 prompt 组合逻辑很复杂,记忆文件虽然存在,但不一定会被发送给模型。只有用一个反向测试任务实际验证,才能确认记忆链路是通的。
第四步,检查 token 消耗
如果集成了 API 调用,对比开启和关闭记忆注入时的 token 消耗。正常情况下,开启记忆会带来少量额外 token 消耗,但如果增长异常明显(比如从 5% 涨到 50%),说明加载策略不够克制,需要调低max_tokens_per_inject或者缩小注入范围。
7. 常见问题与排查思路
本地持久记忆在工程实践中会遇到一些重复出现的问题,提前知道排查路径能省不少时间。
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| 记忆已写入,但 AI 会话里“看不到” | 记忆未导出或未注入到 prompt | 检查导出命令输出和工具的上下文配置 | 改用初始化脚本自动导出,确认启动时执行 |
| AI 把“背景信息”当成“硬性规则” | 记忆条目类型区分不清楚 | 检查条目的type字段 | 将约束性的内容统一标记为 rule,背景资料单独存放 |
| 记忆注入后上下文被快速占满 | max_tokens_per_inject太大或注入条目过多 | 观察 token 消耗曲线 | 调小注入 token 上限,按类型和标签精确加载 |
| 多个 Agent 同时写入发生覆盖 | 没有隔离 Agent 的记忆目录 | 查看文件修改时间和内容 | 按 Agent 划分独立记忆目录,共享目录只写入共识内容 |
| 记忆文件越来越多,难以维护 | 缺少归类和清理策略 | 查看记忆条目的数量和标签分布 | 定期归档过期决策,删除已不再适用的规则 |
| 记忆内容包含敏感信息,被意外分享 | 明文文件未做访问控制 | 检查目录权限和 Git 提交历史 | 敏感信息单独存放,必要时对内容脱敏,避免写入 token 或密钥 |
这里特别提醒一点:任何本地记忆工具保存的都是明文信息,如果项目涉及敏感内容,务必在写入前做脱敏处理。不要将数据库密码、API 密钥、个人信息直接写进记忆文件,尤其是当项目仓库有可能被分享或公开时。比起“方便”带来的小收益,敏感信息泄露的风险要大得多。
8. 适用场景与方案选型建议
回到一个更实际的问题:你的项目到底适不适合用 Llmem 这种“无 embedding 的本地持久记忆”方案?
我个人认为,下面几类场景非常适合:
第一,中大型业务项目的长期迭代。项目里有一堆业务约定、模块边界、架构决策,你不想每次新开会话都重新解释一遍。那把这些约束写入本地记忆,让 AI 每次自动加载,体验会提升很多。
第二,团队内部使用的 AI 编码规范统一。团队希望通过 AI 工具强制落地某些编码规范,比如“所有对外接口必须包含 OpenAPI 注释”“数据库变更必须先生成迁移脚本”。把这类规范写进共享记忆,相当于给 AI 编码助手制定了一套团队工作手册。
第三,多 Agent 协同开发。多个 Agent 负责不同模块时,公共记忆作为唯一的共识来源,可以大幅减少 Agent 之间的信息不一致。
反过来,如果项目处于快速原型阶段,代码结构每天都在变,那太重的记忆维护反而会成为负担。这种情况下更推荐“大上下文 + 精确摘要”的组合,而不是立刻搭建复杂的记忆体系。另外,如果你的需求是让 AI 在几十万行的老代码库里做开放式的语义搜索,那应该考虑基于 embedding 的 RAG 方案,Llmem 的结构化记忆不是为这个场景设计的。
有一个判断值得反复琢磨:embedding 解决的是“模糊查找”问题,Llmem 解决的是“精确记住”问题。前者适合你不知道自己该问什么的情况,后者适合你明确知道 AI 应该遵守什么的情况。AI 编程的日常,更多时候是后者。
9. 最佳实践与工程建议
把外部记忆作为一种正式的工程组件引入 AI coding 流程,需要一些纪律。以下是几条务实的建议。
建议一:记忆条目要走“写文档”的标准,而不是“随手记”的标准
每一条记忆都应该有明确的类型、适用范围、优先级和时效性。写之前问自己:这条记忆是“必须遵守的规则”,还是“仅供参考的背景信息”?如果是规则,那它是否足够精确到可以编写自动化检查?如果连人都不能准确判断,AI 更无法判断。
建议二:控制注入量,每次对话只加载必要的记忆
把记忆库当成一个冰箱,拿出来什么就放回什么,但别一次把整个冰箱搬上桌。建议按优先级和类型精确加载,比如高优先级规则全量注入,背景信息按需查询。上下文窗口是稀缺资源,要把每一寸留给真正影响本轮任务的语义空间。
建议三:把记忆目录纳入版本控制
.llmem/目录应该跟代码一起提交到 Git。原因有三:一是可以回溯 AI 的记忆变化历史,定位“它为什么突然违反约定”;二是团队协作时,新成员拉取代码的同时也获得了项目记忆;三是防止本地文件误删除导致记忆全丢。提交信息里注明“memory: update API convention”这样的说明,让历史清晰可查。
建议四:定期做记忆“清理”
记忆不是越多越好。项目演进后,过时决策可能变成错误约束。建议每两周或每个迭代周期回顾一次记忆库,删除已经不适用的条目,合并重复的约束。就像代码要重构一样,AI 的记忆库也需要维护。
建议五:敏感信息永远不要进入记忆文件
前面已经提过,这里再强调一次。因为记忆文件是明文且可能被多个 Agent 或团队成员读取,正确的做法是配置环境变量或使用密钥管理服务,让 AI 通过工具调用动态获取,而不是把密钥写死在记忆里。
建议六:先在小范围试点,再推广到整个工作流
初次接入时,别急着把所有项目规范都灌进去。选一个模块、一周时间,验证记忆机制是否真的减少了重复沟通,再逐步扩大范围。引入记忆机制本身也需要“最小可行”的节奏,避免一开始就陷入维护负担。
10. 总结与下一步实践方向
Llmem 这个项目给我的启发不在工具本身,而在于它的技术判断:AI 编程工具的持续进化,不只依赖更强大的模型,也依赖更合理的上下文管理机制。用本地文件、明文格式和结构化标记实现持久记忆,听起来不够“智能”,但在工程场景里,这种确定性、可审计、可控制的设计,往往比黑盒的语义检索更可靠。
如果你正在被 AI 编码工具反复遗忘困扰,可以按这篇文章的思路做一个最小实验:在新项目里初始化一个记忆库,写入两三条核心规则,让 AI 编码导入后跑一个冲突测试。你可能会发现,一个看起来简单的记事本,对 AI 协作体验的提升比想象中大得多。
下一步建议继续了解两个方向:一是上下文工程,理解 token 分配、摘要压缩和优先级策略,这直接决定记忆注入效果;二是多 Agent 协作中的共享状态设计,当多个 Agent 共享一套记忆时,如何保证一致性和可回滚性,这是 AI coding 工具走向深水区后无法回避的问题。Llmem 的清简路线不一定适合所有场景,但它证明了一件事:解决 AI 的记忆问题,不一定要高成本依赖复杂的检索系统,克制的设计同样有效。
