前言 切分得到的文本块要变成可检索的向量,才能写入向量库做相似度搜索。嵌入模型(Embedding) 把句子或文档映射成固定维浮点向量;相近语义在向量空间中更接近。 本文讲 LangChain 1.x 下如何用 init_embeddings / OpenAIEmbeddings 初始化模型,以及对句子、文档做向量化。 聊天模型与嵌入模型是两套能力:ark-code-latest 不能当嵌入用。 整链见《LangChain 06:RAG 概要》;加载与切分见《LangChain 07:文档加载器》《LangChain 08:文本切分器》;入库见《LangChain 10:Milvus 入库》。 下文需要 Python 3.12+ ,依赖用 uv 管理。 示例脚本放在代码子目录,在该目录执行 uv run python xxx.py。
依赖 建议使用 Python 3.12 及以上。 用 uv 初始化工程并声明依赖(版本请按项目实际调整)。
1 2 3 4 uv init langchain-embeddings cd langchain-embeddingsuv venv --python 3.12 uv add "langchain>=1.0,<2.0" langchain-openai python-dotenv rich
后续可直接 uv run python demo.py。 若习惯激活,Windows 使用 .venv\Scripts\activate,macOS / Linux 使用 source .venv/bin/activate。
在项目根目录创建 .env(不要提交进 Git),按你实际开通的嵌入服务填写。 下面以硅基流动为例(OpenAI 兼容协议);也可换成 CloseAI 等其它兼容端点。
1 2 SILICONFLOW_API_KEY=你的硅基流动 API Key SILICONFLOW_BASE_URL=https://api.siliconflow.cn/v1
若用 CloseAI,可改为 CLOSEAI_API_KEY / CLOSEAI_BASE_URL,模型名换成该平台提供的嵌入模型。
实现 初始化模型 推荐用 init_embeddings,前缀 openai: 表示走 OpenAI 兼容客户端。Pro/BAAI/bge-m3 在硅基流动上常见输出维度为 1024 ,入库时维度必须与 Collection 一致。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 import osfrom dotenv import load_dotenvfrom langchain.embeddings import init_embeddingsfrom rich import print as rprintload_dotenv(override=True ) embedding_model = init_embeddings( model="openai:Pro/BAAI/bge-m3" , api_key=os.environ["SILICONFLOW_API_KEY" ], base_url=os.environ["SILICONFLOW_BASE_URL" ], ) rprint(type (embedding_model))
也可用 OpenAIEmbeddings 直连同一兼容端点(效果等价,写法更「OpenAI 风格」)。
1 2 3 4 5 6 7 8 9 10 11 12 import osfrom dotenv import load_dotenvfrom langchain_openai import OpenAIEmbeddingsload_dotenv(override=True ) embedding_model_alt = OpenAIEmbeddings( model="Pro/BAAI/bge-m3" , api_key=os.environ["SILICONFLOW_API_KEY" ], base_url=os.environ["SILICONFLOW_BASE_URL" ], )
CloseAI 等平台只需换 Key、Base URL 与模型名,例如 openai:text-embedding-3-large(维数以厂商文档为准,常与 bge-m3 不同)。
句子向量化 单条查询用 embed_query,返回 list[float]。 检索时用户问题通常走这条 API。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 import osfrom dotenv import load_dotenvfrom langchain.embeddings import init_embeddingsfrom rich import print as rprintload_dotenv(override=True ) embedding_model = init_embeddings( model="openai:Pro/BAAI/bge-m3" , api_key=os.environ["SILICONFLOW_API_KEY" ], base_url=os.environ["SILICONFLOW_BASE_URL" ], ) text = "你好,很高兴认识你" vec = embedding_model.embed_query(text) rprint(len (vec)) rprint(vec[:5 ])
维数应与所选模型一致(bge-m3 多为 1024)。 前几维只用于确认调用成功,不必人工解读数值含义。
文档向量化 多条文本用 embed_documents,返回与输入等长的向量列表。 入库前对切分后的 page_content 列表调用即可。
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 import osfrom dotenv import load_dotenvfrom langchain.embeddings import init_embeddingsfrom rich import print as rprintload_dotenv(override=True ) embedding_model = init_embeddings( model="openai:Pro/BAAI/bge-m3" , api_key=os.environ["SILICONFLOW_API_KEY" ], base_url=os.environ["SILICONFLOW_BASE_URL" ], ) texts = [ "Hi there!" , "Oh, hello!" , "What's your name?" , "My friends call me World" , "Hello World!" , ] vectors = embedding_model.embed_documents(texts) for text, vec in zip (texts, vectors): rprint(f"{text} -> {vec[:3 ]} " )
结合 CSV 文档 可先把表格读成 Document,再对 page_content 批量嵌入。 样例文件放在代码上级的 data/,路径用 ../data/...。
创建 articles.csv 在 ../data/articles.csv 中写入:
1 2 3 id,title,content,author 1,Introduction to Python,Python is a popular programming language.,John Doe 2,Data Science Basics,Data science involves statistics and machine learning.,Jane Smith
加载并嵌入 避免已日落的 langchain-community,用标准库读 CSV 再嵌入。
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 28 29 30 31 32 33 34 35 import csvimport osfrom pathlib import Pathfrom dotenv import load_dotenvfrom langchain.embeddings import init_embeddingsfrom langchain_core.documents import Documentfrom rich import print as rprintload_dotenv(override=True ) path = Path("../data/articles.csv" ) docs: list [Document] = [] with path.open (encoding="utf-8" , newline="" ) as f: for i, row in enumerate (csv.DictReader(f)): page_content = "\n" .join(f"{k} : {v} " for k, v in row.items()) docs.append( Document( page_content=page_content, metadata={"source" : str (path), "row" : i}, ) ) embedding_model = init_embeddings( model="openai:Pro/BAAI/bge-m3" , api_key=os.environ["SILICONFLOW_API_KEY" ], base_url=os.environ["SILICONFLOW_BASE_URL" ], ) texts = [d.page_content for d in docs] vectors = embedding_model.embed_documents(texts) rprint(len (vectors)) for text, vec in zip (texts, vectors): rprint(f"{text} \n{vec[:3 ]} \n" )
真实 RAG 中通常先切分再 embed_documents,而不是整表一行不切。
本地还是在线 嵌入 多数情况优先在线 API ;隐私/内网或长期高 QPS 再考虑本地 GPU。 选型对照见《LangChain 06:RAG 概要》中「本地还是在线」;本文示例按在线兼容端点书写。 换本地时仍须保证入库与检索使用同一模型与同一维数。
验证
配置 .env 后跑「句子向量化」,打印维数应符合模型说明。
跑「文档向量化」,向量条数等于文本条数。
跑「结合 CSV」,每行文档都有对应向量预览。
总结
用 init_embeddings("openai:模型名", api_key=..., base_url=...) 对接兼容服务。
查询用 embed_query;批量文档用 embed_documents。
维数必须与后续向量库 Collection 的 dimension 一致。
默认优先在线嵌入;换本地时仍保持同一模型与维数。
下一步把向量写入 Milvus,见《LangChain 10:Milvus 入库》。