这道题问的是大规模长期记忆怎么设计存储架构,本质上是在问:当历史数据多到放不进上下文窗口时,你怎么在存储成本和检索效率之间找到平衡。我的思路是分层,但不是简单按冷热分,而是按记忆的用途分三层。
先说工作记忆,也就是最近几轮对话,我直接放 Redis 里,不压缩,原始文本存着,保证上下文连贯。这块访问延迟必须毫秒级,因为用户等着回复。再一个是情节记忆,就是历史会话片段,我放 [[Vector Database]] 里,比如 Milvus 或 Pinecone。这里有个边界划分:如果只是关键词匹配,用倒排索引就够了;但要做语义理解,就得靠向量。实际落地我倾向于两者结合,就是 [[Hybrid Search]],同一段记忆同时走向量相似度和关键词,三路召回再精排。
具体到实现,我会给每段记忆加上元数据,比如时间、主题、情感标签,检索时先用这些过滤掉大部分无关数据,再在剩下的里面做向量检索。这样能避免全库扫描。举个例子,客服系统里用户查退款进度,我先按用户 ID 和时间范围缩小候选集,再通过向量找语义相似的退款流程片段,召回率比纯向量高很多。
然后是语义记忆,也就是冷数据,比如用户画像、长期偏好,这些我压缩成[[知识图谱]]或者摘要向量存着。这里有个坑:如果直接存原始文本,存储成本会爆炸。所以我会定期用 LLM 生成摘要,只保留关键信息。检索时先查摘要,如果不够再通过链接取原始详情。
检索优化这块,我重点讲两个手段。第一是混合索引,刚才提到了,向量加关键词加时间,三路召回后做一个 [[Rerank]]。第二是分层检索,先用粗量化的向量中心做粗筛,再用原始向量精排。这就像找书先看分类架号,再在架子上找具体书,能省掉很多无效计算。
落地时有个常见失败场景:如果记忆重要性不做动态衰减,一条三年前的旧对话权重还和今天一样,检索结果就会被过时信息污染。所以我会算一个重要性分数,等于初始权重乘以时间衰减因子再乘以访问频次。高频访问的保留完整文本,低频冷数据只留摘要。
另外,写操作我优先更新工作记忆,保证实时性,然后异步刷到向量库。这里有个延伸问题:如果异步刷盘过程中宕机了,怎么保证一致性?我会用写前日志加版本号,重启后重放未完成的写操作。
最后说我的取舍。我更倾向先按时间和主题做物理分片,把记忆分到不同分区,查询时并行检索近期记忆用精确匹配,远期记忆用模糊匹配,合并排序后截断送入上下文。这样既控制延迟,又保证质量。如果一开始就追求全量精确检索,系统很容易撑不住,上线后会发现召回延迟飙升。所以我的建议是:从物理分片开始,再逐步加混合索引,别一上来就上最复杂的方案。