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 或内容版本,可以先做条件请求。页面未变化,就继续使用缓存正文;发生变化,再重新抽取相关片段。
如果来源不提供可靠版本信号,可以比较内容指纹、标题时间和关键区块,或者直接刷新高风险页面。
搜索缓存也可以作为旧候选集合,但应重新运行发现步骤,检查是否出现新来源。
所以“最新”要求改变的是验证策略,不等于系统里每一层缓存全部关闭。目标是把刷新资源放在可能影响结论的位置。
一次命中应该经历哪些判断?
第一步,计算候选缓存键,并检查权限范围与工具版本。
第二步,读取当前任务的新鲜度要求和证据用途。
第三步,检查缓存对象的抓取时间、内容时间、页面版本和最近验证状态。
第四步,选择直接使用、条件验证、强制刷新、后台刷新或拒绝复用。
第五步,返回结果时附带缓存状态和证据元数据,让研究状态知道它是新取、已验证复用还是待刷新候选。
第六步,最终报告发布前,对高时效和高风险主张再次核验来源。

命中不代表直接返回,任务时效与证据用途还要决定是否复核。
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 由来源变化、任务契约和风险决定,不能照搬固定教学值。目标是在保持证据新鲜与可追溯的前提下复用中间结果。

先证明缓存没有让答案过期
把“做了缓存”换成下面这些可核验事实,面试官才能判断这套策略是否真的守住了时效和权限边界。
- 缓存键是否包含真正影响输出的参数、权限和处理版本?
- 路由器能否识别时效要求,并在命中后决定验证或刷新?
- 页面更新、权限变化和删除是否有主动失效与版本记录?
- 是否用陈旧命中和最终主张时效验证缓存,而不只看命中率?