ADR-017 — 会话记忆装配策略:分层记忆 + 可替换装配口
触发:M1-C3 用了"只喂最近 6 轮"的硬窗口;owner 指出不能对用户预设"只记 N 轮 / X 时长"的限制,并要求提前考虑长周期 × 多会话累积下的检索效率/准确性,同时明确表示不确定 RAG 是最优方案。本 ADR 锁死框架与工程口子,把"具体检索方法"留作有证据时再选。
§0 决策简述
- 对用户不设记忆上限:永远不向用户暴露/施加"只记 N 轮 / X 天"这类限制。记多少由token 预算 + 相关性在系统内部决定,用户侧体感是"它记得住"。
- 分层记忆(四层配合,非单一方案):
- 近期:最近若干轮原样喂入("若干"由 token 预算决定,非固定轮数)。
- 中期:超预算的旧对话滚动摘要(压成保留金融语义锚点的精炼版——即架构 §11.1 的
Snapshotted/ Context Snapshot 的落地)。 - 长期:真正的长期记忆是结构化资产(判断记录 / 画像,ADR-007),它们是从对话提炼的高信号内容,非原始噪音。
- 大规模按需检索:历史很大时,针对当前问题捞回最相关的若干条补入。
- 工程承诺 = 单一可替换"上下文装配口":把"这次该喂哪些上下文"收口到一个独立模块(ContextAssembler 口)。今天内部实现 = 近期(预算内) + 滚动摘要;将来加检索层 = 只换/扩这个模块,不返工(遵 ADR-014 边界抽取原则)。
- 长期检索的具体方法 = 明确待定,到规模触发点用证据评估再选。RAG(向量语义检索)只是候选之一,不预设为最优(owner 立场)。
§1 检索方法候选(到触发点再评,现在都不锁)
| 候选 | 简述 | 适用 / 风险 |
|---|---|---|
| 向量语义检索(RAG) | 把历史 embed,按语义相似度捞 | 召回"意思相近"的强;但建/维护向量库有成本,且语义相似 ≠ 真相关,可能引噪 |
| 结构化检索 | 直接按 标的/时间/judgment 主键查结构化资产 | 高信号、可解释、零额外基建;前提是关键内容已沉淀成结构化资产(判断记录/画像) |
| 关键词 / BM25 | 传统倒排检索 | 便宜、可解释;对同义/语义弱 |
| 滚动摘要(不检索) | 只压缩、不召回 | 最简单;旧细节会丢,靠摘要保锚点 |
| 长上下文直喂 | 随大模型上下文窗口变大,少检索多直喂 | 模型能力涨则越省事;成本/延迟随长度涨 |
| 混合 | 近期原样 + 摘要 + 结构化资产查 + 可选语义检索 | 大概率终态;复杂度最高,按需拼 |
当前立场:终态很可能是"以结构化资产为长期记忆主干 + 摘要兜中期 + 语义检索仅作补充",但不在现在拍死;到下方触发点用真实数据评。
§2 何时认真选检索方法(防"太晚")
挂靠 ADR-014 的触发器 + 兜底:
- 触发:单用户历史规模 / 多用户上线(ADR-014 T3)/ 检索实测命中率或延迟不达标。
- 硬兜底:ADR-014 已锁"M2 规模化 / 首次多用户部署前强制复审一次"——届时把检索方法连同存储后端一起评估选型。
- 因为 §0.3 的可替换装配口已就位,那时换方法是"插一层",不是重写。
§3 当前里程碑实现(M1,不过度)
- 现在做:① 去掉"6 轮硬限" → 改 token 预算窗口(近期尽量多、不设轮数上限给用户);② 超预算旧对话 → 滚动摘要(落地 §11.1 Snapshotted);③ 把上下文装配抽成可替换模块(检索层的预留口)。
- 现在不做(明确推迟,留口):向量库 / RAG / 任何规模化检索基建——单用户低频下属过度工程。
- 长期记忆里"结构化资产"那条依赖判断存档,按 ADR-016/owner 决定(丙)暂休眠,不阻塞本层。
§4 关联
- 架构 §11.1 Session 生命周期(Active/Snapshotted——本 ADR 的滚动摘要即其落地)/ §15 数据存储。
- ADR-014 语言栈(触发器 + M2 前强制复审,本 ADR 检索选型挂靠它)。
- ADR-007 状态写入两步(结构化资产 = 长期记忆主干候选)。