Lossless-Memory:一个无需摘要的个人 AI 长期记忆层
TL;DR
Lossless-Memory 将 AI 与人类的每一次对话逐字记录并附带时间戳,优先按时间进行索引,并将一个微小的“我们现在在哪里”索引注入到模型的上下文中,从而为单机单用户提供无损的回溯能力。
项目简介
Lossless-Memory 是一个用于个人 AI 助手的本地、基于文件的长期记忆层。它包含:
- 原始 JSONL 日志(每天一个):包含每次对话的七字段记录,从不进行摘要。
- SQLite 索引:一个精确匹配的 FTS5 索引,用于存储单词及对应的时间戳,以及一个用于语义搜索的备用向量索引(sqlite-vec)。
- 时间主干(Temporal Backbone):一个查询解析器,用于提取时间表达式(日语相对短语或绝对日期),并在进行任何排序之前限制搜索范围。
- LLL 索引:一个由人工编写的微小主题标记列表,在每次对话时注入到模型上下文中,以保留当前的对话线程。
该系统特意设计为单用户、单机模式,并不作为通用的向量数据库包装器或摘要工具使用。
核心设计支柱
1. 无损原始日志
每次对话都会追加到每日 JSONL 文件中,包含以下字段:
ts ISO-8601 UTC 时间戳
actor 发言者标识符
role user | assistant | system
type text | action | meta
text 逐字内容
model 模型标识符(可选)
session 会话 ID
这些日志是事实来源;所有索引都可以从它们中重建。
2. 时间主干
时间是主要轴线,而不仅仅是元数据:
- FTS5 索引在每一行中存储时间戳。
- 解析器能够理解日语相对短语(例如“昨日”、“先週”)以及任何绝对 ISO 日期,并在排序之前将其转换为具体的时间范围。
- 如果存在时间短语,结果将限制在该范围内并按时间顺序返回。仅当精确索引返回的结果过少时才会使用语义搜索,且其使用情况会明确报告。
这使得诸如“上周二晚上我们决定了什么?”之类的查询能够按顺序返回当晚所说的确切内容。
3. LLL —— “我们现在在哪里”索引
LLL 是一个轻量级主题标记索引,由人类在对话主题转换时编写的简短、带时间戳的行组成。模型会读取此索引但从不编辑它,确保 AI 即使在上下文窗口压缩后也能始终了解当前线程。
架构图
原始对话日志 (JSONL, 每日) ← 事实来源,从不摘要
│
▼
摄入 ──► 7 字段记录
│
├──► index_exact SQLite FTS5 + 时间戳 (单词 + 时间)
├──► index_vector sqlite-vec 嵌入 (含义,最后手段)
└──► state_index LLL 主题标记 (我们现在在哪里)
│
▼
回溯 ── 单一入口:解析时间短语 → 限制范围 → 排序 → 返回逐字行
│
▼
注入到模型上下文中 (按需,或对于 LLL 每次对话都注入)
守护进程每 10 分钟进行一次增量重新索引;仅处理修改过的每日文件,因此无需完全重建。
实际性能数据
| 指标 | 数值 |
|---|---|
| 日常运行 | 自 2026 年 7 月起运行(日志始于 2026 年 6 月) |
| 精确搜索索引重建(重构前后) | 40 s → 1.24 s |
| 向量索引行数(最坏情况) | 865,588 行(2026 年 9 月 4 日) → 修复后 124,174 行 |
| 向量存储大小 | 2.54 GB → 337 MB |
| 重新索引间隔 | 10 分钟 |
这些数据来自作者的单用户部署,展示了重构的实际影响。
为什么选择无损方案?
作者构建此系统是为了服务于一位每天与 AI 助手交谈并经历过因摘要导致逐渐遗忘的用户。摘要会丢弃确切的措辞、语气和时间戳——这些元素使记忆变得个性化。通过拒绝摘要,系统在牺牲额外磁盘空间和需要稳健时间索引的前提下,保留了完整的对话质感。其目标是打造一个像人类一样记住你的伙伴,且完全运行在你拥有的硬件上。
局限性与待解决问题
- 单用户、单机 —— 不支持多租户。
- 日语优先的时间解析 —— 相对时间短语仅在日语中有效;英语用户必须提供绝对 ISO 日期。
- 日志格式 —— 针对 Claude Code 的 JSONL 进行了优化;存在一个通用的
{ts, role, text}导入器,但经过的实战测试较少。 - 无公开基准测试 —— 所提供的数据是操作测量值,而非对比性能数据。
- 语义搜索依赖于本地嵌入模型 (sentence-transformers);GPU 加速为可选。
社区反馈(Hacker News 评论)
“看起来是一种巧妙的信息检索方法。时间/版本化的编年史绝对有用。” – alansaber
“这与 https://github.com/obra/episodic-memory 有什么不同?” – schainks
“相对时间解析器是针对日语硬编码的;英语会话只能使用手动 ISO 日期。接入 dateparser 或 duckling 只需一个晚上,所以将其留在路线图中是一个奇怪的选择。” – TimByte
“起初看起来很有用,但最终你会遇到瓶颈,导致它无法工作,你必须添加另一种记忆技术。最终你会得到一个复杂的多层系统,因为人们想要的‘记忆’实际上是 10 种不同的东西,每种都需要自己的解决方案。” – 0xbadcafebee
“看起来这会经常破坏缓存。这会增加某些提供商的账单费率,对于本地模型,生成响应也需要时间,特别是在长时间运行的代理会话中。” – theresLand
这些评论既强调了对时间维度的热情,也表达了对语言支持、可扩展性以及与现有缓存或记忆框架集成的担忧。
入门指南
git clone https://github.com/aru-labs/lossless-memory
cd lossless-memory
pip install -e .
cp config.example.json config.json # 根据需要编辑名称和路径
按照 examples/quickstart.md 指南摄入示例对话、构建索引并运行时间范围查询(约 5 分钟)。pytest 往返测试验证了整个流水线。
文档与进一步阅读
| 文档 | 范围 |
|---|---|
docs/memory-system.md |
概念与规范 |
docs/temporal-backbone.md |
时间优先索引与短语解析 |
docs/lll.md |
主题标记索引与人/AI 职责 |
docs/philosophy.md |
避免摘要的理由 |
docs/lessons.md |
失败、修复与性能数据 |
docs/ja/ |
日语原文 |
许可证
MIT License (c) 2026 Aru & Cece.
Sources
相关
- 项目
- 项目
- 项目
- 项目
- 项目