主题
嵌入模型集成
使用 LangChain Python 集成嵌入模型。
概述
嵌入模型会将原始文本——例如一个句子、段落或推文——转换为固定长度的数字向量,用以捕捉其语义含义。这些向量让机器能够基于含义而非精确词语来比较和搜索文本。
在实践中,这意味着含义相近的文本会被放置在向量空间中彼此靠近的位置。例如,嵌入不仅能匹配 "machine learning" 这一短语,还能在措辞不同的情况下找出讨论相关概念的文档。
工作原理
- 向量化:模型将每个输入字符串编码为高维向量。
- 相似度评分:使用数学指标比较向量,以衡量底层文本之间的相关程度。
相似度指标
有几种指标常用于比较嵌入:
- 余弦相似度:衡量两个向量之间的夹角。
- 欧氏距离:衡量点之间的直线距离。
- 点积:衡量一个向量在另一个向量上的投影程度。
下面是一个计算两个向量之间余弦相似度的示例:
python
import numpy as np
def cosine_similarity(vec1, vec2):
dot = np.dot(vec1, vec2)
return dot / (np.linalg.norm(vec1) * np.linalg.norm(vec2))
similarity = cosine_similarity(query_embedding, document_embedding)
print("Cosine Similarity:", similarity)1
2
3
4
5
6
7
8
2
3
4
5
6
7
8
接口
LangChain 通过 Embeddings 接口为文本嵌入模型(例如 OpenAI、Cohere、Hugging Face)提供了标准接口。
提供两个主要方法:
embed_documents(texts: List[str]) → List[List[float]]:嵌入文档列表。embed_query(text: str) → List[float]:嵌入单个查询。
NOTE
该接口允许以不同策略嵌入查询与文档,不过在实践中大多数服务商的处理方式相同。
热门集成
| 集成 | 下载量 | | :- | :- | | [`AzureOpenAIEmbeddings`](https://docs.langchain.com/oss/python/integrations/embeddings/azure_openai) |
| | [`OpenAIEmbeddings`](https://docs.langchain.com/oss/python/integrations/embeddings/openai) |
| | [`GoogleGenerativeAIEmbeddings`](https://docs.langchain.com/oss/python/integrations/embeddings/google_generative_ai) |
| | [`OllamaEmbeddings`](https://docs.langchain.com/oss/python/integrations/embeddings/ollama) |
| | [`DatabricksEmbeddings`](https://docs.langchain.com/oss/python/integrations/embeddings/databricks) |
| | [`Sentence Transformers on Hugging Face`](https://docs.langchain.com/oss/python/integrations/embeddings/sentence_transformers) |
| | [`MistralAIEmbeddings`](https://docs.langchain.com/oss/python/integrations/embeddings/mistralai) |
| | [`CohereEmbeddings`](https://docs.langchain.com/oss/python/integrations/embeddings/cohere) |
| | [`NVIDIAEmbeddings`](https://docs.langchain.com/oss/python/integrations/embeddings/nvidia_ai_endpoints) |
| | [`PerplexityEmbeddings`](https://docs.langchain.com/oss/python/integrations/embeddings/perplexity) |
| | [`TogetherEmbeddings`](https://docs.langchain.com/oss/python/integrations/embeddings/together) |
|
常见部署模式
在实践中,大多数团队会落脚于以下四种模式之一:
- 托管型旗舰:OpenAI
text-embedding-3-large、Cohereembed-english-v3、Googlegemini-embedding-001、Voyagevoyage-3。一次 API 调用即可开箱获得一流的质量,无需本地基础设施。代价是按调用计费以及对数据出境的依赖。 - 本地开源:
BAAI/bge-*、mixedbread-ai/mxbai-embed-*、Qwen/Qwen3-Embedding-*、nomic-ai/modernbert-embed-*、sentence-transformers/all-*。下载一次,随处运行。没有按调用计费,数据永不离开你的环境。在较小规模下,CPU 上可能比托管 API 更慢;配备 GPU 时则具有竞争力甚至更快。 - 本地开源专用模型:针对你的特定领域、语言或任务微调的模型。从一个强大的开源基座(例如
BAAI/bge-m3)起步,即便仅用几千对领域内查询/文档进行微调,往往在检索准确率上也能超越托管旗舰模型。 - 生产规模的自托管:通过 Text Embeddings Inference (TEI) 或 Ollama 提供同样的开源模型(基座或微调后)。让你兼得本地推理的经济性与托管服务商的横向扩展能力和 API 易用性。
LangChain 对四者的处理方式相同:你实例化一个 Embeddings 子类,并将其交给向量存储或检索器。模式 (2) 和 (3) 使用 HuggingFaceEmbeddings;模式 (4) 针对 TEI 的 OpenAI 兼容端点使用 OpenAIEmbeddings,或使用 OllamaEmbeddings。
需要考虑的因素
质量
从 MTEB 排行榜入手。MTEB 在检索、聚类、分类和重排序任务上对嵌入模型进行基准测试,是事实上的行业参考。按你的语言和任务进行筛选(对 RAG 来说,检索最为常见)。
排行榜上的数字并不总能迁移,因此在确定之前,请在自己的数据上做一次小规模评估。LangSmith 为此提供了工具;请参阅评估指南。
成本
托管嵌入的定价通常在每百万 token 几美分到 ~$0.15 的范围内。对于一个仅嵌入一次、每天被查询数千次的语料库,成本往往由查询侧主导。
本地推理没有按调用计费,但需要 CPU(较慢)或 GPU(资本支出或云成本)。两者的分界点取决于工作负载:低量级的个人项目在 CPU 上基本免费;对于中等量级的生产环境,用单块 GPU 通过 TEI 提供本地模型,在单位经济性上往往胜过托管方案。
延迟
托管嵌入 API 每次请求会带来大约 50-200ms 的网络延迟。在 CPU 上,小模型(all-MiniLM-L6-v2 一类)处理一个短查询需要 10-100ms,更大的模型则需要 50-500ms。在 GPU 上,本地推理通常比往返一次托管 API 更快。
对于批量索引,每次请求的延迟没有吞吐量那么重要。TEI 和多进程本地推理会积极地进行批处理。在 GPU 上运行时,可以考虑在 HuggingFaceEmbeddings 上设置 encode_kwargs=""batch_size": 64" 或更高。
维度
嵌入维度会影响向量存储的存储量和查询计算量。典型大小:
- 384(小型 Sentence Transformers 模型,
all-MiniLM-L6-v2) - 768(中型 ST 模型,
all-mpnet-base-v2、bge-base) - 1024(
bge-large、Cohere v3、Voyage) - 1536(OpenAI
text-embedding-3-small、Qwen3-Embedding-0.6B) - 3072+(OpenAI
text-embedding-3-large、Qwen3-Embedding-4B/8B)
更大的向量通常更准确,但会消耗更多存储和查询计算量。若干现代模型(OpenAI text-embedding-3-*、mixedbread-ai/mxbai-embed-large-v1、以 Matryoshka 训练的 ST 模型、Qwen3-Embedding)支持截断:将向量切分到更小的维度,而质量只有平缓的下降。这有助于在更小的索引中容纳更多向量。
上下文长度
大多数经典嵌入模型的上限为 512 个 token(all-mpnet-base-v2、经典 BGE)。较新的模型支持更长的上下文:
nomic-ai/modernbert-embed-base:8192 个 tokenAlibaba-NLP/gte-multilingual-base:8192 个 tokenBAAI/bge-m3:8192 个 token- OpenAI
text-embedding-3-*:8191 个 token
如果你的分块很长(整页技术文档、法律段落),优先选择长上下文模型。对于短分块,512 个 token 的限制很少成为约束。
多语言支持
对于多语言检索,选择在你的语言上训练过的模型。不错的默认选择:
- 开源:
BAAI/bge-m3、intfloat/multilingual-e5-*、Alibaba-NLP/gte-multilingual-*、Qwen/Qwen3-Embedding-*(通过HuggingFaceEmbeddings) - 托管:Cohere
embed-multilingual-v3、OpenAItext-embedding-3-*
查询与文档提示词
若干现代开源模型(E5、BGE、Qwen3-Embedding、GTE)在训练时对查询和文档使用不同的文本前缀。在查询时使用错误的前缀是常见的质量回退原因。使用 HuggingFaceEmbeddings 时,请显式传入提示词:
python
from langchain_huggingface import HuggingFaceEmbeddings
embeddings = HuggingFaceEmbeddings(
model_name="intfloat/e5-large-v2",
encode_kwargs={"prompt": "passage: "},
query_encode_kwargs={"prompt": "query: "},
)1
2
3
4
5
6
7
2
3
4
5
6
7
请在 Hugging Face 上查看各模型的卡片,了解推荐的提示词字符串。
许可
大多数流行的开源嵌入模型采用宽松许可(Apache 2.0、MIT)。少数较新的专用模型在生产环境使用需要商业许可。上线前请检查各模型的许可。
超越单向量稠密嵌入
每个分块使用单个稠密向量是默认做法,但并非唯一选择。
稀疏与混合检索
稠密嵌入在处理精确匹配查询(产品编码、命名实体、代码标识符)方面不如基于关键词的索引。混合检索将稠密索引与 BM25 或稀疏神经索引(SPLADE、BAAI/bge-m3 的稀疏输出)相结合,以覆盖这两种情况。
后交互与多向量
ColBERT 风格的模型为每个 token 生成一个向量(而不是每个分块一个),再通过延迟交互对查询与文档打分。在复杂查询上,这通常比单向量稠密检索更准确,代价是更高的存储开销与更复杂的索引。目前该领域的开源模型包括 jinaai/jina-colbert-v2、answerdotai/answerai-colbert-small-v1,以及较新的延迟交互变体如 lightonai/LateOn。LangChain 内置的检索器面向单向量嵌入;延迟交互通常需要专门的索引(Vespa、Qdrant 的多向量支持,或 PyLate)。
起点建议
如果你只想要一个可用的起点:
- 快速原型、托管:
OpenAIEmbeddings(model="text-embedding-3-small") - 快速原型、本地、无需 API 密钥:
HuggingFaceEmbeddings(model_name="sentence-transformers/all-mpnet-base-v2", encode_kwargs=""normalize_embeddings": True") - 生产环境、托管、质量优先:
VoyageAIEmbeddings(model="voyage-3")或OpenAIEmbeddings(model="text-embedding-3-large") - 生产环境、开源、质量优先:
HuggingFaceEmbeddings(model_name="BAAI/bge-m3", encode_kwargs=""normalize_embeddings": True"),通过 TEI 提供服务 - 多语言、开源:
HuggingFaceEmbeddings(model_name="intfloat/multilingual-e5-large"),并配置好查询与文档提示词
在你自己的数据上度量检索质量,然后迭代。
缓存
嵌入可以存储或临时缓存,以免重复计算。
可以用 CacheBackedEmbeddings 来缓存嵌入。这个包装器把嵌入存入键值存储:文本先被哈希,哈希值用作缓存中的键。
初始化 CacheBackedEmbeddings 主要支持的方式是 from_bytes_store。它接受以下参数:
underlying_embedder:用于生成嵌入的嵌入器。document_embedding_cache:任意用于缓存文档嵌入的ByteStore。batch_size:(可选,默认None)两次存储更新之间嵌入的文档数量。namespace:(可选,默认"")文档缓存使用的命名空间。有助于避免冲突(例如设为嵌入模型的名称)。query_embedding_cache:(可选,默认None)用于缓存查询嵌入的ByteStore,或设为True以复用与document_embedding_cache相同的存储。
WARNING
- 使用不同嵌入模型时,请始终设置
namespace参数以避免冲突。 CacheBackedEmbeddings默认不缓存查询嵌入。要启用该功能,请指定query_embedding_cache。
python
import time
from langchain_classic.embeddings import CacheBackedEmbeddings
from langchain_classic.storage import LocalFileStore
from langchain_core.vectorstores import InMemoryVectorStore
# Create your underlying embeddings model
underlying_embeddings = ... # e.g., OpenAIEmbeddings(), HuggingFaceEmbeddings(), etc.
# Store persists embeddings to the local filesystem
# This isn't for production use, but is useful for local
store = LocalFileStore("./cache/")
cached_embedder = CacheBackedEmbeddings.from_bytes_store(
underlying_embeddings,
store,
namespace=underlying_embeddings.model
)
# Example: caching a query embedding
tic = time.time()
print(cached_embedder.embed_query("Hello, world!"))
print(f"First call took: {time.time() - tic:.2f} seconds")
# Subsequent calls use the cache
tic = time.time()
print(cached_embedder.embed_query("Hello, world!"))
print(f"Second call took: {time.time() - tic:.2f} seconds")1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
在生产环境中,通常应使用更健壮的持久化存储,例如数据库或云存储。可选方案见存储集成。
所有嵌入模型
| 集成 | 下载量 | | :- | :- | | [`AzureOpenAIEmbeddings`](https://docs.langchain.com/oss/python/integrations/embeddings/azure_openai) |
| | [`OpenAIEmbeddings`](https://docs.langchain.com/oss/python/integrations/embeddings/openai) |
| | [`Gemini Enterprise 智能体平台`](https://docs.langchain.com/oss/python/integrations/embeddings/google_vertex_ai) |
| | [`GoogleGenerativeAIEmbeddings`](https://docs.langchain.com/oss/python/integrations/embeddings/google_generative_ai) |
| | [`BedrockEmbeddings`](https://docs.langchain.com/oss/python/integrations/embeddings/bedrock) |
| | [`OllamaEmbeddings`](https://docs.langchain.com/oss/python/integrations/embeddings/ollama) |
| | [`DatabricksEmbeddings`](https://docs.langchain.com/oss/python/integrations/embeddings/databricks) |
| | [`Hugging Face 上的 BGE`](https://docs.langchain.com/oss/python/integrations/embeddings/bge_huggingface) |
| | [`Hugging Face`](https://docs.langchain.com/oss/python/integrations/embeddings/huggingfacehub) |
| | [`Hugging Face 上的 Instructor 嵌入`](https://docs.langchain.com/oss/python/integrations/embeddings/instruct_embeddings) |
| | [`Hugging Face 上的 Sentence Transformers`](https://docs.langchain.com/oss/python/integrations/embeddings/sentence_transformers) |
| | [`文本嵌入推理`](https://docs.langchain.com/oss/python/integrations/embeddings/text_embeddings_inference) |
| | [`FireworksEmbeddings`](https://docs.langchain.com/oss/python/integrations/embeddings/fireworks) |
| | [`MistralAIEmbeddings`](https://docs.langchain.com/oss/python/integrations/embeddings/mistralai) |
| | [`CohereEmbeddings`](https://docs.langchain.com/oss/python/integrations/embeddings/cohere) |
| | [`Pinecone`](https://docs.langchain.com/oss/python/integrations/embeddings/pinecone) |
| | [`NVIDIAEmbeddings`](https://docs.langchain.com/oss/python/integrations/embeddings/nvidia_ai_endpoints) |
| | [`WatsonxEmbeddings`](https://docs.langchain.com/oss/python/integrations/embeddings/ibm_watsonx) |
| | [`PerplexityEmbeddings`](https://docs.langchain.com/oss/python/integrations/embeddings/perplexity) |
| | [`Oracle AI 向量检索生成`](https://docs.langchain.com/oss/python/integrations/embeddings/oracleai) |
| | [`Elasticsearch`](https://docs.langchain.com/oss/python/integrations/embeddings/elasticsearch) |
| | [`BasetenEmbeddings`](https://docs.langchain.com/oss/python/integrations/embeddings/baseten) |
| | [`OCIGenAIEmbeddings`](https://docs.langchain.com/oss/python/integrations/embeddings/oci_generative_ai) |
| | [`TogetherEmbeddings`](https://docs.langchain.com/oss/python/integrations/embeddings/together) |
| | [`SambanovaEmbeddings`](https://docs.langchain.com/oss/python/integrations/embeddings/sambanova) |
| | [`Voyage AI`](https://docs.langchain.com/oss/python/integrations/embeddings/voyageai) |
| | [`UpstageEmbeddings`](https://docs.langchain.com/oss/python/integrations/embeddings/upstage) |
| | [`Naver`](https://guide.ncloud-docs.com/docs/clovastudio-dev-langchain) |
| | [`NomicEmbeddings`](https://atlas.nomic.ai/) |
| | [`OpensolrEmbeddings`](https://opensolr.com/langchain) |
| | [`Cloudflare workers AI`](https://developers.cloudflare.com/ai/models/#text-embeddings) |
| | [`Nebius`](https://docs.tokenfactory.nebius.com/quickstart) |
| | [`AimlapiEmbeddings`](https://docs.aimlapi.com/) |
| | [`PolarDBPGEmbeddings`](https://github.com/polardb/langchain-polardb-pg) |
| | [`Localai`](https://localai.io/features/embeddings/index.html) |
| | [`PredictionGuardEmbeddings`](https://docs.predictionguard.com/api-reference/api-reference/embeddings) |
| | [`BrainiallEmbeddings`](https://app.brainiall.com/docs) |
| | [`DoublewordEmbeddings`](https://docs.doubleword.ai/inference-api/intro-to-doubleword-inference) |
| | [`Modelscope`](https://www.modelscope.cn/docs/sdk/pipelines) |
| | [`ForgeEmbeddings`](https://voxell.ai/forge) |
| | [`Lindorm`](https://help.aliyun.com/en/lindorm/product-overview/product-introduction-overview) |
| | [`Netmind`](https://github.com/protagolabs/langchain-netmind) |
| | [`GreenNodeEmbeddings`](https://greennode.ai/) |
| | [`EmpirioLabsEmbeddings`](https://docs.empiriolabs.ai) |
| | [`TelnyxEmbeddings`](https://developers.telnyx.com/docs/inference/models) |
| | [`ANEEmbeddings`](https://github.com/sbryngelson/langchain-aneforge) |
| | [`KeiroEmbeddings`](https://github.com/Keirolabs-API/langchain-keiro) |
| | [`Isaacus`](https://isaacus.com/docs) |
|