跨会话长期记忆:上游(acp-kernel)提案
给 acp-kernel / billion-context-pi 作者的方案稿。想法来自 billion-context-dsh 的 P1-4 缺口:会话内压缩我们做得很好了,但会话结束即失忆——跨会话记忆这块,希望 kernel 来拥有(算法归 kernel,宿主只做集成)。
一、问题
ACP 解决的是"一个会话内上下文无限膨胀"。但它不解决"下一个会话不知道上个会话发生了什么":
- 今天聊定的设计决策、踩的坑、用户偏好,明天开新会话全没了
- 业界(mem0 / Letta / Claude Code Auto Memory / Cline Memory Bank)都有跨会话记忆,但都独立于压缩体系
核心认知:每次压缩生成的块(如 tier-1 块 b1)本身就是适合长期存储的内容——压缩把已消费对话提炼成精炼摘要,这个摘要天然就是长期记忆的候选。所以跨会话记忆不该是另起炉灶的独立系统,而应该是压缩体系的自然延伸:记忆沉淀复用压缩产物,模型决定哪些块/内容值得沉淀(不搞引擎自动归档——沉淀决策始终是模型自决)。
一句话:把"跨会话记忆"和"压缩"做成同一套机制的两面——压缩是会话内折叠,记忆是跨会话沉淀;都复用 kernel 的蒸馏/ref/搜索基础设施。
二、核心机制:nudge 表态 + fork 提取(模型自决写入)
当模型判断"这段有值得跨会话记住的内容"(无论是对话内容,还是某个压缩块 b1 的摘要值得沉淀)时:
nudge 触发(kernel 已有)
→ 模型回顾上下文(本来就在做)
→ 模型判断:这段有值得跨会话记住的吗?
有 → 调用轻量工具 memory_commit(type, note) 【纯表态,不写内容】
→ 引擎 fork 一个同模型子对话(同文本 + 一句指令"提取当前需要的记忆,重点:{note}")
→ fork 会话最后:模型用 memory_write 把提炼结果写入记忆库
→ fork 使命结束(可归档/删除),主对话继续压缩
三个工具,权限分离:
| 工具 |
谁可见 |
干什么 |
memory_commit(type, note) |
主对话 |
表态"这段值得记"(type 枚举 + note 聚焦提示);不写内容 |
memory_recall(query) |
主对话 |
读回:检索记忆库取全文(见 §三) |
memory_write(content) |
仅 fork 会话 |
真正写记忆库;主对话物理上无写权限 |
主对话只有"请求写"的能力、没有"写"的能力——写记忆库只能通过 fork 会话的 memory_write 完成,权限天然隔离(fork = 带 memory_write 工具定义的一次性 LLM 调用,宿主把工具输出落库)。这比"fork 直接落文件"更符合工具面架构,也让三工具语义进 kernel 接口定义。
为什么这样设计:
- 时机是现成的——nudge 时模型正在做全局回顾,对"这段讲了什么、什么值得留"认知最佳(比 Claude Code 的"每轮结束自动提取"更省,比 mem0 的"应用层另起 LLM"更模型自决)
- 决策与执行分离——模型只做轻量"要不要记"的判断(一次工具调用,note 是聚焦提示),繁重的提炼下放给 fork(不打断主对话、不占主对话上下文)
- fork 缓存命中——同模型同文本(+一句指令),prompt cache 共享
三、读回:常驻索引 + 自主取回(两时机,不搞多层)
时机① 常驻索引:记忆库目录(一句话/条 + 类型 + 上次读取时间)注入 system prompt,每次 turn 都在
→ 模型"知道有什么"(存在性提示,解决"想不起来去翻")
时机② 自主取回:模型看到相关条目 → 调 memory_recall(query) 取全文
→ 细节按需取,不一股脑全塞
这正好是 Claude Code 生产实践的形态(MEMORY.md 常驻 + FileRead 取全文),两大主流系统(Claude Code / Letta)独立收敛到同一形态,不是我们发明。
四、选择与衰减:一个公式两用
问题:纯"被读频率"优先 → 富者愈富(被读 → 频率升 → 优先被读 → 更被读;没被读的永远不见天日)。
机制(字段全是记忆条目自带的,不需要 embedding/向量):
score = importance + min(距上次读取天数 / 30, 5) + uniform(0, 0.5)
importance(1-10):模型 memory_commit 表态时顺带评分(一次性评估,Generative Agents 做法)
anti-recency:越久没被读优先级越高——刚读过的降权让位,把正反馈变负反馈
random jitter:随机打破"永远同一批"的锁定
- top-N = 5(对齐 Claude 5-slot);会话累计 surfacing 上限对齐 Claude 60KB
这一个公式同时是"可见性调度"和"保质期":不被读的记忆不是消失,而是权重回升等机会——Ebbinghaus 遗忘曲线反过来用,一个机制两用。
五、记忆条目 = kernel 的 tier-3 蒸馏块(不造新格式)
- 记忆条目数据模型直接复用 kernel 分层蒸馏产物(Agentic Memory 论文明确:tier-1/2/3 蒸馏 ≡ short→long 迁移,tier-3 超浓缩就是天然长期记忆条目)
- 检索复用 kernel
searchBlocks hybrid 基础设施(扩展一个记忆库文档源即可)
- 记忆库本身 = 人类可读 markdown 目录(人能看能改 = 外部纠错通道)+ 每条带 citation(来源会话+seq,延续可回溯哲学)
六、kernel 要做什么(A 类)/ 宿主要做什么(B 类)
| 归 kernel(上游实现) |
归宿主(DSH 集成) |
memory_commit 的决策时机挂钩(nudge 文案加记忆引导) |
工具注册(DSH 工具面) |
| fork/一次性 LLM 提取的接口定义 |
实际 LLM 调用(宿主运行时) |
| 记忆条目数据模型(= tier-3 蒸馏块扩展) |
markdown 文件存储 + citation(seq 方言) |
| score 选择机制 + Ebbinghaus 衰减 |
常驻索引注入 system prompt |
memory_recall 检索(searchBlocks 扩展) |
/acp memory list 命令 |
|
nudge → memory_commit 的时机接线 |
实施顺序:kernel 先行,宿主后随——kernel 发布记忆能力后,宿主 bump kernel 并全部调 kernel API(符合我们既有的"缺陷走 upstream、不在宿主 patch kernel"约定)。
七、一句话
把"跨会话记忆"做成压缩体系的自然延伸:nudge 时模型表态 → fork 提取 → 记忆库 = tier-3 蒸馏块 + 人类可读 markdown;读回 = 常驻索引 + 自主取回;选择/衰减 = importance + 反新鲜度 + 随机,一个公式两用。算法归 kernel,宿主只做集成。
附:完整设计文档与调研
希望 kernel 拥有的能力面(§六 A 类): 记忆条目数据模型(= tier-3 蒸馏块扩展)、score 选择 + Ebbinghaus 衰减、memory_recall 检索(searchBlocks 扩展)、nudge 文案记忆引导、三工具接口语义(commit/recall/write, write 仅 fork)。宿主侧只做 DSH 集成(B 类)。实施顺序: kernel 先行, 宿主后随。
跨会话长期记忆:上游(acp-kernel)提案
一、问题
ACP 解决的是"一个会话内上下文无限膨胀"。但它不解决"下一个会话不知道上个会话发生了什么":
核心认知:每次压缩生成的块(如 tier-1 块 b1)本身就是适合长期存储的内容——压缩把已消费对话提炼成精炼摘要,这个摘要天然就是长期记忆的候选。所以跨会话记忆不该是另起炉灶的独立系统,而应该是压缩体系的自然延伸:记忆沉淀复用压缩产物,模型决定哪些块/内容值得沉淀(不搞引擎自动归档——沉淀决策始终是模型自决)。
一句话:把"跨会话记忆"和"压缩"做成同一套机制的两面——压缩是会话内折叠,记忆是跨会话沉淀;都复用 kernel 的蒸馏/ref/搜索基础设施。
二、核心机制:nudge 表态 + fork 提取(模型自决写入)
当模型判断"这段有值得跨会话记住的内容"(无论是对话内容,还是某个压缩块 b1 的摘要值得沉淀)时:
三个工具,权限分离:
memory_commit(type, note)memory_recall(query)memory_write(content)主对话只有"请求写"的能力、没有"写"的能力——写记忆库只能通过 fork 会话的 memory_write 完成,权限天然隔离(fork = 带 memory_write 工具定义的一次性 LLM 调用,宿主把工具输出落库)。这比"fork 直接落文件"更符合工具面架构,也让三工具语义进 kernel 接口定义。
为什么这样设计:
三、读回:常驻索引 + 自主取回(两时机,不搞多层)
这正好是 Claude Code 生产实践的形态(MEMORY.md 常驻 + FileRead 取全文),两大主流系统(Claude Code / Letta)独立收敛到同一形态,不是我们发明。
四、选择与衰减:一个公式两用
问题:纯"被读频率"优先 → 富者愈富(被读 → 频率升 → 优先被读 → 更被读;没被读的永远不见天日)。
机制(字段全是记忆条目自带的,不需要 embedding/向量):
importance(1-10):模型 memory_commit 表态时顺带评分(一次性评估,Generative Agents 做法)anti-recency:越久没被读优先级越高——刚读过的降权让位,把正反馈变负反馈random jitter:随机打破"永远同一批"的锁定这一个公式同时是"可见性调度"和"保质期":不被读的记忆不是消失,而是权重回升等机会——Ebbinghaus 遗忘曲线反过来用,一个机制两用。
五、记忆条目 = kernel 的 tier-3 蒸馏块(不造新格式)
searchBlockshybrid 基础设施(扩展一个记忆库文档源即可)六、kernel 要做什么(A 类)/ 宿主要做什么(B 类)
memory_commit的决策时机挂钩(nudge 文案加记忆引导)memory_recall检索(searchBlocks 扩展)/acp memory list命令实施顺序:kernel 先行,宿主后随——kernel 发布记忆能力后,宿主 bump kernel 并全部调 kernel API(符合我们既有的"缺陷走 upstream、不在宿主 patch kernel"约定)。
七、一句话
附:完整设计文档与调研
希望 kernel 拥有的能力面(§六 A 类): 记忆条目数据模型(= tier-3 蒸馏块扩展)、score 选择 + Ebbinghaus 衰减、memory_recall 检索(searchBlocks 扩展)、nudge 文案记忆引导、三工具接口语义(commit/recall/write, write 仅 fork)。宿主侧只做 DSH 集成(B 类)。实施顺序: kernel 先行, 宿主后随。