如何用 LiteLLM 缓存为大模型重复请求降本提速
【免费下载链接】litellmThe fastest, litest AI Gateway. Rust core with Python SDK. Call 100+ LLM APIs in OpenAI (or native) format with cost tracking, guardrails, load balancing, and logging [Bedrock, Azure, OpenAI, Anthropic, OpenAI, VertexAI, vLLM, Nvidia NIM]项目地址: https://gitcode.com/GitHub_Trending/li/litellm
如果你的应用每天向同一个大模型接口发出大量内容雷同的请求,那么账单上的重复计费和秒级的等待延迟多半来自同一件事:相同的输入被反复完整调用。LiteLLM 缓存机制就是在调用链中间加一层"结果复用"——命中已有结果时直接返回,不再请求上游模型。本文从问题出发,讲清楚缓存后端怎么选、几行代码怎么开、过期策略怎么定、效果怎么度量,以及落地前容易踩的几个坑,帮你把重复的 LLM 调用变成一次性的成本。
重复调用为什么会又慢又贵
一次大模型请求要经历网络往返、排队、推理三个阶段,其中推理耗时和 token 费用与请求内容完全相关。当请求重复时,这两项支出没有任何变化,属于纯粹的浪费。
判断"重复"最简单可靠的依据是缓存键:LiteLLM 会把模型名、消息内容、关键参数做确定性摘要,得到同一个请求的唯一指纹。指纹命中且未过期,即视为缓存命中。缓存命中率就是命中次数占总请求的比例,它是衡量缓存价值的第一个数字——对 FAQ、分类、抽取这类高重复度场景,命中率轻松超过 70%;对开放式对话则可能只有个位数。
所以缓存不是开关,而是杠杆:杠杆的大小取决于你业务里"可复用输入"的占比。先估算这个占比,再决定投入多少在基础设施上。
五种缓存后端,按部署规模选
LiteLLM 把所有后端收敛在同一个Cache入口后面,切换后端只改构造参数。选型时可以对照下表:
| 后端类型 | 数据去向 | 命中方式 | 适用场景 |
|---|---|---|---|
| local(内存) | 进程内字典 | 完全相同 | 单机应用、开发测试 |
| disk(磁盘) | 本地文件 | 完全相同 | 需重启后保留、无外部依赖 |
| redis | Redis 实例 | 完全相同 | 多进程/多实例共享,生产主流选择 |
| dual(双写) | 内存 + Redis | 先查内存再查 Redis | 高 QPS 下减少 Redis 往返 |
| redis-semantic / qdrant-semantic | 向量索引 | 语义相近即可 | 同义改写、措辞漂移的长尾问题 |
两点需要在选型时说透:
- 命名空间:相当于给缓存键统一加前缀,不同业务或不同环境的数据各自隔离,互不覆盖。Redis 后端建议显式指定,例如
namespace="billing"。 - TTL(Time To Live):缓存条目从写入到自动失效的秒数。不设置则长期有效,靠手动或容量策略清理。
内存缓存零依赖,是验证缓存收益最快的起点;确认有效后再迁移到 Redis,业务代码不用改,只换构造参数——这是这个抽象层最大的工程价值。
如何开启 LiteLLM 缓存:三步落地
第一步,全局挂载缓存。下面这段代码先挂一个进程内缓存,并把 Redis 的等价写法留在注释里,方便单机验证后直接切换:
import litellm from litellm.caching import Cache # 起点:进程内内存缓存,零外部依赖 litellm.cache = Cache(type="local") # 多实例部署时换成这一行即可,业务代码不变 # litellm.cache = Cache(type="redis", host="10.0.0.5", port=6379, # namespace="faq-service")第二步,保持默认行为不变。挂载之后completion调用自动先查缓存、未命中才透传上游,命中时直接把缓存的响应对象返回,调用方无感知。
第三步,对个别请求做精细控制。同一套 API 里,你可以按请求粒度决定"这条要不要缓存、缓存多久、放在哪个键空间":
response = litellm.completion( model="gpt-4o-mini", messages=[{"role": "user", "content": "如何重置数据库密码?"}], cache={ "s-maxage": 3600, # 本条结果缓存 1 小时后失效 "namespace": "faq", # 与全局命名空间隔离的独立键空间 }, )cache字典还支持no-store(本次结果不写入缓存)和no-cache(本次只查不存),例如敏感查询、要求实时性的调用可以直接标为no-cache,避免拿到几小时前的旧答案。
让缓存更聪明:语义匹配与跨模型复用
精确匹配有一个天花板:用户把"怎么改密码"问成"如何重置登录凭证",指纹不同,缓存失守。语义缓存解决的正是这一层。它把每条输入先转成向量再入库,查询时按含义而非文本比较;相似度阈值 0.95 表示"含义接近程度超过 95% 才返回旧结果",阈值越严越安全、命中率越低,通常从 0.9 起步,观察误命中率再收紧:
litellm.cache = Cache( type="redis-semantic", host="10.0.0.5", port=6379, similarity_threshold=0.95, # 语义接近度超过该值才判定为命中 )除了纵向的"同义命中",LiteLLM 还支持横向的跨模型复用:给metadata传入caching_groups,同组模型共享同一个缓存键。当业务从 gpt-4o 灰度切到 claude 时,切换前的调用结果立刻可被复用,切换窗口期的账单不会翻倍:
response = litellm.completion( model="gpt-4o", messages=messages, metadata={"caching_groups": [["gpt-4o", "claude-3-5-sonnet"]]}, )需要留意的是语义缓存依赖一个 embedding 模型做向量化,默认使用 OpenAI 的文本嵌入模型,这会带来少量额外调用;对私有化部署,可换成自托管的嵌入端点。
如何设置合理的过期时间
过期策略分三层,从粗到细:
- 全局默认 TTL:构造参数里
ttl指定所有条目的生存秒数,default_in_redis_ttl可单独覆盖 Redis 侧默认值,比如把 FAQ 类答案设为86400(一天),把行情类数据压到几分钟。 - 按请求覆盖:上文
cache字典里的s-maxage只对该条结果生效,优先级高于全局值。 - 主动失效:当业务数据源头变更(配置更新、文档改版)时,调用缓存的删除接口按命名空间或键批量清理,比等 TTL 自然到期更干净。
定 TTL 的实用原则:以"源数据的最长保鲜期"为准,而不是"业务有多保守"。答案 30 天不变就设 30 天,为了安全压到 10 分钟只会把命中率白白打低,还要多付上游调用的钱。
如何度量缓存效果:命中率、时延与成本账
缓存上线后如果没有度量,很快会退化成"感觉有用"。建议盯住三个指标:
- 命中率:按后端和命名空间分别统计,能定位是哪类请求在贡献命中、哪类在空转;
- 时延分布:命中请求应落在毫秒级,若 P50 没有明显下移,说明请求根本没走到查缓存路径;
- 费用差值:命中即零 token 计费,用命中请求数乘以该模型均价,就是缓存每月省下的钱。
把 LiteLLM 接上 Langfuse 之类的追踪工具后,每次调用都会留下完整的追踪记录,延迟、token 数、费用一目了然,缓存收益可以直接在 trace 里对账:
除了命中率,还要监控缓存存储占用。Redis 侧用INFO memory看驻留大小,语义索引的向量库条目数会随请求量线性增长,TTL 设置过长的条目是主要的膨胀来源。
落地前容易踩的四个坑
- 把非确定性输出当确定性输出缓存。模型带随机性时,同一输入每次答案不同;缓存第一个答案后,用户看到的是"冻结"的输出。对此类调用要么标
no-cache,要么把temperature归零后再缓存。 - 多用户共键。把用户身份(user id、team id)排除在消息之外的请求很容易跨用户命中,A 看到 B 的定制答案。要么把用户标识写进消息内容,要么按用户开命名空间。
- 语义阈值一刀切。0.95 对 FAQ 合适,对"总结这段代码"这类任务型请求可能把两个不同文件的总结混到一起。语义缓存应按业务线单独调阈值,而不是全局一个数。
- 流式与工具调用场景未验证。缓存的是完整响应对象,启用前先确认你的链路(含工具调用、流式拼装)能正确处理缓存返回的对象结构,避免上线后在边缘路径上炸出异常。
LiteLLM 缓存的价值不在开关本身,而在命中率与成本账本上:先用内存缓存测出可复用占比,再按规模迁到 Redis 或语义后端,用 TTL 和命名空间管住数据新鲜度,最后用追踪工具对账收益。下一步建议:挑一个重复度最高的接口(如 FAQ 或分类),挂上Cache(type="local")跑一天,把命中率数字算出来,再决定要不要为它上 Redis。
【免费下载链接】litellmThe fastest, litest AI Gateway. Rust core with Python SDK. Call 100+ LLM APIs in OpenAI (or native) format with cost tracking, guardrails, load balancing, and logging [Bedrock, Azure, OpenAI, Anthropic, OpenAI, VertexAI, vLLM, Nvidia NIM]项目地址: https://gitcode.com/GitHub_Trending/li/litellm
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考