语义缓存成本优化RAG性能优化实战教程

AI API 语义缓存(Semantic Cache)实战指南:让相似请求复用响应,节省 60%+ 成本

2026-09-06 · 约 10 分钟阅读

做 AI 应用后端的人基本都遇到过这种问题:用户反复问"你们的退货政策是什么?""你们的营业时间?""怎么申请退款?",问题文字略有差异,但语义几乎一致。Prompt Caching(官方前缀缓存)只对完全相同的前缀起作用,这种"换了几个字"的问题完全帮不上忙——于是你每次都要花几美分调用一次大模型,请求量一大,月底账单惊人。

语义缓存(Semantic Cache)是另一种思路:把每次问答的"问题"也存进向量库,下次来了相似问题,直接返回上次的答案。实测下来,对客服、知识库、代码补全这类场景,能轻松砍掉 40%-70% 的重复调用。

语义缓存 vs Prompt Caching:别搞混

特性Prompt Caching语义缓存
匹配方式完全相同前缀向量相似度(语义近似)
命中率主要靠稳定 system prompt主要靠用户问题模式稳定
实现方官方(OpenAI/Anthropic)自行实现(GPTCache、Redis + Embedding)
命中粒度token 级整条问答
适用场景长 system prompt + 短 user 输入短 system + 长/重复 user 输入
成本节约主要省 input 重复部分省整次调用的钱

两者不是替代关系,是互补关系。生产环境通常会同时开启:Prompt Caching 负责 system prompt 复用,Semantic Cache 负责整问答复用。

核心原理:三步走

1. 入库:用户问题 → Embedding 向量化 → 存到向量库,连同对应的 LLM 答案一起存

2. 查询:新问题 → Embedding 向量化 → 在向量库里找 Top-K 最相似的历史问答 → 计算相似度

3. 决策:相似度超过阈值(如 0.92)就返回缓存答案,否则正常调用 LLM 并把新问答入库

import numpy as np
from typing import Optional

class SemanticCache:
    def __init__(self, embedding_client, threshold=0.92, ttl_seconds=86400):
        self.embedding_client = embedding_client
        self.threshold = threshold
        self.ttl = ttl_seconds
        self.entries = []  # 生产环境用 Redis + Vector DB

    def _embed(self, text: str) -> np.ndarray:
        # 推荐用 text-embedding-3-small 或 bge-m3,性价比高
        return np.array(self.embedding_client.embed([text])[0])

    def _cosine(self, a: np.ndarray, b: np.ndarray) -> float:
        return float(np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b) + 1e-9))

    def lookup(self, query: str) -> Optional[str]:
        if not self.entries:
            return None
        q_vec = self._embed(query)
        best_score, best_answer = -1.0, None
        for entry in self.entries:
            score = self._cosine(q_vec, entry["vector"])
            if score > best_score:
                best_score, best_answer = score, entry["answer"]
        return best_answer if best_score >= self.threshold else None

    def store(self, query: str, answer: str):
        self.entries.append({
            "vector": self._embed(query),
            "answer": answer,
            "ts": time.time()
        })

用现成框架:GPTCache 5 行代码接入

如果不想自己造轮子,GPTCache 是目前最成熟的语义缓存库,支持 Redis/Milvus/Postgres 等多种后端:

from gptcache import cache
from gptcache.adapter.api import get, put
from gptcache.embedding import OpenAI
from gptcache.similarity_evaluation.distance import SearchDistanceEvaluation

# 初始化
cache.init(
    embedding_func=OpenAI(),
    data_manager="sqlite,faiss",  # 或 "redis,milvus"
    similarity_evaluation=SearchDistanceEvaluation(),
)

def chat_with_cache(question: str) -> str:
    cached = get(question)
    if cached:
        return cached
    answer = call_openai(question)  # 你的正常 LLM 调用
    put(question, answer)
    return answer

GPTCache 帮你处理了向量化、相似度计算、过期清理、缓存淘汰等所有脏活。

阈值怎么设?这是最关键的工程问题

阈值设太高 → 命中率低,省不下钱

阈值设太低 → 错误命中,用户收到错误答案

经验值:

  • 客服/FAQ 场景:阈值 0.88 - 0.92
  • 代码补全场景:阈值 0.94 - 0.96(要更严格,避免错误复用)
  • 通用聊天场景:阈值 0.85 - 0.90
  • 严肃法律/医疗场景:阈值 0.95+,或者干脆不开启

调优技巧:先离线跑一批历史问答日志,看不同阈值下的命中率 + 错误率,画一张曲线图找拐点。

实战要注意的 5 个坑

1. 用户上下文要剥离:缓存 key 应该只包含"问题本体",不要把用户名、订单号这种上下文混进去,否则完全无法命中

2. Embedding 选型决定上限:便宜的就用 text-embedding-3-small,复杂的用 bge-large-v3,中文场景建议专门挑对中文友好的模型

3. 答案要存原始 JSON,别只存字符串:Function Calling 场景下,返回的是结构化 JSON,缓存必须存完整结构

4. 设置合理的 TTL:24 小时是常见默认值,金融/订单类建议几分钟就过期

5. 缓存穿透保护:极冷门的长尾问题反复来,要设置"短时间内不重复计算"的兜底(比如同一个 hash 5 分钟内只调一次)

与中转站怎么配合

如果用中转站接入,建议把语义缓存这一层放在你自己的后端,而不是依赖中转站。原因有三:

1. 数据私密:缓存里的问答往往包含业务敏感数据,中转站是否可信你没法完全控制

2. 缓存策略灵活:自己实现可以根据业务调阈值、调 TTL、调淘汰策略

3. 中转站不稳定时的兜底:当主中转站挂了,缓存能直接顶上来,QPS 不掉

代码层面,语义缓存层放在调用中转站之前:

def answer(question: str) -> str:
    hit = semantic_cache.lookup(question)
    if hit:
        return hit  # 缓存命中,零成本
    fresh = client.chat.completions.create(
        model="gpt-5.6",
        messages=[{"role": "user", "content": question}]
    ).choices[0].message.content
    semantic_cache.store(question, fresh)
    return fresh

成本预估

假设你的应用每天 100 万次问答,30% 语义高度重复,开启语义缓存后:

  • 30% 命中:节省 30 万次调用
  • 每次调用假设 ¥0.03(GPT-4o mini 量级)
  • 每天省 ¥9,000,一个月省 ¥27 万

加上 Redis/向量库的存储成本(一般几千元/月封顶),ROI 极高。

总结

语义缓存是 2026 年 AI 后端工程师的"必修技能",因为它直接对应"省成本"这个最实在的诉求。但它不是 Prompt Caching 的替代品,两者搭配使用效果最佳。生产环境推荐直接用 GPTCache 起步,再根据业务数据调阈值、调 TTL、加监控。如果对中转站选型还有疑问,可以看看 openairouter.net 上对各家中转站的横向对比,重点关注稳定性和价格透明度。

找到最适合你的 AI API 中转站

收录 125+ 服务商,按价格、模型、标签一键筛选

查看所有中转站 →