跳到正文

AGENT PROJECT INTERVIEW · Q17 / 25

Agent 从海量记忆里怎么找对内容?相关性、时间性和重要性怎样组合

拆解 Agent 记忆从权限过滤、混合召回到相关性、时间性、重要性重排的完整链路,并覆盖冲突、遗忘和评估。

作者与复核:吴师兄内容依据:公开 Agent 教程、项目题资料与工程推导查看关联教程 →查看吴师兄公开作品 →

25 道题目Q17
本页内容20 节

30 秒先说结论

Agent 记忆检索先按用户、租户、项目、类型、有效状态、权限和时间做硬过滤,再结合结构化查询、关键词和向量生成候选,最后用语义相关性、作用域、时间性、重要性、来源与条件匹配重排。冲突不能静默取最高分,过期和无权记录不得入选,也必须允许无记忆结果。

面试官可能会问:“长期记忆已经存了很多条,为什么不能直接向量检索 TopK?”

因为“语义相似”只回答文本像不像,不回答这条记忆属于谁、当前 Agent 有没有权限、信息是否还有效、来源是否可信、是不是被新版本替代,以及它对当前任务到底有多重要。

用户今天问“帮我继续上次的 RAG 评测”,向量库可能召回一个月前的项目目标,也可能召回另一个项目里措辞相似的评测记录。旧目标语义很像,但当前阶段已经变化;另一个项目更像,却属于错误作用域。若系统只取相似度最高的几条,记忆越多,污染当前决策的机会反而越大。

这道题要回答的是一条检索与排序链路:先识别查询意图和主体,做权限、租户、类型、状态、时间与项目范围过滤,再生成语义候选,结合相关性、时间性、重要性、来源和条件匹配重排,最后去重、处理冲突、控制注入预算,并允许“没有任何记忆值得使用”。

先给出 30 秒回答

Agent 记忆检索不能只做向量 TopK。我会先根据当前任务构造检索意图,并用用户、租户、项目、记忆类型、有效状态、权限和时间范围做硬过滤;再对剩余候选计算语义相关性,并结合时间性、业务重要性、来源可信度、条件匹配和使用反馈做重排。不同类型的记忆使用不同权重和时效规则,当前用户明确输入与实时工具事实始终高于历史记忆。冲突条目不能静默选一条,而要成组裁决或请求确认;过期、被替代和无权限条目不得进入排序。最后限制条数和 Token,保留来源与时间注入上下文,并用正例、难负例、冲突和不应召回样本评估。

这段话的关键不是给出一个万能公式,而是把硬约束与软排序分开。

Agent 记忆检索与重排流程

先排除不能用的记忆,再在可用候选里判断哪条更值得进入上下文。

第一步:先理解当前任务要找什么

用户输入不一定能直接作为向量查询。

“继续做昨天那个方案”包含指代,需要先从当前会话确定“那个方案”可能对应的项目和任务阶段。“还是按以前的风格写”需要检索表达偏好,而不是搜索所有历史文章。“上次为什么失败”更需要事件与失败记录,不是用户画像。

检索器可以从当前 State 提取几个结构化字段:主体是谁、任务或项目是什么、需要的记忆类型、时间范围、实体与关键词、当前目标、必须遵守的权限和预算。模型可以帮助解析自然语言,但主体、租户、权限和项目标识应来自可信上下文,不能由模型猜。

查询改写也要保留原始问题。若改写错误,Trace 需要看见模型怎样把“昨天的方案”解析成某个项目。只有记录查询意图、过滤条件和候选变化,才能判断漏召回发生在理解、过滤、向量召回还是重排。

一个任务可能需要多路检索。用户偏好走结构化属性查询,历史任务摘要走语义检索,最近事件走时间范围查询,实体关系走精确键或图关系。不要强迫所有记忆都经过同一条向量查询。

硬过滤为什么必须在相似度之前

权限、主体和有效状态不是“加一点惩罚分”就能解决的软条件。

如果候选不属于当前用户或租户,它无论多相似都不能被使用。如果记录已经撤回、删除或被新版本替代,它也不能因为分数高再次出现。如果当前 Agent 没有读取某类敏感记忆的角色权限,排序模型不应该见到它的正文。

硬过滤通常包含:租户与用户、共享范围、项目或工作区、角色与 Agent 能力、记忆类型、active 状态、版本、有效时间、数据用途和敏感等级。具体字段按产品定义,但原则是越权与失效数据在候选生成前就排除。

有些向量数据库支持元数据过滤,也仍需在结果回到主存储后复查权限、版本和状态。索引可能同步延迟,旧向量仍在。主记录是当前有效性的依据,不能把索引副本当最终事实源。

这也解释了为什么记忆写入必须保存来源、主体、权限、时间和版本。写入时只存一段文本,检索时就没有可靠字段做硬过滤。

相关性不是只有一个向量分数

语义向量擅长找表达不同但含义接近的内容。例如用户问“回答别太啰嗦”,可以找到“偏好简洁表达”。但相关性至少还包含实体、任务阶段和条件是否一致。

“RAG 评测集怎么构建”和“Agent 评测集怎么构建”语义接近,项目对象不同。某条记忆说“发布前先人工确认”,如果只适用于外部公众号发布,就不该自动约束本地草稿预览。文本相似度看不见这些作用域。

更稳的相关性可以由多种信号组成:向量语义、关键词或实体匹配、项目和阶段匹配、记忆类型匹配、条件满足程度、与当前计划步骤的关联。结构化条件可以先过滤或作为强特征,不要全部压成自然语言交给 Embedding。

混合检索不是为了堆算法,而是弥补单一检索的盲区。精确标识、专有名词和版本号适合关键词或结构化查询,模糊表达与同义改写适合向量。合并后再去重和重排。

时间性怎样计算才不会误伤长期事实

越新的记忆不一定越正确,越旧的记忆也不一定过期。

昨天的会议安排可能今天已经无效,多年前确认的语言偏好仍可能有效。统一按创建时间衰减,会让稳定身份或长期规则被短期噪音挤掉。

时间性至少要区分创建时间、最后确认时间、有效时间、最后使用时间和事件发生时间。对临时任务、事件和阶段目标,可以设置较强时间窗口;对用户确认的稳定偏好,时间更多用于触发复核而非直接降到不可用;对实时业务状态则不应依赖记忆,使用时重新查询权威系统。

过期判断优先使用明确的 expires_at、被替代状态或业务规则。软时间衰减只参与同类有效候选的排序。不能把“时间久”当作删除理由,也不能因为“刚写入”就越过来源可信度。

如果用户当前明确更新了偏好,新版本应通过版本关系使旧版本退出普通候选,而不是让两条通过时间分数竞争。

重要性不应完全交给模型打分

重要性回答的是“这条信息对未来任务造成多大影响”,但模型给出的重要分数很容易受措辞影响。

用户明确要求保存、影响安全或审批、决定任务硬约束、频繁跨会话复用的信息,通常比一次闲聊更重要。这个判断应结合记忆类型、用户动作、业务规则和使用场景。模型可以提供建议,不能让一句夸张表达自动获得最高优先级。

重要性还与当前任务有关。一个长期偏好对写作任务很重要,对数据库迁移可能无关。可以把全局重要性与查询相关性分开,避免高重要记录在所有任务里反复出现。

系统不必永久保存一个静态 importance 数值。随着用户撤回、规则变化、长期未使用或验证失败,它需要复核。重要性影响排序和保留策略,但不能覆盖权限、状态与当前明确指令。

在没有真实标注和线上结果前,不要给出固定的相关性、时间性、重要性权重。面试中说“0.6、0.3、0.1”看似具体,面试官会立刻追问这些数怎样得到。更可靠的回答是先说明信号与约束,再通过标注集和消融选择参数。

相关性、时间性与重要性的作用边界

三类信号各自回答不同问题,权限和有效性不参与加权竞争。

一个可解释的排序框架

完成硬过滤后,可以为每个候选计算一组特征,而不是直接输出一个无法解释的分数。

candidate_features = {
  semantic_relevance,
  entity_and_scope_match,
  recency_or_validity,
  task_importance,
  source_authority,
  condition_match,
  prior_usefulness
}

这只是特征示意,不是固定公式。不同记忆类型可以使用不同排序器。用户偏好更看重明确来源与适用条件,事件记忆更看重时间和项目,程序经验更看重验证状态与任务相似性。

排序结果要能解释“为什么入选”和“为什么被挡掉”。Trace 至少记录查询意图、硬过滤数量、候选来源、主要特征、最终名次、被去重或冲突处理的原因。线上答案受错误记忆影响时,团队能定位是索引召回错还是排序规则错。

如果使用模型重排,需要给它候选的来源、时间、类型和适用条件,并限制它只能在已授权候选中选择。模型不能通过重排重新引入过滤掉的内容。

冲突记忆不能简单选分最高的一条

两个候选可能同时相关,却互相矛盾。例如旧记忆说“回答简短”,新记忆说“技术题完整推导”。若版本关系已经明确,旧记录应在硬过滤阶段退出。若两条分别适用于不同场景,排序需要根据当前条件选择。

真正未解决的冲突,应成组进入冲突裁决节点。裁决依据包括当前用户明确输入、来源类型、时间、确认状态和适用条件。无法判断时向用户澄清,或不注入任何一条。

不能让向量分数替代事实权威。语义更像当前问题,不代表内容更正确。实时工具事实与当前用户指令也不应被历史记忆覆盖。

冲突处理结果可以触发记忆更新:确认新偏好后建立替代关系;发现条件差异后补充作用域;确认某条错误后撤回并进入遗忘或删除流程。检索不是只读动作,它也会暴露需要维护的记忆质量问题。

为什么要有“不召回”这个结果

很多系统为了展示 Memory,每轮都强行返回几条历史。这样会把低相关内容塞满上下文,让模型误以为必须使用。

候选全部低相关、冲突未解、权限不足、过期或来源不可信时,正确结果就是空。Agent 应根据当前输入继续,或者询问用户,而不是说“根据你以前的偏好”并编造历史。

可以设最低质量门槛,但门槛需要按标注数据校准,不是拍脑袋。还可以把“无记忆基线”作为对照,观察加入候选是否真正改善任务,还是只是让回答看起来更个性化。

评估必须包含大量不应召回的难负例:不同用户问相似问题,同一用户在不同项目处理同类任务,旧偏好已被修改,措辞相似但实体不同,以及包含敏感内容却无权限的记录。

去重、多样性和上下文预算

前十条候选如果都是同一偏好的不同表述,注入更多并不会增加信息,只会放大它的权重。

重排后需要按规范化事实、来源和语义聚类去重。对于同一事实的多来源,可以保留一个主条目并附来源数量或引用。对于不同方面的记忆,可以做有限多样性选择,避免全部候选只覆盖一个子主题。

注入上下文时限制条数和 Token,并按“当前任务需要”选择粒度。简单偏好用一行结构化信息,历史任务可能只注入摘要与工件引用,必要时再读取详情。不要把完整对话、工具轨迹和向量库原文一次性拼进 Prompt。

每条注入内容应标明这是历史记忆、来源、确认状态和时间。历史信息不能伪装成系统指令。模型需要知道它可能过期,并优先服从本轮用户与实时事实。

检索与遗忘怎样联动

长期未命中不自动代表可以删除,但检索日志能为复核和遗忘提供信号。

如果一条候选频繁被召回却总被用户纠正,可能内容错误或条件过宽,应进入更新或撤回。如果条目长期无使用价值且类型允许,可以按保留策略过期。用户明确要求删除时,不等待排序自然降权,而是立即让主记录和索引不可再读。

遗忘后要验证语义索引、关键词索引、缓存和派生摘要都不再返回。检索器对每个结果复查主记录状态,可以防止异步清理期间旧索引泄漏。

权限变更也类似。Agent 或角色失去访问权后,旧缓存必须失效;不能因为候选过去被读取过,就继续保存在会话外缓存中供其他任务使用。

不同失败症状应该检查哪一层

漏召回、错召回和越权召回对应不同诊断路径。

一个完整例子:继续上次的 RAG 评测

用户说:“继续上次的 RAG 评测,还是先看召回问题。”

查询解析得到当前用户、当前工作区、RAG 项目、评测任务、关注召回阶段,以及可能的最近时间范围。硬过滤先排除其他用户、其他项目、无权读取、过期和被替代记录。

候选生成分多路:按项目和任务 ID 查最近状态;语义检索历史总结与失败记录;精确查询用户已确认的输出偏好。重排时,当前项目和任务阶段匹配高于一般语义相似,最近一次确认的评测状态高于更早草稿,用户偏好只影响呈现方式,不改变评测事实。

若召回两条冲突记录,一条说“问题主要在切分”,另一条说“复查后主要是查询改写”,系统查看来源和版本。若后者是后续确认结论,旧记录退出普通召回;若两者针对不同数据集,保留条件并分别呈现。

最终注入内容可以只有当前阶段、已确认问题、待验证假设和相关工件引用,而不是完整历史对话。若没有可信候选,就请用户提供项目标识或从当前材料重新开始,不编造“上次结论”。

怎样建立评测集

先从真实或人工设计的任务对生成查询、允许访问的记忆集合、应该召回的条目、必须排除的条目和期望的无结果场景。

正例覆盖同义表达、跨会话指代、长期偏好、最近事件和项目续接。难负例覆盖不同主体、不同项目、相似措辞、过期版本、冲突未解、权限不足和已删除条目。

指标可以分层:硬过滤是否挡住越权与失效内容;候选召回是否包含正确条目;重排是否把正确条目放到预算内;注入后任务是否更正确;错误记忆是否造成污染。还要记录无记忆基线与不同检索策略的对照。

消融可以依次去掉时间性、重要性、来源、条件匹配或混合检索,观察哪些样本受影响。权重和阈值应从这些标注与失败案例中得到,而不是先写死再寻找解释。

端到端评估还要检查模型是否正确使用了记忆。检索正确但最终答案忽略,问题在上下文组织或生成;错误候选进入上下文,问题在检索;正确候选被过滤,问题在意图或元数据。只有分层 Trace 才能定位。

Agent 记忆检索验收清单

检索质量既看找到什么,也看挡住什么和最终是否真正使用。

面试官会怎样连续追问

追问一:相关性、时间性和重要性权重怎么定

不先报固定权重。先按记忆类型定义特征和硬约束,再用标注集、难负例和消融选择参数。用户偏好、事件与程序经验不应该共享同一套权重。

追问二:为什么权限不能作为负分

因为越权候选无论相关性多高都不能被使用。权限与租户是准入条件,应在候选生成前过滤,并在主记录层再次复查。

追问三:越新的记忆优先吗

只在同类有效候选中可能优先。稳定事实不能被短期噪音覆盖,实时业务状态应重新查询权威系统。明确失效和版本替代高于软时间衰减。

追问四:冲突时选相似度最高的一条行不行

不行。相似度不代表权威。应看当前明确输入、来源、确认状态、时间和适用条件,无法裁决时请求确认或不注入。

追问五:为什么记忆检索要允许空结果

强行返回会把低相关历史变成错误上下文。没有可信、有效、授权候选时,空结果比错误个性化更安全。

追问六:怎样判断问题在检索还是模型使用

保留查询意图、过滤、候选、重排、注入和最终引用 Trace。正确条目未入候选是召回问题,入候选未进预算是排序问题,已注入但未使用是生成或任务设计问题。

怎样口述一条可信的记忆检索链路

我会把 Agent 记忆检索分成硬过滤、候选生成、软重排和上下文注入四层。先从当前任务提取主体、项目、记忆类型和时间范围,用租户、权限、有效状态、版本与用途做硬过滤;再结合结构化查询、关键词和向量生成候选。重排时综合语义相关性、实体与作用域、时间性、业务重要性、来源可信度和条件匹配,不给所有记忆类型套一组固定权重。当前明确指令和实时工具事实高于历史记忆,冲突条目按来源与条件裁决,无法判断就请求确认。最后去重、控制 Token,并保留来源和时间注入。评估既测正确召回,也测跨用户、过期、冲突和无结果这些难负例。

记忆召回是否可信,看这十项

  1. 查询是否包含主体、租户、项目、类型、时间和权限作用域。
  2. 无权限、过期、删除和被替代记录是否在排序前排除。
  3. 相关性是否同时考虑语义、实体、阶段和适用条件。
  4. 时间性是否区分稳定事实、临时事件和实时业务状态。
  5. 重要性是否结合用户动作与业务规则,而非只用模型分数。
  6. 冲突能否裁决、更新或请求确认,而不是静默取最高分。
  7. 是否允许没有记忆可用,并限制注入条数和 Token。
  8. 检索、排序、注入和最终使用能否通过 Trace 分层诊断。
  9. 用户撤回、删除或权限变化后,旧索引和缓存是否不再返回。
  10. 没有真实评估时,是否避免虚构权重、命中率和性能收益。

记忆检索追求的是克制:在当前权限和任务边界内,只让真正相关、仍然有效、值得信任的少量历史进入决策。能在不该回忆时保持安静,和在需要时找到正确信息同样重要。

INTERVIEW FOLLOW-UPS

面试官会怎样继续追问?

这些追问会继续检查方案取舍、验证方法和项目事实。
  1. Q01

    相关性、时间性和重要性的权重怎么确定?

  2. Q02

    为什么权限和有效状态不能只作为排序负分?

  3. Q03

    新旧记忆冲突时怎样决定使用哪一条?

  4. Q04

    怎样区分检索失败、重排失败和模型没有使用记忆?

PROJECT CHECK

换成你的项目,这几件事能否说清楚?

  • 先做租户、权限、状态、版本和作用域硬过滤
  • 组合语义、实体、时间、重要性、来源与条件信号
  • 支持冲突裁决、空结果和受控上下文注入
  • 覆盖难负例、删除后不可召回与分层 Trace
用自己的项目经历练一次