私有文档问答要先把文本变成向量,再进向量库做相似度检索。各云厂商 Embedding API 的请求格式、维度、批大小限制不同。Embeddings 抽象把「一段或多段文本 → list[float] 向量」统一成两个入口:embed_query(单条检索)与 embed_documents(批量建库)。
段末注释:Embeddings = 文本嵌入(text embedding)模型的 LangChain 封装,输出固定维度的浮点向量。
1. 一句话定位
| 维度 | 内容 |
|---|---|
| 角色 | 能力层向量化:为 RAG 索引与 query 编码 |
| 输入 → 输出 | str 或 list[str] → list[float] 或 list[list[float]] |
| 典型调用入口 | embeddings.embed_query(...)、embeddings.embed_documents(...) |
| 与 LangGraph | 通常作为索引离线步骤或 RAG 节点内一步;图编排见 LangGraph 目录 |
2. 实现逻辑
建库 + 检索的典型流程:
1 | 1. 文档切分 → list[str] chunks |
字段级变形:
1 | "LangChain 是什么?" → embed_query → [0.12, -0.03, ..., 0.08] # len=1536 等 |
3. 原理说明
3.1 Embeddings 基类
langchain_core.embeddings.Embeddings 定义 embed_documents 与 embed_query。检索时 query 与 document 应使用同一模型、同一维度,否则相似度无意义。
Embeddings(抽象类)
功能:str / list[str] → 定长浮点向量。子类如 HuggingFaceEmbeddings、OpenAIEmbeddings。
默认值:model / model_name 视集成(HF 类默认常为 sentence-transformers/all-mpnet-base-v2)。
最小维度:文本至少 1 段非空 str;输出向量 dim 由模型固定(本系列示例多语言 MiniLM 为 384)。
embed_query(text: str)(方法)
功能:编码单条检索问句。无额外默认参数。
最小维度:text 长度 ≥1 字符;返回 list[float],len == d。
1 | v = embeddings.embed_query("什么是 RAG?") # len(v) == 384 |
embed_documents(texts: list[str])(方法)
功能:批量编码入库文本,内部按 batch 切分。
最小维度:texts len≥1(空列表返回 []);每条建议非空;返回 list[list[float]],形状 (n, d)。
1 | vecs = embeddings.embed_documents(["chunk A", "chunk B"]) # n=2, d=模型维 |
3.2 query 与 document 是否区分
部分模型(如 BGE)对 query/document 用不同前缀;OpenAI text-embedding-3-* 通常同一接口。
HuggingFaceEmbeddings(数据类 / 实现)
功能:本地 Sentence Transformers 推理,无需 API Key。
| 字段 | 类型 | 默认值 | 最小维度 |
|---|---|---|---|
model_name |
str | all-mpnet-base-v2 |
非空模型 ID |
model_kwargs |
dict | {} |
可空;device 常用 "cpu" |
encode_kwargs |
dict | {} |
可空;检索建议 normalize_embeddings=True |
cache_folder |
str / None | None |
走 HF 默认缓存 |
1 | HuggingFaceEmbeddings( |
3.3 批处理与 rate limit
embed_documents 内部常按 batch 切分;云 API 大批量应控并发,避免 429。维度写入 VectorStore 前须与 collection schema 一致。
OpenAIEmbeddings(实现类)
功能:调用云 Embedding API。默认 model="text-embedding-3-small"(dim 1536,可 dimensions 截断)。
最小维度:同基类;api_key 从环境变量读取,构造器可省略。
3.4 与 VectorStore 的关系
多数 VectorStore 构造时传入 embedding=embeddings,add_documents 时自动调 embed_documents;也可手动算向量再 add_embeddings。
add_embeddings(VectorStore 方法,视实现)
功能:已有向量直接入库,跳过再编码。
最小维度:texts / embeddings 等长,len≥1;每条向量 len == d。
3.5 向量落盘
embed_documents 只返回内存 list[list[float]]。小库写 JSON {model, docs, vectors};规模上来用 FAISS save_local 或 Chroma persist_directory。加载后只对用户问题调 embed_query。
落盘 JSON 最小结构(数据约定,非官方类)
| 字段 | 类型 | 默认值 | 最小维度 |
|---|---|---|---|
model |
str | 必填 | 非空,加载时须与当前模型一致 |
dim |
int | 必填 | ≥1,且等于 len(vectors[0]) |
docs |
list[str] | 必填 | len≥1 |
vectors |
list[list[float]] | 必填 | 形状 (len(docs), dim) |
1 | payload = {"model": MODEL, "dim": len(vectors[0]), "docs": docs, "vectors": vectors} |
4. 最小可运行示例
社区方案:langchain-huggingface + Sentence Transformers 本地推理(官方集成,无需 API Key)。
- 场景:离线建库、内网/隐私文本、无云额度原型。
- 做法:
embed_documents批量编码 → JSON 落盘(原文 + 向量 + 模型名)→ 下次启动只embed_query检索。 - 风险:首次下载权重(本例约 120MB);换模型必须重建文件;JSON 只适合小库;
normalize_embeddings必须与检索度量一致(归一化后点积 = 余弦相似度)。
段末注释:L2 归一化 = 把向量长度缩到 1;开启后点积与余弦相似度数值相同。
1 | pip install -U langchain-huggingface sentence-transformers |
1 | import json |
接 OpenAI(需 OPENAI_API_KEY)时只换构造器,落盘与检索逻辑不变:
1 | from langchain_openai import OpenAIEmbeddings |
重要配置参数
| 参数(API 名) | 类型 / 默认值 | 功能说明 | 作用与影响 | 参考起点 | 配置指导 |
|---|---|---|---|---|---|
model / model_name |
str,构造器 | 选定嵌入模型,决定语义空间与输出维 d |
换模型必须重建索引,否则召回崩溃 | 多语言 MiniLM / text-embedding-3-small |
建库与查询必须同一模型 |
encode_kwargs.normalize_embeddings |
bool,默认 False | 编码后是否 L2 归一化(点积=余弦) | True 才能用点积检索;与落盘向量必须一致 | True(点积检索) | 中途改此值须重算全部向量 |
model_kwargs.device |
str | 指定本地推理设备 | cuda 加速、cpu 更稳 |
cpu |
无 GPU 勿填 cuda |
cache_folder |
str,可选 | 本地权重缓存目录 | 不设则走 HF 默认缓存 | Hugging Face 默认 | 内网预先下载到此目录 |
dimensions |
int,部分云模型可选 | 截断输出向量维数 | 越小越省存储、召回可能变差 | 1536 / 256 | 必须与已落盘 dim 一致 |
chunk_size |
int,云集成常见 | 一次 API 最多送多少条文本 | 过大易 413/429;过小吞吐低 | 100~1000 | 批量建库按厂商限额拧 |
max_retries |
int | 云 API 失败自动重试次数 | 提高建库成功率、拉长尾延迟 | 2~6 | 批量索引建议保留 |
api_key |
str | 云 Embedding 鉴权 | 本地 HF 不需要 | 环境变量 | 勿进仓库 |
5. 易踩坑
- 索引与查询用了不同 Embeddings 模型:召回率骤降,且不易从日志直接看出;落盘文件须写入并校验
model。 - 把 embed_documents 结果当 embed_query 混用维度:自定义 pipeline 时须校验
len(v)与落盘dim一致。 - 每次启动都对全量文档再跑 embed_documents:应加载已落盘向量,只对 query 编码。
- 未归一化却用点积当余弦:
normalize_embeddings与检索公式必须同一套。
小结
- Embeddings 提供 embed_query / embed_documents 双入口,是 RAG 向量化的标准接口。
- 建库与检索须 同一模型、同一维度。
embed_documents结果须自行落盘(或交给 VectorStore);查询阶段只embed_query。- 本地真实语义用 HuggingFaceEmbeddings + Sentence Transformers,无需 API Key。