先记住这个答案
向量相似度、关键词和时间衰减分别捕捉语义、字面和时效性。推荐先并行召回:Top-K向量结果与关键词匹配结果取并集;然后对每条记忆计算融合分:融合分 = α·向量分 + β·关键词分 − γ·时间衰减量。α、β、γ需按场景调参,且要防止单一信号独占。关键是用时间衰减控制遗忘速度,而不是让旧记忆永远沉底。
- 分路召回,融合排序更稳
- 时间衰减用于遗忘而非主导
- 无万能权重,需按任务调参
从单信号到融合排序的机制改进
只用向量相似度会丢失精确事实:用户问“订单号12345状态”,向量可能召回语义相近但订单号错误的记录。加入关键词匹配能强行命中约束,但关键词过度依赖字面,忽略“退货”和“退款”等语义关联。因此常用RRF或加权求和,但混合前应明确各信号在召回和精排的角色。
推荐方案是双路召回后做归一化精排:向量检索取前N,关键词检索取前M,并集候选;对候选每条计算分数=w1向量余弦归一化 + w2BM25归一化 − w3*log(1+age_days)。权重通过小规模标注样本或A/B测试确定,其中时间衰减只做惩罚项,避免把热门旧记忆完全排除。
用户偏好变化的工程场景
假设Agent记忆库有用户上周说“喜欢喝美式”,今天说“改喝拿铁”。高频检索时,向量相似度对两条都高,关键词也都能命中“喝”。若不加时间衰减,旧偏好可能被无差别召回,导致推荐错误。若采用时间衰减项如 w3*log(1+age_days),旧记忆的年龄约7天,时间衰减量远大于新记忆,导致其总分下降,排序自然靠后。
实际处理时还依赖写入端:当检测到用户明确修改偏好,应把旧记忆标记为“已替换”而非仅靠衰减。若只用衰减,旧记忆仍可能进入TopK,需在业务层增加冲突判断,即当两条记忆属于同一事实槽位时优先返回时间戳更新的那条。这属于排序之外的硬约束,能减少多数低级错误。
信号失效与调整原则
时间衰减并非对所有记忆都合适。用户长期不变的稳定属性如“母语中文”,若因时间久被降权,可能造成荒谬答复。这类记忆应写入非衰减层或使用超长半衰期。反之,临时状态如“正在找工作”则需较快衰减。若不加区分,统一衰减会破坏事实的稳定性。
关键词和向量各有失效区:关键词对拼写错误、口语化表达完全失效,向量对精确数字、近期新词可能混淆。调整原则是引入老化策略时先按记忆语义类型分组,每组设定不同权重;同时在评估阶段分别测量三类信号对最终检索质量的影响,若去掉某信号后效果不变则说明其权重冗余。
容易答错的地方
- 权重越大越优
- 把向量相似度权重调到0.9,以为语义最准,结果精确数字和用户ID经常跑偏。正确做法是权重分配应基于任务类型:专名查询提高关键词,开放问答提高向量。并可用网格搜索或贝叶斯调参确定,而非拍脑袋。
- 所有记忆用同一个时间衰减
- 用户口味变化快,而职业经历变化慢,统一半衰期必然让一边失效。应把记忆按稳定性分类,为每类设置不同衰减速率。实际可用两个通道:长期稳定事实通过摘要写入,短期偏好用事件记录,检索时分开打分。
面试官还会怎么问?
如果两个信号出现冲突,向量说相关但关键词完全不匹配,该信谁?
取决于查询类型。如果是用户历史事实的精确复核(如姓名、编号),关键词不匹配通常意味着错误,应该降低该条排名;如果是开放式问答,语义发散正常,可保留。实践中可设置强制过滤:对包含数字或专名的查询,关键词匹配成为必要条件。
时间衰减的速率如何依据检索日志调优?
分析黄金答案中记忆的年龄分布,若发现近期记忆占比高但偶尔需要旧记忆,可拟合指数衰减系数。另一种方式是记录反馈:对检索结果点击或点赞后作为正样本,优化衰减参数。注意避免以人工标注覆盖真实用户行为分布。
向量相似度和关键词分数量纲不同,怎么归一化?
向量分数通常不满足分布稳定,常用min-max或z-score按批次归一化,但线上需要缓存统计量。另一种方案是不融合原始分数,改用排名分:把每条候选在两个信号中的名次相加,即RRF融合,可避免向量绝对值波动影响。RRF与加权求和各有适用场景,加权求和可调权重更灵活,RRF无需调参更稳健。时间衰减则作为对最终排名的额外惩罚。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。