学习 LangChain 中 Embedding(嵌入)模型的选型与初始化,以及句子的向量化(embed_query)和文档的向量化(embed_documents),完成 RAG 管线的第三环节。
- 作用:将文档切片的文本转化为向量,供后续向量数据库存储和相似度检索。
- 常见提供商与模型:
| 提供商 | 模型示例 | 向量维度 | 特点 |
|---|
| OpenAI | text-embedding-3-small | 1536 | 通用性强 |
| OpenAI | text-embedding-3-large | 3072 | 精度高,成本高 |
| 北京智源研究院 (BGE) | BAAI/bge-large-zh-v1.5 | 1024 | 中文效果优秀 |
| 北京智源研究院 | BAAI/bge-m3 | 1024 | 多语言支持 |
- 维度与精度的关系:维度越高 → 向量化越精细 → 相似度匹配越精准 → 但 Token 消耗越多、越贵。
| 方法 | 输入 | 用途 |
|---|
embed_query(text: str) | 单个句子/查询文本 | 将用户查询向量化,用于检索 |
embed_documents(texts: List[str]) | 字符串列表 | 将文档块批量向量化,用于存储 |
- 写法一(
init_embedding + 前缀):from langchain.embeddings import init_embedding
model = init_embedding("openai/text-embedding-3-large", api_key=..., base_url=...)
- 写法二(直接导入
OpenAIEmbeddings):from langchain_openai import OpenAIEmbeddings
model = OpenAIEmbeddings(model="text-embedding-3-large", api_key=..., base_url=...)
┌──────────────────────────┐
│ 文档 (CSV/TXT/PDF...) │
└───────────┬──────────────┘
│ CSVLoader / TextLoader
▼
┌──────────────────────────┐
│ Document 对象列表 │
└───────────┬──────────────┘
│ load_and_split() / split_documents()
▼
┌──────────────────────────┐
│ List[str] 字符串列表 │ ← 第二环节产物
└───────────┬──────────────┘
│ embed_documents()
▼
┌──────────────────────────┐
│ List[List[float]] 向量 │ ← 第三环节产物
└───────────┬──────────────┘
│ 存入向量数据库
▼
┌──────────────────────────┐
│ Milvus / Chroma / FAISS │
└──────────────────────────┘
用户查询: "你好,很高兴认识你"
│
│ embed_query()
▼
List[float] (查询向量)
│
│ 向量相似度检索
▼
返回最相关的文档块
import os
from dotenv import load_dotenv
load_dotenv(override=True)
from langchain.embeddings import init_embedding
model1 = init_embedding(
"openai/text-embedding-3-large",
api_key=os.getenv("OPENAI_API_KEY"),
base_url=os.getenv("OPENAI_BASE_URL")
)
from langchain_openai import OpenAIEmbeddings
model2 = OpenAIEmbeddings(
model="text-embedding-3-large",
api_key=os.getenv("OPENAI_API_KEY"),
base_url=os.getenv("OPENAI_BASE_URL")
)
model3 = init_embedding(
"openai/BAAI/bge-m3",
api_key=os.getenv("SILICONFLOW_API_KEY"),
base_url=os.getenv("SILICONFLOW_BASE_URL")
)
text = "你好,很高兴认识你"
embedding_result = model1.embed_query(text)
print(f"向量维度: {len(embedding_result)}")
print(f"前5个标量: {embedding_result[:5]}")
texts = [
"人工智能是计算机科学的一个分支。",
"机器学习是实现人工智能的一种方法。",
"深度学习是机器学习的一个重要方向。"
]
embeddings = model1.embed_documents(texts)
print(f"共 {len(embeddings)} 个向量")
print(f"第一个向量的前3个标量: {embeddings[0][:3]}")
from langchain_community.document_loaders import CSVLoader
from langchain_text_splitters import RecursiveCharacterTextSplitter
loader = CSVLoader(
file_path="./data/sample.csv",
encoding="utf-8"
)
splitter = RecursiveCharacterTextSplitter(chunk_size=200, chunk_overlap=20)
docs = loader.load_and_split(text_splitter=splitter)
texts = [doc.page_content for doc in docs]
embeddings = model1.embed_documents(texts)
print(f"共生成 {len(embeddings)} 个向量")
print(f"第一个文档片段: {texts[0]}")
init_embedding 报错 "no provider specified": - 需要加
"openai/" 前缀,或显式传入 provider="openai" 参数。
- 维度不匹配问题:后续创建 Milvus Collection 时,
dimension 参数必须与嵌入模型的输出维度一致(如 1024 或 3072)。 - 费用控制:
embed_documents 会批量调用 API,文档量大时注意 Token 消耗和费用。 - API 兼容:硅基流动、智谱等国内平台大多兼容 OpenAI 的 Embedding API 格式,直接用
openai/ 前缀即可。 .env 文件加载:务必在初始化模型前执行 load_dotenv(override=True),确保环境变量已加载。
- 嵌入模型选型主要考虑三个因素:中文支持质量、向量维度(精度 vs 成本)、API 兼容性。
- 对于中文 RAG 项目,北京智源研究院的 BGE 系列(
bge-large-zh-v1.5、bge-m3)是性价比很高的选择。 embed_query 和 embed_documents 的区别在于输入形式,前者用于用户查询,后者用于文档批量入库。- 本节完成了 RAG 管线的前三个环节串联:加载 → 切分 → 向量化,为下一节存入 Milvus 做好准备。