内容提要
ai-memory 是一个用 Rust 编写的 agent 记忆层,通过 MCP 和生命周期钩子为 CLI 工具提供共享长期记忆,以 git 版本化的 markdown 树和 SQLite 索引存储。其核心是十五条设计不变量,每条都基于实际 issue 教训,强调磁盘为真相源、单写者、类型化隐私边界等。项目还包含四路融合检索、记忆衰减机制和严格的安全措施,避免常见架构陷阱。
延伸解读
设计不变量:从事故报告到编译期约束
ai-memory 的十五条设计不变量并非抽象的最佳实践,而是从其他项目的具体 issue 中提炼出的教训。例如,配置只读一次、单写者 SQLite actor、钩子超时 200ms 等,每条都对应着 agentmemory、cognee 或 basic-memory 的真实事故。这种将事故报告转化为强制约束的做法,比泛泛而谈的架构原则更可执行,也更容易在评审中引用和验证。
markdown 为真相源的代价与补偿
选择 markdown 树作为真相源,换来了备份迁移简单、工具可直接读取等好处,但也意味着文件系统与 SQLite 之间没有真正的跨资源事务。项目通过约束所有写入必须经过特定函数、尽力回滚和重新索引来补偿。这种权衡在文档中坦白说明,提醒接入方注意 at-least-once 语义,避免在崩溃场景下产生误解。
检索与衰减:平衡相关性与时效
四路融合检索(全文、实体、链接、向量)结合 RRF 融合,并引入有界权威乘子,在势均力敌时优先规则、决策等权威内容,但不隐藏情节证据。记忆衰减机制通过保留分公式平衡热度和时效,区分不同操作者的强化,避免单一用户重复访问造成偏差。这些设计让记忆既相关又不过时。
安全与隐私:类型化边界与提示注入防御
项目将隐私剥离实现为类型化边界,Sanitized<NewObservation> 只能通过 sanitize() 构造,从类型层面杜绝绕过脱敏。同时,所有 LLM 提示中的仓库文本、观测等均视为不可信数据,并显式添加信任边界。自动改进的提案默认自动批准,但可开启 require_approval 或配置评估门,防止模型输出被当作指令执行。
Q&A
ai-memory 是什么?它主要解决什么问题?
ai-memory 是一个用 Rust 编写的 agent 记忆层,通过 MCP 和生命周期钩子为 CLI 工具(如 Claude Code、Codex)提供共享的长期记忆。它解决的是多个编码 agent 切换时上下文丢失的问题,让记忆在会话之间持久化,无需手动复制粘贴总结。
ai-memory 如何存储记忆?为什么选择 markdown 作为真相源?
ai-memory 将记忆存储为 git 版本化的 markdown 树,并用 SQLite 索引进行检索。选择 markdown 作为真相源的原因包括:备份和迁移简单(git clone 或 rsync)、支持在 Obsidian 中直接查看、数据库可从文件重建(损坏可恢复)、任何能读 markdown 的工具都可用。代价是文件系统与 SQLite 之间没有跨资源事务,一致性靠约束入口保证。
ai-memory 的检索机制是怎样的?
ai-memory 的检索是四路融合:FTS5 全文、实体匹配、链接邻居、向量余弦(如果配置了嵌入器)。四路结果用 RRF 融合,之后有一个有界的权威乘子,根据页面种类、tier、pinned 和内置标签调整相关性。命中会回写访问计数和最后访问时间,用于衰减公式。
ai-memory 如何处理记忆过期?
ai-memory 将记忆分为四个 tier:工作记忆(会话结束丢弃)、情节记忆(30天热、180天冷,按分数驱逐)、语义与流程记忆(无限期,只能被新版本取代)。保留分计算公式包含 salience、时间衰减、访问次数和操作者多样性。清扫分三段:硬删过期页面、驱逐低分页面并留墓碑、最终清除墓碑。pinned 页面豁免衰减。
ai-memory 如何防止提示注入?
ai-memory 将仓库文本、观测、wiki 页面和既往提案都视为不可信数据,而非指令。自动注入的 handoff、项目简报等也使用显式信任边界和分隔符。自动改进链上还有第二道闸:模型提出的修改先进待审轨迹,可开启 require_approval 或配置可执行评估门。
ai-memory 的十五条不变量是什么?它们有什么特点?
十五条不变量是项目必须遵守的约束,每条都基于实际 issue 教训,例如:配置只有一条读取路径、单写者 SQLite actor、索引与数据同事务提交、钩子发射后不管(超时≤200ms)、隐私剥离是类型化边界、只用 JSON schema 结构化输出等。它们的特点是每条都关联具体 issue,是事故报告转成的约束,评审时必须引用出处。
ai-memory 的代码结构是怎样的?有哪些主要 crate?
ai-memory 由十个 crate 组成:ai-memory-core(词汇表、隐私剥离)、ai-memory-store(SQLite 存储)、ai-memory-wiki(markdown 管理)、ai-memory-hooks(钩子入口)、ai-memory-llm(LLM 客户端)、ai-memory-consolidate(编译流水线)、ai-memory-mcp(MCP 服务器)、ai-memory-web(只读 HTTP 界面)、ai-memory-workstream(原生 harness 适配器)、ai-memory-cli(二进制入口)。
ai-memory 为什么不用 Postgres 或 LanceDB 等数据库?
ai-memory 不用 Postgres 是因为 cognee #2717 和 basic-memory #830/#831 显示它在真实部署中才暴露问题;不用 LanceDB 是因为文件格式漂移和过滤下推失败;不用 Kuzu 是因为上游归档;不用 CozoDB 是因为巴士系数太小;不用 SurrealDB 是因为表面积太大。它选择用 SQLite 表存储图数据,图查询用递归 CTE。