跳到正文

DEEP RESEARCH PROJECT INTERVIEW · Q12 / 25

缓存能省调用,为什么 Deep Research 反而可能拿旧资料回答“最新”?

从分层缓存、缓存键、时效契约、条件验证、权限隔离和陈旧命中出发,讲清 Deep Research 缓存的新鲜度控制。

作者与复核:吴师兄内容依据:公开教程、代码示例与工程推导查看关联教程 →查看吴师兄公开作品 →

25 道题目Q12
本页内容24 节

30 秒先说结论

Deep Research 应分层缓存 Search、Visit、抽取和派生结果,并把参数、权限与处理版本写入键。命中后结合用户时效要求、抓取时间、内容时间和页面版本决定复用、验证或刷新。历史证据不静默覆盖,私有内容不跨租户,TTL 通过陈旧命中和任务风险校准。

Deep Research 会反复搜索相似关键词,也会多次访问同一页面。

不做缓存,同一份搜索结果和网页正文会不断消耗外部接口、时间与解析资源。做了缓存,另一个问题马上出现:用户问“刚发布”“当前版本”“今天有什么变化”,系统却拿昨天或更早的结果回答。

缓存本身没有错。真正的问题是,系统把“以前可用”误当成“现在仍适合当前问题”。

搜索结果、网页正文、抽取片段、计算结果和最终报告的新鲜度要求不同。一个固定 TTL 无法覆盖所有任务。权限、页面版本、查询参数和证据用途如果没有进入缓存键,还可能出现跨任务污染。

所以面试官问缓存策略时,真正想听的是:

哪些层可以缓存,缓存键怎样设计,如何从用户问题识别新鲜度要求,什么时候命中也必须重新验证,怎样处理页面变化、权限隔离和旧证据,又怎样证明缓存节省资源的同时没有损害答案时效?

Deep Research 可以缓存哪几层?

第一层是 Search 结果。

键通常来自规范化 query、语言、地区、时间过滤、返回数量和搜索服务版本。它适合减少短时间内相同发现请求,但搜索排序与网页状态变化较快。

第二层是 Visit 原始内容。

键来自规范化 URL、访问权限和页面版本。页面正文变化频率通常与搜索结果不同,不能共用一个失效时间。

第三层是相关性抽取。

同一页面针对不同研究目标,抽取片段不同。键除了页面版本,还要包含当前问题或抽取目标、抽取器版本和输出 Schema。

第四层是结构化解析与计算。

PDF 解析、表格清洗和确定性计算可以按输入内容哈希、代码或解析器版本缓存。输入不变时更容易复用。

第五层是最终回答或研究报告。

这一层风险最高。它绑定用户任务、证据版本、权限、时间和交付范围。很多情况下只适合复用中间证据,不适合直接返回旧报告。

不同缓存层的复用价值与新鲜度风险

越接近最终结论,缓存越需要绑定任务、证据版本和权限。

缓存键为什么不能只有 query 或 URL?

相同 query 在不同语言、地区和时间范围下,可能需要不同搜索结果。

相同 URL 对登录用户和公开访问者,返回内容可能不同。

同一页面经过不同抽取器版本,得到的结构和相关片段可能不同。

同一份数据使用不同单位、过滤条件和计算代码,派生结果也不同。

因此缓存键要覆盖真正影响输出的变量。遗漏关键维度会发生错误复用,加入过多无关维度又会降低命中率。

一种实用做法是把键拆成资源身份、请求语义、权限范围和处理版本四部分。每次命中都能回答:复用的是哪份资源,为什么与当前请求等价,谁有权读取,经过哪版工具生成。

规范化也要谨慎。去掉空白、统一大小写通常安全,但把“当前版本”和“历史版本”都规范成同一查询就会损害语义。规范化规则同样需要版本和回归测试。

查询重写后,缓存应该按原问题还是新 Query?

多轮研究常把用户原话改写成独立查询,也会为同一缺口生成多个搜索表达。

只按原问题缓存,两个语义相同但说法不同的请求无法复用。只按改写 Query 缓存,模型一次不稳定改写又可能让错误结果长期命中。

更稳妥的做法是同时保留用户任务 ID、当前缺口 ID、原问题和规范化查询。Search 缓存可以按规范化查询复用候选,但证据状态仍记录它服务于哪个缺口。

若改写改变了时间、对象或范围,就不能与旧 Query 视为等价。系统需要比较关键槽位,而不是只算文本相似。

多个改写命中同一 URL 时,可以共享 Visit 原文缓存,但各自的相关性抽取仍要绑定当前目标。页面相同,不代表需要的证据片段相同。

这种分层能避免一个错误 Query 污染整个任务,同时保留真正相同资源的复用价值。

把新鲜度写进任务契约

“什么是某算法”通常不要求分钟级更新。

“某项目当前最新版本支持什么”对时效更敏感。

“比较去年几个版本的变化”需要历史证据,反而不能用今天页面悄悄替换当时内容。

系统应从用户问题提取时间范围、新鲜度词、目标对象和交付风险。随后为每个研究缺口设置允许的证据年龄和复核要求。

这个要求不是让模型自由猜一个 TTL。可以把任务分为稳定事实、版本能力、动态事件和高风险结论,再结合数据源变化频率与服务承诺配置策略。

同一份缓存对一个问题可用,对另一个问题不可用。例如旧官方文档适合说明历史版本,却不适合支持“现在”。

缓存对象应记录抓取时间、页面声明时间、内容版本和最近验证状态。只有抓取时间,没有内容所属时间,仍可能把旧数据当新资料。

看到“最新”就完全禁用缓存吗?

不一定。

可以复用稳定的页面解析结构、DNS 或连接层缓存,也可以用缓存结果帮助定位候选来源。但关键证据需要重新访问或验证页面是否变化。

若来源支持 ETag、Last-Modified 或内容版本,可以先做条件请求。页面未变化,就继续使用缓存正文;发生变化,再重新抽取相关片段。

如果来源不提供可靠版本信号,可以比较内容指纹、标题时间和关键区块,或者直接刷新高风险页面。

搜索缓存也可以作为旧候选集合,但应重新运行发现步骤,检查是否出现新来源。

所以“最新”要求改变的是验证策略,不等于系统里每一层缓存全部关闭。目标是把刷新资源放在可能影响结论的位置。

一次命中应该经历哪些判断?

第一步,计算候选缓存键,并检查权限范围与工具版本。

第二步,读取当前任务的新鲜度要求和证据用途。

第三步,检查缓存对象的抓取时间、内容时间、页面版本和最近验证状态。

第四步,选择直接使用、条件验证、强制刷新、后台刷新或拒绝复用。

第五步,返回结果时附带缓存状态和证据元数据,让研究状态知道它是新取、已验证复用还是待刷新候选。

第六步,最终报告发布前,对高时效和高风险主张再次核验来源。

Deep Research 缓存命中与新鲜度判断流程

命中不代表直接返回,任务时效与证据用途还要决定是否复核。

stale-while-revalidate 适合什么场景?

这个策略可以先返回旧缓存,同时在后台刷新。

它适合允许短暂陈旧、又希望低延迟的场景,例如一个非关键背景页面。返回时应明确“当前使用最近已验证版本,后台正在更新”。

它不适合用户明确要求最新、会影响决策的关键结论。旧值若先进入最终答案,后台刷新发现变化已经太晚。

长任务中还要处理刷新竞争。多个研究单元命中同一过期对象时,应合并为一次刷新,其他调用等待或使用明确标记的旧结果,避免缓存击穿。

刷新完成后,新的页面版本不能静默改写已经生成的历史报告。它应进入当前任务的新证据版本,重新检查受影响主张,并按产品规则更新报告。

后台刷新失败也要保留状态。系统不能把“刷新失败”写成“页面未变化”。

缓存预热和击穿怎样处理?

系统发布、工具升级或批量失效后,大量请求可能同时回源。

预热可以提前加载少量稳定、公开且高频的资源,但不能预先生成所有用户答案。预热对象要有明确来源、权限和版本,避免把旧内容在新系统启动时重新灌入。

对同一个过期键,使用请求合并。第一个请求负责刷新,其他请求等待、使用允许的旧值或得到明确的稍后重试状态,不能各自访问外部服务。

若刷新持续失败,进入短时保护或熔断,不让积压请求把搜索和访问服务压垮。保护期间是否允许旧值,仍由任务时效与风险决定。

还要给不同缓存层分别设并发预算。页面原文刷新成功,不代表所有相关性抽取都要在同一时刻重算;可以按真实访问需求延迟生成。

预热命中率高也不一定有价值。若预热资源很少被当前任务使用,只是把成本从请求时移到发布时。应根据真实访问分布调整,而不是追求缓存看起来很满。

缓存失效为什么最难?

时间到期只是最简单的失效方式。

页面内容可能在 TTL 内更新,工具或抽取器升级后旧结构可能不再兼容,权限变化后旧对象不应继续访问,用户删除数据后相关缓存必须同步清理。

内容版本失效可以用指纹或来源版本检测。

处理版本失效需要把工具、Prompt、抽取 Schema 和代码版本写入键或元数据。

权限失效要由鉴权层驱动,不能等待自然过期。

任务失效出现在用户改变范围、对象或时间要求时。旧证据可能仍保留作历史记录,却不再支持当前结论。

缓存系统需要提供按来源、用户、版本和任务关联的失效入口。只支持“清空全部缓存”,上线后既难操作,也会造成大面积回源。

权限隔离为什么比命中率更重要?

相同 URL 在不同账号下可能返回不同内容。

企业知识、用户上传文件和带授权页面绝不能仅按 URL 共用缓存。键中要包含租户、用户或权限摘要,存储层也要执行同样隔离。

权限摘要还要随角色变化更新。用户失去访问权后,旧缓存不能继续命中。

日志和调试页面也不能泄露缓存正文、查询或密钥。团队需要看到命中与版本信息,不一定需要看到全部敏感内容。

对公共网页与私有资源可以使用不同缓存域,避免配置错误时跨边界复用。

删除请求必须覆盖派生对象。原文被删除后,相关抽取、向量、计算和报告缓存也要有可追踪的清理关系。

提高命中率不能成为放宽权限键的理由。一次跨租户命中就是安全问题,不是性能误差。

页面更新后,历史报告怎么办?

历史报告应保留它生成时使用的证据状态。

不能因为当前页面内容变化,就让旧报告的引用在后台指向一段不同原文。报告需要记录访问时间、页面版本和证据片段定位。

新页面可以触发一次重新验证。若结论受影响,生成新报告版本或提示来源已变化。

历史版本用于回答“当时资料怎么说”,当前版本用于回答“现在是什么”。两者都可能有价值,不能只保留最新覆盖旧记录。

来源删除或迁移时,系统可以寻找官方新地址,但要保留迁移关系。新地址不是旧证据的无痕替换。

这也是缓存与证据库的差别。缓存追求复用,可以过期;证据记录追求可追溯,需要按授权和审计策略保留版本信息。

工具和抽取器升级后,旧缓存还能用吗?

原始网页内容可能仍然有效,但旧抽取结果未必适配新 Schema。

工具升级要区分资源缓存与处理缓存。原文按页面版本复用,相关片段、结构化字段、向量和派生计算则绑定处理器、Prompt、模型与 Schema 版本。

若升级只影响一个字段,可以定向重算受影响层,不必重新搜索全部来源。若新版修复了阅读顺序或表格解析,旧证据片段可能已经不可靠,需要重新抽取并复核相关主张。

缓存迁移不能直接修改历史记录。旧报告继续指向当时的处理版本,新任务使用新版结果。需要重发报告时,创建新的证据版本并重新验收。

发布前可以回放固定页面集,比较新旧抽取的字段、来源定位和主张支持。只有格式兼容,不代表语义没有变化。

版本进入缓存键会降低一段时间的命中率,但比跨版本错误复用更安全。稳定后再通过分层迁移恢复命中。

来源暂时不可访问,旧缓存能否救急?

旧缓存可以帮助保留历史证据,但是否能用于当前回答取决于任务。

用户问历史状态,缓存有明确抓取时间和页面版本时,可以作为当时证据使用。

用户问当前状态,而来源刷新失败时,只能说明最近核验到的时间,不能把旧值标成当前。

高风险结论如果必须由原始来源重新确认,刷新失败就应阻塞确定回答。低风险背景可以在显式时间标签下继续使用。

恢复后重新验证来源,并检查期间生成的报告是否受影响。不能把服务恢复简单等同于旧缓存仍然正确。

这一策略需要产品界面支持时间与状态展示。若前端只显示一段答案,用户无法区分当前证据、历史缓存和待验证内容。

一个教学场景:最新版本问题命中旧缓存

下面是教学设计,不代表真实生产事故或固定缓存配置。

用户问某开源项目“当前版本新增了哪些能力”。

Search 命中旧结果,候选页仍指向上一版发布说明。Visit 缓存也能正常返回正文,所有接口状态都是成功。

如果系统只看命中,它会用旧发布说明生成一份完整回答。

合格流程会识别“当前版本”的时效要求,重新执行发现或检查官方发布入口,并验证候选页版本。若发现新页面,旧缓存保留为历史版本,新页面进入当前证据。

若刷新失败,系统可以说明最近已核验到哪个时间和版本,但不能把它表述为当前最新。

这个场景说明,缓存错误通常源于证据适用性判断,接口和存储即使工作正常也可能返回错误时效的答案。

缓存应该怎样做测试集?

第一类是稳定事实,同一查询多次出现,验证合理命中与资源节省。

第二类是时效查询,包含最新、当前、今天、刚发布和特定时间范围,验证刷新策略。

第三类是页面变化,同一 URL 内容更新、重定向或删除,验证版本与历史引用。

第四类是参数变化,语言、地区、时间过滤、抽取目标和工具版本不同,验证缓存键。

第五类是权限变化,不同租户、角色变更和删除请求,验证隔离与失效。

第六类是并发刷新,多个请求同时命中过期对象,验证合并刷新、排队和失败恢复。

第七类是降级状态,刷新失败、备用来源和旧缓存,验证系统是否正确说明证据时间。

缓存与新鲜度测试矩阵

缓存测试既要证明能命中,也要证明不该命中时会刷新或拒绝。

每个测试要定义期望路径:直接复用、条件验证、强制刷新、允许旧值但标记、或禁止返回。不能只检查键值数据库里有没有数据。

上线后看哪些指标?

命中率是基础指标,但要按缓存层、任务类型和新鲜度等级拆开。

陈旧命中率更重要。它检查返回缓存后,后续刷新是否发现内容已经变化,以及这个变化是否影响结论。

条件验证成功率能说明多少页面可以低成本确认未变化。

刷新延迟和刷新失败率反映时效任务的用户等待。

缓存击穿与合并刷新情况反映并发控制。

权限拒绝、跨域拦截和删除传播用于安全审计。

最终报告要看时效主张是否使用符合时间要求的证据,历史报告是否保持版本一致。

节省多少调用与时延,需要在自己的任务和工具价格上测量,不能把教学配置或局部实验写成生产收益。

怎样排查“缓存让答案变旧”?

先定位错误主张对应的 Evidence ID 和缓存层。

检查缓存键是否漏了时间、权限、参数或处理版本。

检查路由器是否识别了用户的新鲜度要求。

检查缓存对象的抓取时间与内容所属时间是否混淆。

检查页面已变化但条件验证、指纹或刷新任务有没有失败。

检查最终生成是否忽略了“旧缓存”“待刷新”状态。

修复后用同一旧对象、同一当前页面和同一用户问题重放,确认系统选择正确刷新路径。仅仅清空缓存后答案恢复,不能证明根因已修好。

还要检查相反风险:修复是否让所有查询都绕过缓存,导致命中和延迟全面恶化。正确方案应只收紧需要时效或权限验证的路径。

面试官继续追问,怎么接?

追问一:TTL 应该设置多久?

没有跨场景固定值。要根据数据变化频率、用户时效要求、来源版本能力和结论风险配置,并用陈旧命中和刷新结果校准。

追问二:用户问“最新”,是不是所有缓存都不能用?

不是。稳定解析和候选缓存仍可帮助执行,但关键来源要重新发现或验证,最终证据必须满足当前时效。

追问三:相同 URL 为什么不能直接共用 Visit 缓存?

它可能受权限、语言、页面版本和抽取目标影响。公共原文、私有内容和相关片段需要不同键与隔离。

追问四:缓存页面更新后,要修改历史报告吗?

不能静默修改。历史报告保留当时证据版本,新内容触发新报告版本或来源变化提示。

追问五:怎样证明缓存没有损害准确性?

用稳定、时效、页面变化、权限和并发样本对照缓存开关,检查陈旧命中、主张时效、引用版本和最终报告,而不只看命中率。

面试时怎样讲清缓存与新鲜度取舍

Deep Research 的缓存要按层设计。Search 结果、Visit 原文、相关性抽取、确定性计算和最终报告的新鲜度与缓存键都不同。键至少绑定规范化查询或 URL、关键参数、权限范围、工具和处理版本,不能只用 query 或 URL。

命中后我不会直接返回,而是结合用户时间范围、最新或当前等时效要求、证据用途和缓存对象的抓取时间、内容时间与页面版本,选择直接复用、条件验证、强制刷新、后台刷新或拒绝使用。返回结果要标明新取、已验证缓存或待刷新。权限数据按租户隔离,用户删除和角色变化要主动失效,历史报告保留当时证据版本,不能被当前页面静默改写。

验收会覆盖稳定事实、时效查询、页面更新、参数变化、权限、并发刷新和降级,观察命中、陈旧命中、刷新延迟、权限拦截和最终主张时效。TTL 由来源变化、任务契约和风险决定,不能照搬固定教学值。目标是在保持证据新鲜与可追溯的前提下复用中间结果。

Deep Research 缓存新鲜度检查清单

先证明缓存没有让答案过期

把“做了缓存”换成下面这些可核验事实,面试官才能判断这套策略是否真的守住了时效和权限边界。

  • 缓存键是否包含真正影响输出的参数、权限和处理版本?
  • 路由器能否识别时效要求,并在命中后决定验证或刷新?
  • 页面更新、权限变化和删除是否有主动失效与版本记录?
  • 是否用陈旧命中和最终主张时效验证缓存,而不只看命中率?

INTERVIEW FOLLOW-UPS

面试官会怎样继续追问?

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

    缓存 TTL 应该设置多久?

  2. Q02

    用户问最新是不是所有缓存都不能用?

  3. Q03

    相同 URL 为什么不能直接共用缓存?

  4. Q04

    页面更新后要修改历史报告吗?

PROJECT CHECK

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

  • 按 Search、Visit、抽取和派生结果分层缓存
  • 键包含参数、权限、版本和处理契约
  • 命中后根据时效与证据用途验证或刷新
  • 用陈旧命中与最终主张时效验收
用自己的项目经历练一次