从前有家“智能小厨”餐馆,主厨大壮每天都要亲手现做每道菜。生意火爆时,一天下来手腕都累断了——因为不管客人点的是不是同一道“招牌红烧肉”,他都要从洗菜切肉重新开始。后来他学聪明了:把最受欢迎的几道菜提前做好,放在保温柜里,客人一点就立刻端上来,又快又省力气。这个保温柜,就是我们今天要讲的——LLM 应用的“缓存层”。 对于 AI 从业者来说,缓存层是架构设计中“花小钱办大事”的经典智慧。掌握它,意味着你能为企业省下真金白银的 API 费用,同时让用户感受到“秒回”的极致体验——这几乎是性价比最高的职业技能投资。

岗位关联

缓存层是 LLM 应用的“保温柜”,能大幅降低 API 成本、提升响应速度。对 AI 工程师而言,它是降本增效的必备技能,也是架构设计功力的直接体现。

目录
  1. 可视化演示
  2. 缓存的价值
  3. 缓存键设计
  4. 过期与淘汰
  5. 命中率优化
  6. 一致性保障
  7. 实战落地
  8. AI 应用场景
  9. Python 演示
  10. 常见误区
  11. 面试题

可视化演示

动态演示缓存层的核心机制,通过输入/处理/存储/输出四种模式展示关键概念与交互流程。

本节配有交互动效(进入视口后自动加载,约 3KB)。

缓存层:LLM应 LLM应用缓存层总览与降本增效 缓存键设计策略与哈希方法 核心机制可视化 缓存层整体架构与关键组件

缓存的价值

主厨大壮发现,与其每单都从零开始做,不如把最受欢迎的“招牌红烧肉”提前炖好一锅放在保温柜里。客人一点,三秒上菜,燃气费省了大半。一个 LLM 应用里的缓存层,干的就是这活儿:把高频的问答结果存下来,下次遇到相同或相似的问题,直接从缓存取,不再烧钱调用大模型。

这个“保温柜”带来的收益是立竿见影的。第一是省成本——LLM 按 token 计费,每省一次调用,就省一笔钱。假设一次调用成本 1 元,缓存命中率 70%,那 1000 次请求就能省下 700 元。第二是快——直接从缓存读数据通常只要几毫秒,而调用大模型需要几秒。用户感知到的速度,直接决定了产品的体验评分。

当然,保温柜也不是万能的。它最适合的是“高频重复问答”场景,比如常见客服问题、固定话术、产品介绍等。对于千变万化的开放式创作型任务,缓存的效果就有限了。这就像红烧肉可以提前炖,但客人若要点“今天心情定制菜”,你还得现炒。

缓存键设计

保温柜里那么多菜,怎么快速找到客人点的那道?大壮给每道菜都贴了标签:“招牌红烧肉-大份-少辣”。这个标签,就是缓存里的“键”(Key)。键设计得好不好,直接决定了能不能快速、准确地找到缓存结果。

缓存键的本质,是用户请求的“唯一指纹”。一个最简单的设计,就是把用户的完整问题字符串当作键。但实际中没那么简单——“你好请问红烧肉多少钱”和“红烧肉价格?”其实是同一个问题,字符串却完全不同。如果直接拿原字符串当键,这两个请求会分别查两次缓存,都没命中,白白浪费两次 LLM 调用。

解决办法是“查询规范化”:在生成缓存键之前,先对用户输入做标准化处理。比如统一小写、去除多余空格、把同义词替换成标准词。这样一来,“什么是机器学习”和“请问什么是机器学习?”就能映射到同一个键上。规范化做完后,再通过哈希运算把键变成固定长度的字符串,方便快速查找。

这里要留个心眼:如果两个问题的语义相同但表达完全不同,比如“怎么省 API 钱”和“如何降低大模型调用成本”,字符串规范化就无能为力了。这就要用到更高级的“语义缓存”,通过向量化 + 余弦相似度来判断问题是否“意思相近”,不过这是后话了。对于绝大多数场景,先把字符串层面的规范化做好,就已经能带来可观的收益。

回到大壮的厨房:把“标签”贴得规范统一,才能在数百道预制菜中一秒锁定目标。缓存键设计,就是给每个查询贴一个“规范标签”,贴得好,命中率自然高。

缓存键=Hash(normalize(用户问题))\text{缓存键} = \text{Hash}(\text{normalize}(\text{用户问题}))
缓存键设计的目标是:让“同一个意思的问题”映射到同一个键,让“不同的问题”映射到不同的键。
  1. 规范化处理先将用户问题标准化,去除标点、统一大小写、替换同义词,消除细枝末节的差异。
    normalize(q)=lowercase(trim(q))\text{normalize}(q) = \text{lowercase}(\text{trim}(q))
  2. 哈希运算将规范化后的字符串通过哈希函数(如 MD5、SHA-256)映射为固定长度的哈希值,作为缓存的存储键。
    key=MD5(normalize(q))\text{key} = \text{MD5}(\text{normalize}(q))

过期与淘汰

保温柜的容量终究有限,大壮不可能把所有菜都提前做好。做多了卖不掉会浪费,放久了会不新鲜。所以他要定规矩:哪些菜在保温柜里待多久?柜子满了先撤掉哪道?这就是缓存的“过期”与“淘汰”策略。

最直观的策略是 TTL(生存时间)——给每份缓存设置一个保质期。比如客服问答的答案是 24 小时内有效,过了 24 小时就自动销毁,下次请求再重新调用 LLM 生成。这个策略简单可靠,适合答案相对稳定、不会频繁变化的场景。

但如果所有菜都设同样的保质期,就有问题了:有些菜每天都有人点(热数据),有些菜一周也没人问一次(冷数据)。这时候就需要“淘汰策略”来管理——当保温柜放不下时,优先撤掉最久没被点的菜。这就是经典的 LRU(最近最少使用)策略:记录每份菜最后一次被“翻牌”的时间,满员时淘汰最久没被翻牌的。

TTL 和 LRU 不是互斥的,实际项目中常常组合使用:TTL 保证“数据不会无限期陈旧”,LRU 保证“空间不会被无用数据占满”。就像大壮既给每道菜贴保质期标签,又在冷藏柜满时优先扔掉最没人气的剩菜——双管齐下,保温柜才能长期高效运转。

淘汰优先级=arg⁡min⁡i∈cache(lastAccessTimei)\text{淘汰优先级} = \arg\min_{i \in \text{cache}}(\text{lastAccessTime}_i)
LRU 淘汰策略的核心思想:如果一份缓存很久没被访问,那它很可能以后也不会被访问。类似的策略还有 LFU(按访问频率淘汰),但 LRU 实现更简单、最常用。
  1. 记录访问时间每次从缓存中取数据时,把当前时间更新为该键的最后访问时间。
    lastAccessTime[key]=now\text{lastAccessTime}[\text{key}] = \text{now}
  2. 淘汰最久未访问项缓存容量满时,遍历所有键,找出 lastAccessTime 最小的键并删掉,为新数据腾出空间。
    evict=arg⁡min⁡klastAccessTime[k]\text{evict} = \arg\min_{k} \text{lastAccessTime}[k]

命中率优化

保温柜的终极追求是什么?让客人点的菜尽量都能“三秒上桌”。这个比例,在缓存领域叫“命中率”——命中率越高,省的钱越多、响应越快。大壮想了三招来提高“上菜命中率”。

第一招:提前预热。大壮每天开门前,就把昨天的销量 Top 10 菜品提前做好放保温柜。对应到 LLM 应用,就是每天凌晨把“高频问题 Top N”提前调 LLM 生成好答案存入缓存。用户早上打开应用,热门问题直接命中缓存,体验极佳。第二招:请求归一化。前面讲的缓存键设计中的规范化,就是命中的基础——键设计归一了,同一个问题不管怎么问都能命中同一份缓存。第三招:渐进式写入。刚开始没数据时,所有请求都要走 LLM,这时应用是不那么“聪明”的。但随着系统运行,每次未命中的结果都会写入缓存,运行越久,“保温柜”里的好菜越多,命中率逐渐爬坡。

命中率的优化是一个持续迭代的过程。就像大壮每天复盘“哪些菜被剩下、哪些菜不够卖”,不断调整备菜清单。缓存系统的运营者也要定期分析“哪些问题高频未命中”,把这些漏网之鱼补充进预热列表,命中率自然会稳步上升。

命中率=缓存命中的请求数总请求数×100%\text{命中率} = \frac{\text{缓存命中的请求数}}{\text{总请求数}} \times 100\%
命中率是衡量缓存层效果的核心指标。常见的优化路径:从 0% 起步,通过预热和归一化快速提升到 60%-80%,再通过持续分析和调优逼近 90% 以上。
  1. 计算命中比例统计一段时间内,直接在缓存中找到答案的请求数量与总请求数量的比值。
    HitRate=NhitNtotal\text{HitRate} = \frac{N_{\text{hit}}}{N_{\text{total}}}
  2. 持续优化目标通过预热、规范化、语义缓存等手段,不断提高命中率分子。

一致性保障

这天,大壮改了招牌红烧肉的配方——从“偏甜”改成了“偏咸鲜”。但保温柜里还放着昨晚按老配方做好的菜。客人一尝:哎,怎么味道不对?这就是缓存与源头数据的“不一致”问题。LLM 应用也一样:当知识库更新、Prompt 调整或模型版本升级后,如果缓存不清理,用户就会拿到“过时的答案”。

解决这个问题最直接的办法是“主动失效”:当源数据发生变化时,主动把相关的缓存清掉。比如知识库里新增了一篇文章,就把所有涉及该话题的缓存全部删除,下次请求重新生成。这就像大壮改了配方后,果断把旧的红烧肉全部撤下,重新按新配方做一锅。主动失效实现简单,但要精准知道“数据变化影响了哪些缓存”,需要维护一个“数据到缓存”的映射关系。

另一个思路是“双写机制”:源数据更新时,同时更新缓存。这听起来很合理,但实际操作中往往有风险——如果缓存写入失败,就产生了不一致。更稳健的做法是“旁路更新”:先用新数据重新生成 LLM 答案,再原子地替换掉旧缓存。最后,版本号比对技术可以兜底——给每条缓存记录加一个数据版本号,每次读取时对比源数据版本号,不一致则主动失效重建。

一致性是缓存系统里最考验功力的部分——因为缓存本质上是在“正确性”和“性能”之间做权衡。大壮的选择是:配方更新频繁的菜不提前准备(不加缓存),配方稳定的菜放心用保温柜(大胆缓存)。LLM 应用也一样,对于答案会随知识库频繁更新的场景,要更激进地管理失效;对于大纲稳定、通用知识类的问答,可以放心让缓存多活一阵子。

缓存有效性={有效if cacheVersion==sourceVersion失效otherwise\text{缓存有效性} = \begin{cases} \text{有效} & \text{if } \text{cacheVersion} == \text{sourceVersion} \\ \text{失效} & \text{otherwise} \end{cases}
版本号机制是缓存一致性的“安全网”:通过比对数据版本号,即使主动失效和双写都漏掉了,读取时也能发现缓存已过期并及时刷新。
  1. 记录数据版本号每次更新源数据时,将版本号加一,缓存中同时记录生成该答案时对应的版本号。
    sourceVersion←sourceVersion+1\text{sourceVersion} \leftarrow \text{sourceVersion} + 1
  2. 读取时校验一致性从缓存读取答案时,比对缓存记录中的版本号与当前源数据的版本号。
    isValid=(cacheVersion==sourceVersion)\text{isValid} = (\text{cacheVersion} == \text{sourceVersion})

实战落地

理论讲完,回到真正的厨房——怎么给真实世界的 LLM 应用装上“保温柜”?大壮的落地清单分三步:评估、设计、监控。

第一步是场景评估。先问自己三个问题:我的应用是不是高频问答型?用户重复问同一个问题的概率高吗?答案是否经常变化,还是相对稳定?如果高频且稳定,缓存层收益显著;如果是低频且个性化,缓存收益有限,不如把钱花在别处。第二步是方案设计。确定缓存键怎么生成(用什么字段拼接)、TTL 定多长(1 小时?24 小时?)、淘汰策略用哪种组合、在代码的哪一层接入缓存(在 LLM 调用前先查缓存,未命中才调用 LLM)。第三步是监控调优。指标看命中率、缓存大小、过期失效数;日志记录未命中的问题,定期分析是否可以通过规范化或预热提高命中率。

在这个三步走的过程中,最容易被忽略的是“缓存键的设计是否考虑了模型和 Prompt 的版本”。如果今天用的 Prompt 和昨天不一样,那么同样的用户问题生成的答案可能也不同——这时缓存键里最好加入 Prompt 版本号,以免新旧答案混淆。大壮的智慧在于:他不仅关心“菜够不够快”,更关心“菜是不是按当前配方做的”。缓存层设计,最难得就是这份细致。

至此,保温柜的完整经营之道已经铺开:从价值判断、键的标签设计、保质期管理、上菜命中率优化、配方一致性保障,到最终的落地执行。主厨大壮的保温柜,就是 LLM 应用缓存层的完美缩影——它让系统更快、更省、更聪明。

text3 行
用户请求 → 规范化 → 查缓存 → 命中?→ 返回结果                        ↓未命中                    调用 LLM → 写入缓存 → 返回结果

AI 应用场景

智能客服知识库问答

阶段:应用架构层(缓存层)

解决的问题:智能客服是典型的高频重复问答场景——“怎么退款?”“发货时间多久?”这类问题每天被问成千上万次。没有缓存时,每个用户的问题都要调用一次 LLM,成本高企,响应还要等上两三秒。接入缓存层后,把高频问题的回复缓存起来,相同的直接返回,只有新问题才调用 LLM,成本直线下降。

具体案例:某电商平台的智能助手每天处理约 10 万次咨询,其中约 65% 是重复问题。通过 Redis 缓存层 + 归一化键设计,缓存命中率达到 68%,API 调用次数从日均 10 万次降到 3.2 万次,月度 API 费用从 6 万元降至 2 万元,用户平均响应时间从 2.8 秒缩短到 0.4 秒。

文档问答系统(RAG 应用)

阶段:检索增强生成(RAG)流程的最终应答环节

解决的问题:在 RAG 架构中,相同文档片段的解析、向量化、检索非常耗时。若多个用户问相似问题,系统会对同一批次文档反复处理,消耗 token 额度。通过在“检索结果-最终答案”层面加缓存,相同问题可以直接复用已生成的答案,省去重复检索和生成。

具体案例:某企业内部的 SOP 问答机器人,员工围绕同一份《报销制度》反复提问。加入语义缓存后,用向量相似度判断问题语义是否相近,相似度超过 0.95 直接命中缓存。上线一个月后,LLM 调用量下降 47%,同时答案一致性提升——不会再因为 LLM 有时“心情不好”答得不一样了。

多轮对话中的订阅回复

阶段:应用架构层(缓存层)

解决的问题:在多轮对话中,如果对话历史高度重复(比如每天的日报生成、定时通知),可以用缓存层复用固定的开场白、结束语和常用话术。同时,缓存层还能配合流式输出的场景,将固定话术快速返回,预留时间给动态内容生成。

具体案例:某教育产品的 AI 老师每天早晨给每位学生发送学习日报,日报的模板话术完全相同,只有成绩数据不同。通过缓存固定模板,AI 老师的调用成本降低了 80%,发送速度从每人 3 秒提升到每人 0.2 秒。

Python 演示

python67 行
import timeimport hashlibfrom collections import OrderedDict class LLMCache:    def __init__(self, capacity=100, ttl=3600):        self.capacity = capacity        self.ttl = ttl        self.cache_map = OrderedDict()        self.hit_count = 0        self.total_count = 0     def _normalize(self, question):        return " ".join(question.strip().lower().split())     def _make_key(self, question):        norm = self._normalize(question)        return hashlib.md5(norm.encode()).hexdigest()     def get(self, question):        self.total_count += 1        key = self._make_key(question)        if key in self.cache_map:            answer, timestamp = self.cache_map[key]            if time.time() - timestamp < self.ttl:                self.cache_map.move_to_end(key)                self.hit_count += 1                return answer            else:                del self.cache_map[key]        return None     def set(self, question, answer):        key = self._make_key(question)        self.cache_map[key] = (answer, time.time())        self.cache_map.move_to_end(key)        if len(self.cache_map) > self.capacity:            self.cache_map.popitem(last=False)     def hit_rate(self):        if self.total_count == 0:            return 0.0        return self.hit_count / self.total_count def fake_llm(question):    time.sleep(0.5)    return "这是关于【" + question + "】的AI回答" cache = LLMCache(capacity=5, ttl=10)questions = [    "什么是机器学习",    "什么是机器学习?",    "如何降低API成本",    "什么是机器学习",    "如何降低API成本",    "今天天气怎么样",] for q in questions:    ans = cache.get(q)    if ans is None:        ans = fake_llm(q)        cache.set(q, ans)    print("Q:", q)    print("A:", ans) print("命中率: {:.1f}%".format(cache.hit_rate() * 100))
目的:演示一个带有规范化、TTL 过期和 LRU 淘汰的完整缓存层实现,直观感受缓存层的核心工作原理。
  1. key = self._make_key(question)把用户问题哈希成固定长度的缓存键,实现快速查找。
  2. answer, timestamp = self.cache_map[key]从缓存中取出答案和存入时间,用于判断是否过期。
  3. if time.time() - timestamp < self.ttl检查缓存是否在保质期内,超出 TTL 则视为过期。
  4. self.cache_map.move_to_end(key)将被命中的键移到末尾,这是 LRU 策略的关键操作。
  5. self.cache_map.popitem(last=False)淘汰最久未使用的键(队首),腾出空间给新缓存。
  6. self.hit_count / self.total_count统计缓存命中比例,是评估缓存收益的核心指标。

常见误区

误区缓存命中率高就一定省钱,反正有缓存用不用白不用。我在所有接口上都加了缓存,成本肯定能降下来。

正解缓存本身有存储成本、维护成本、失效机制开发成本。如果应用场景是高度个性化的(比如让 AI 写诗、写独特文案),命中率可能长期很低,缓存带来的收益甚至覆盖不了它引入的复杂度开销。在实施缓存之前,要优先分析请求的重复率,判断这个场景值不值得做缓存。

为何常见:看到“缓存降低 70% 成本”的案例就以为放之四海皆准,忽略了案例背后的高频重复前提。高频问答场景天然适配缓存,而创作类需求不在此列。

误区TTL 设得长一点,缓存就不容易过期,命中率更高,成本更低。我把所有缓存的 TTL 都设成了 7 天。内部数据更新完,用户还是看到旧答案——这就尴尬了。TTL 越长,缓存和源数据不一致的风险越大,用户拿到过时信息的概率越高,信任被消耗。正确的做法是根据数据稳定性来设定不同的 TTL,稳定知识设长、易变数据设短,甚至用主动失效替代 TTL。

正解缓存过期时间是为“数据新鲜度”服务的。如果答案会随知识库更新而变化,设很长 TTL 必然导致用户拿到过期内容;如果答案固定不变,设太短又浪费了缓存价值。所以要按数据更新频率分类配置 TTL,而不是一刀切。

为何常见:人们天然希望一次配置省心省力,但忽略了数据生命周期是动态的。缓存设计必须贴合数据的真实变化节奏。

误区缓存就是要快,数据稍微旧一点没关系吧,用户不会发现的。我上线缓存后从不做失效处理。直到有用户反馈“AI 还在推荐一个月前下架的商品”,才发现一致性出了问题。对于知识库问答来说,过时的信息不只是体验问题,还可能造成业务误导甚至合规风险。缓存的设计必须包含一致性保障机制:主动失效、双写更新或者版本号比对。

正解LLM 应用的输出会直接影响用户的决策,过时内容轻则被吐槽,重则产生错误引导。缓存层需要在“快”和“新”之间取得平衡,在源数据发生变更时及时清理或更新相关缓存。

为何常见:缓存层在技术实现上容易让人只顾读性能而忽略写链路,尤其当主动失效需要跨系统联动时容易被简化掉。

误区LRU 可以解决所有缓存容量问题,直接用 LRU 就好。于是我给所有缓存都用 LRU,结果发现很多缓存被频繁地写入又被淘汰,根本没有被读取过——成本反而增加了。当数据访问存在批量扫描或周期性强访问时,LRU 表现不稳定,可能出现“写入即淘汰”的抖动。要结合业务场景,比如用衰减计数的方法,优化访问频率的计算方式。

正解LRU 假设“近期被访问的将来更可能被再次访问”,这适合大多数场景,但并非普适。对于周期性访问的数据(如每周一被集中查看的报表),LRU 可能在非活跃周期将其淘汰,导致周期开始时大量重新生成。这时需要结合 TTL、LFU 或人工预热来兜底。

为何常见:缓存策略的知识里 LRU 被讲得最多、最容易理解,于是被当成了万能钥匙,忽略了它背后的访问模式假设。

面试题

Q1. 缓存层最主要解决什么问题?

单选题 · easy

  • A.提高模型精度
  • B.降低调用成本、提升响应速度← 正确答案
  • C.增强数据安全性
  • D.减少代码量

答案:B。缓存层通过“预先存储”高频问题的答案,减少重复调用 LLM,从而降低成本并加快响应。选项 A 与模型训练相关,C、D 与缓存核心收益无关,选项 B 准确地概括了缓存的价值。

Q2. 缓存键设计的核心目标是什么?

单选题 · easy

  • A.让键尽可能长
  • B.让相同的问题映射到相同键← 正确答案
  • C.让所有问题映射到同一个键
  • D.让键随机化

答案:B。缓存键是查询的指纹,好的键设计能让语义相同的请求命中同一缓存。A 中长键浪费空间,C 中所有问题共用一个键会直接导致回答错乱,D 随机化必然无法复用,都可以用“统一标签才能快速找菜”来理解。

Q3. 什么是 TTL 策略?

单选题 · easy

  • A.缓存数据永不过期
  • B.设置缓存数据的保质期,过期后自动失效← 正确答案
  • C.淘汰最久未使用的缓存
  • D.缓存容量满时删除最早的数据

答案:B。TTL(Time To Live)给缓存设“保质期”,到期自动失效。C 是 LRU 淘汰策略,D 是 FIFO 策略,都不属于 TTL 的定义。用“食物保质期”类比,到期就不应该再出售了。

Q4. 以下关于 LRU 淘汰策略的描述,哪项正确?

单选题 · mid

  • A.优先淘汰最早创建的缓存
  • B.优先淘汰最近最少使用的数据← 正确答案
  • C.优先淘汰体积最大的数据
  • D.优先淘汰访问频率最高的数据

答案:B。LRU(Least Recently Used)在容量满时优先淘汰“最久没有被访问”的项。A 是 FIFO 策略,C 是大小优先策略(如 LFU 的变体),D 是 LFU(最不经常使用)策略。类比保温柜:先撤掉最久没人点的菜,而不是最早做的菜。

Q5. 如何提高 LLM 应用的缓存命中率?

单选题 · mid

  • A.尽可能缩短 TTL
  • B.对用户请求做规范化后再生成缓存键← 正确答案
  • C.不缓存任何结论,只缓存过程
  • D.永远不使用淘汰策略

答案:B。请求规范化可以让“同一意思的不同表达”落到同一个键上,从而大幅提升命中率。A 缩短 TTL 反而降低命中率;C 与缓存要“存结果”的理念相悖;D 会导致缓存无限膨胀,不可行。

Q6. 以下哪些策略可以用于保证缓存与源数据的一致性?

多选题 · mid

  • A.源数据更新时主动删除相关缓存← 正确答案
  • B.双写机制,更新源数据时同步更新缓存← 正确答案
  • C.缓存键加入源数据的内容摘要
  • D.引入版本号比对,发现版本不一致时重建缓存← 正确答案

答案:ABD。ABC 都能预防不一致。B 双写是常用的强一致策略之一,但要注意写入失败的处理;D 是兜底的校验手段,保证读取时发现过期数据。C 不能保证一致性,内容摘要作为键的一部分反而降低命中率。

Q7. 在缓存命中率计算中,以下公式正确的是?

单选题 · hard

  • A.命中率 = 缓存量 / 总请求量
  • B.命中率 = 命中次数 / 总请求次数← 正确答案
  • C.命中率 = 未命中次数 / 总请求次数
  • D.命中率 = 命中次数 / 未命中次数

答案:B。命中率的定义是“命中次数 ÷ 总请求次数”。A 用量而非次数,错误;C 计算的是未命中率;D 是一个比值而不是概率。理解方式:100 道菜订单里,70 桌需要现做,30 桌直接上菜,那么命中率就是 30%。

Q8. 关于缓存键设计,下面哪些做法是合理的?

多选题 · hard

  • A.将用户问题规范化之后再哈希作为键← 正确答案
  • B.将模型版本号、Prompt 版本号加入缓存键← 正确答案
  • C.对所有用户共享同一套缓存← 正确答案
  • D.直接用原问题字符串作为键

答案:ABC。A 是缓存键规范化的基础,正确。B 可以有效防止版本变化导致新旧答案混淆,合理。C 对于通用型知识问答是合理的,能最大化命中率;但如果涉及用户个性化数据则不可行。D 不做任何处理,会让语义相同的问题互相之间无法命中,不合理。

Q9. 缓存未命中时,系统应该怎么做?

单选题 · easy

  • A.直接返回错误
  • B.调用 LLM 生成答案,写入缓存后返回← 正确答案
  • C.返回一个空字符串
  • D.无限重试

答案:B。缓存未命中意味着没有现成的答案,此时需要调用 LLM 生成答案,然后回填缓存,供后续请求使用。A 返回错误是严重的事故行为;C 返回空值对用户毫无意义;D 无限重试会放大成本。这正是“先查保温柜、没有就现做并放回保温柜”的流程。

Q10. 某问答系统的日请求量为 1 万次,命中率为 70%,每次 LLM 调用成本约 $0.01,那么日省成本约为多少?

多选题 · extreme

  • A.3000 次调用省下 $30← 正确答案
  • B.7000 次调用省下 $70
  • C.10000 次调用省下 $100
  • D.一天最多节省 $70← 正确答案

答案:AD。命中率 70% 意味着 1 万次请求中 7000 次命中,这 7000 次不需要调用 LLM,省下 7000 × $0.01 = $70,即 D 正确。换个角度,若不缓存,1 万次全调用需 $100;按实际调用 3000 次算,成本为 $30,省下 $70,所以 A 也对。B 误把剩余调用当成节省量,C 夸大了节省上限。这就好比保温柜只省下了那些不用现做的菜的燃气费。