# CacheBackedEmbedding 的使用与注意事项
# 问题背景
Embedding 缓存用于避免重复向量化。只要文本、模型和预处理规则不变,同一个 chunk 的向量就可以复用。缓存能降低费用、减少延迟,也能避免重建索引时反复调用外部接口。
# 工程要点
这部分能力进入生产前,需要把输入、输出、版本和可观测信息设计清楚。输入包括原始文档、用户问题和业务过滤条件;输出包括 chunk、向量、检索结果、答案和引用来源;版本包括模型版本、切分规则、索引版本和文档更新时间。
不要只验证代码能跑通,还要验证结果是否符合业务问题。可以准备一组固定问题,每次调整参数后观察 Top K 是否命中正确资料、答案是否引用正确来源、延迟和成本是否可接受。
# 源码示例
from langchain_classic.embeddings import CacheBackedEmbeddings
from langchain.storage import LocalFileStore
from langchain_openai import OpenAIEmbeddings
underlying = OpenAIEmbeddings(model="text-embedding-3-small")
store = LocalFileStore("./embedding-cache")
cached_embeddings = CacheBackedEmbeddings.from_bytes_store(
underlying,
store,
namespace=underlying.model,
)
vectors = cached_embeddings.embed_documents([
"RAG 使用检索结果增强生成。",
"向量数据库用于语义相似搜索。",
])
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# 拓展
这类组件通常不是孤立使用。Embedding 会影响向量库召回,切分会影响 Embedding 表达,metadata 会影响过滤和权限,Prompt 会影响模型是否忠于证据。任何一处改动,都可能改变最终回答质量。
建议把 RAG 当成数据工程、检索工程和生成工程的组合系统。先保证数据正确进入索引,再保证检索能稳定召回,最后再优化模型表达。
# 最新版 LangChain 用法提示
当前 API 参考中 CacheBackedEmbeddings 位于 langchain_classic。文档 Embedding 默认会缓存;如果要缓存 query Embedding,需要显式配置 query 侧缓存。无论使用哪个版本,都要把模型名或版本放进 namespace,避免新旧向量混用。
# 常见问题
# 这类组件应该先在什么规模上验证?
先用一小批真实文档和真实问题验证,而不是直接全量入库。验证时至少观察三类结果:检索是否命中正确片段、返回片段是否包含足够上下文、最终回答是否严格基于证据。
# 只看相似度分数够不够?
不够。相似度分数只能说明向量距离,不代表答案一定正确。还要看 chunk 是否完整、metadata 是否正确、过滤条件是否过严或过松,以及 Prompt 是否要求模型只根据上下文回答。
# 参数应该怎么调?
先固定评测问题集,再一次只改一个变量,例如 chunk 大小、overlap、top_k、Embedding 模型或过滤条件。每次改动都记录召回命中率、答案准确率、延迟和成本。
# 面试题
# 1. RAG 链路里最容易被忽略的工程点是什么?
最容易被忽略的是数据处理和评估。很多问题不是 LLM 不会答,而是文档解析错误、chunk 切坏、metadata 丢失、向量版本混乱、检索过滤条件错误,导致模型拿不到正确证据。
# 2. 为什么不能只依赖 LLM 自身参数记忆?
参数记忆存在知识过期、领域知识缺失、事实边界不清和不可追踪的问题。RAG 通过检索外部证据,把回答范围约束在可追踪内容上,适合企业知识库、产品文档和实时资料问答。
# 3. 如何判断一个 RAG 系统的问题出在检索还是生成?
先直接查看检索返回的文档。如果返回内容已经不相关,问题在加载、切分、Embedding、向量库或 Retriever;如果返回内容正确但回答错误,问题多半在 Prompt、上下文压缩、引用组织或模型输出约束。
# 生产问题排查
| 问题 | 常见原因 | 处理方式 |
|---|---|---|
| 回答看起来合理但没有依据 | Prompt 没要求基于上下文,或检索片段不相关 | 增加拒答策略、引用来源、检索结果抽样检查 |
| 召回结果经常跑偏 | chunk 过短、Embedding 模型不适合、query 表达不完整 | 调整切分策略,评估 Embedding,必要时做查询改写 |
| 命中了旧内容 | 文档更新后没有重新入库,或缓存没有区分版本 | 使用文档 hash、版本号、更新时间和重建任务 |
| 多租户数据串库 | metadata filter 缺失或字段设计不严谨 | 强制 tenant_id / dataset_id 过滤,并做权限测试 |
| 成本增长明显 | 重复 Embedding、top_k 过大、无缓存 | 增加缓存、批处理、限流和调用统计 |
| 延迟不稳定 | 向量库网络抖动、LLM 响应慢、检索链路串行 | 并行化可并行步骤,增加超时、重试和降级策略 |