菜鸟AI - 让提示词生成更简单! 全站导航 全站导航
AI工具安装 新手教程 进阶教程 辅助资源 AI提示词 热点资讯 技术资讯 产业资讯 内容生成 模型技术 AI信息库

已有账号?

首页 > AI教程 > LangChain向量嵌入与语义表示实战推荐榜单
进阶教程 综合资讯

LangChain向量嵌入与语义表示实战推荐榜单

2026-06-01
阅读 0
热度 0
作者 菜鸟AI编辑部
摘要

摘要

向量嵌入将文本映射为数值向量,实现语义检索。LangChain提供统一接口,对接OpenAI、HuggingFa

在LangChain的生态系统中,向量嵌入是所有语义检索功能的核心基础设施。无论是构建RAG、智能问答系统,还是对文本进行分类,底层都依赖它——它首先将人类语言转换为机器可计算的数值。本章从最基础的概念出发,逐步梳理如何对接各类嵌入模型、在本地运行以及优化性能,最后通过实战将技术文档转化为具体的向量表示。所有代码均可直接复制运行,新手也能轻松跟上。

第8章 向量嵌入与语义表示(LangChain实战)

8.1 什么是 Embedding?为何用于检索?

8.1.1 核心定义:文本的“数值指纹”

Embedding(嵌入)本质上是一种语义编码技术。它将任何文本——单词、句子或整篇文档——映射到一个高维数值向量空间中。在这个向量空间里,语义越相似的文本,其向量的距离就越接近。

举一个直观的例子:

  • “猫”的向量可能是 [0.82, -0.15, 0.33, ..., 0.21]

  • “狗”的向量可能是 [0.79, -0.18, 0.31, ..., 0.23]

  • “苹果”的向量可能是 [-0.22, 0.85, -0.17, ..., 0.09]

可以看到,“猫”和“狗”在向量空间中距离很近,因为它们同属动物,语义相似;而它们与“苹果”的距离则很远,因为语义关系疏远。这正是Embedding的核心价值:将抽象的语义转化为可计算、可比较的数值。

8.1.2 为何用于检索?超越传统关键词匹配

传统的关键词检索(如MySQL的like查询)存在一个致命缺陷:它仅匹配字面字符串,无法理解语义相似性。例如,搜索“如何用LangChain做RAG”可能找不到“LangChain搭建检索增强生成系统”这篇文章,尽管两者语义相同。而Embedding检索则能解决这个问题。

Embedding检索的工作流程非常清晰:

  1. 提前将所有文档转换为嵌入向量,存储在向量数据库中;

  2. 用户提问时,将问题也转换为嵌入向量;

  3. 计算查询向量与数据库中文档向量的距离,返回距离最近(最相似)的文档。

这正是LangChain中RAG的核心流程之一。Embedding充当了连接人类语言与机器检索能力的关键桥梁。

8.1.3 关键提醒

需要明确的是:LangChain本身不生产嵌入模型,它更像一个集成平台。它提供统一的接口,让开发者能轻松对接OpenAI、Hugging Face、本地模型等。只需改动一行代码,就能切换底层模型,无需关心具体调用细节。

8.2 使用 OpenAI、Hugging Face、Sentence-Transformers 生成嵌入

本节聚焦三种最主流的嵌入方式。代码力求精简,直接复制即可运行,依赖安装和参考来源一并注明。

8.2.1 准备工作:安装核心依赖

无论使用哪种模型,先安装基础工具:

pip install langchain# 核心框架pip install python-dotenv# 管理环境变量(用于存储API密钥)

8.2.2 OpenAI Embeddings(行业标准,精度高)

OpenAI的嵌入模型(如text-embedding-ada-002)性价比高,是生产环境的主流选择。当然,前提是需要OpenAI API密钥。

代码示例(简短可运行)

from langchain.embeddings.openai import OpenAIEmbeddingsfrom dotenv import load_dotenvimport os

# 加载环境变量(.env文件中存OPENAI_API_KEY=你的密钥)load_dotenv()

# 初始化OpenAI嵌入模型embeddings = OpenAIEmbeddings(model="text-embedding-ada-002",# 推荐模型,性价比最高openai_api_key=os.getenv("OPENAI_API_KEY"))

# 生成单句嵌入text = "LangChain向量嵌入实战"embedding = embeddings.embed_query(text)# 检索时用embed_query,文档用embed_documentsprint(f"嵌入向量维度:{len(embedding)}")# 输出1536(ada-002固定维度)print(f"嵌入向量前5位:{embedding[:5]}")

关键说明

  • embed_query 专门用于生成用户查询的嵌入,会针对检索精度进行优化;

  • embed_documents 用于生成文档的嵌入;

  • 需额外安装 openai 包(pip install openai)。

8.2.3 Hugging Face Embeddings(开源免费)

Hugging Face上提供大量免费开源嵌入模型,例如all-MiniLM-L6-v2,无需API密钥,非常适合本地开发或预算有限的项目。

代码示例

from langchain.embeddings import HuggingFaceEmbeddings

# 初始化Hugging Face嵌入模型(自动下载模型)embeddings = HuggingFaceEmbeddings(model_name="all-MiniLM-L6-v2",# 轻量模型,速度快,适合入门model_kwargs={"device": "cpu"},# 若有GPU,改为"cuda"encode_kwargs={"normalize_embeddings": True}# 归一化,提升检索精度)

# 批量生成文档嵌入texts = ["LangChain是一个大模型开发框架","Embedding用于将文本转为向量","Hugging Face提供开源嵌入模型"]embeddings_list = embeddings.embed_documents(texts)print(f"批量生成{len(embeddings_list)}个嵌入,每个维度:{len(embeddings_list[0])}")

关键说明

  • 需安装 sentence-transformers 包(pip install sentence-transformers);

  • model_name 可替换为其他模型(如 all-MiniLM-L12-v2),精度更高但速度略慢。

8.2.4 Sentence-Transformers(专为句子嵌入优化)

Sentence-Transformers库专注于句子或段落级别的嵌入。LangChain提供了专用接口,本质上是对Hugging Face模型的一层封装,使用更简洁。

代码示例

from langchain.embeddings.sentence_transformer import SentenceTransformerEmbeddings

# 初始化Sentence-Transformers嵌入模型embeddings = SentenceTransformerEmbeddings(model_name="all-MiniLM-L6-v2")

# 生成单句嵌入text = "Sentence-Transformers专注于句子语义嵌入"embedding = embeddings.embed_query(text)print(f"嵌入向量维度:{len(embedding)}")

关键说明

与直接使用HuggingFaceEmbeddings相比,SentenceTransformerEmbeddings接口更清爽,默认执行归一化,省去冗余操作。适合句子级嵌入任务。

8.3 本地嵌入模型部署(BGE、text2vec)

当数据敏感、无法调用第三方API,或需要离线运行时,本地部署嵌入模型是最佳选择。重点介绍两个对中文友好的模型:BGE(中文检索效果公认优秀)和text2vec(轻量高效),它们都能通过LangChain在本地运行。

8.3.1 本地部署核心前提

  • 环境:Python 3.8及以上,建议安装PyTorch(CPU即可,GPU加速更佳);

  • 依赖:一行命令搞定——pip install sentence-transformers torch

  • 模型获取:首次运行时自动下载(几百MB到几个GB不等),也可手动从Hugging Face下载后本地加载。

8.3.2 BGE模型部署(中文首选)

BGE(BAAI General Embedding)由智源AI推出,中文语义理解能力强,支持长文本(最长8192 token),是中文RAG场景的首选。推荐直接使用BGE-M3版本。

代码示例(本地加载)

from langchain.embeddings import HuggingFaceEmbeddings

# 本地部署BGE-M3(自动下载,首次较慢)embeddings = HuggingFaceEmbeddings(model_name="FlagAI-Open/BGE-M3",model_kwargs={"device": "cpu",# 若有GPU,替换为"cuda""trust_remote_code": True# 必须为True,BGE含自定义代码},encode_kwargs={"normalize_embeddings": True,# 务必归一化,否则相似度不准确"max_length": 8192# BGE-M3支持长文本,按需调整})

# 测试中文嵌入text = "LangChain本地部署BGE嵌入模型"embedding = embeddings.embed_query(text)print(f"BGE-M3嵌入维度:{len(embedding)}")# 输出1024维print(f"嵌入向量前5位:{embedding[:5]}")

关键说明

  • 模型版本:推荐BGE-M3;轻量版BGE-base-zh适合算力有限的设备。

  • GPU加速:若安装PyTorch-GPU,将device改为"cuda",生成速度提升5-10倍。

  • 本地加载:将model_name改为本地路径(如"./BGE-M3"),避免重复下载。

8.3.3 text2vec模型部署(轻量高效)

text2vec是专为中文设计的轻量嵌入模型,体积约100MB,速度极快,在笔记本CPU上也能流畅运行,足以满足日常开发需求。

代码示例

from langchain.embeddings import HuggingFaceEmbeddings

# 本地部署text2vec模型embeddings = HuggingFaceEmbeddings(model_name="shibing624/text2vec-base-chinese",model_kwargs={"device": "cpu"},encode_kwargs={"normalize_embeddings": True})

# 测试中文嵌入texts = ["text2vec轻量高效", "中文嵌入模型推荐"]embeddings_list = embeddings.embed_documents(texts)print(f"text2vec嵌入维度:{len(embeddings_list[0])}")# 输出768维

关键说明

  • 优势在于体积小、速度快,CPU即可高效处理。
  • 特别适合中小规模中文文档检索或本地Demo开发。

8.4 嵌入维度、距离度量(余弦相似度)

生成嵌入后,必须理解两个核心概念:“嵌入维度”(向量的长度)和“距离度量”(如何判断向量相似性)——它们直接决定检索精度。

8.4.1 嵌入维度:向量的“长度”

核心定义

嵌入维度即向量中数值的个数。例如ada-002为1536维,BGE-M3为1024维。通常维度越高,承载的语义信息越丰富,但计算和存储成本也相应增加。

主流模型维度对照(重点记忆)

模型名称嵌入维度特点
OpenAI text-embedding-ada-0021536通用、高精度、性价比高
BGE-M31024中文最优、支持长文本
all-MiniLM-L6-v2384轻量、快速、适合入门
text2vec-base-chinese768中文轻量、精度与速度平衡

维度选择建议

  • 生产环境(通用场景):优先1024~1536维(如BGE-M3或ada-002),精度足够。

  • 本地Demo、低算力设备:选384~768维(如all-MiniLM-L6-v2或text2vec)。

  • 注意:维度并非越高越好,超过一定阈值后精度提升微乎其微,反而增加成本。

8.4.2 距离度量:判断语义相似的“标尺”

距离度量用于计算两个向量之间的“距离”,距离越近语义越相似。LangChain中最常用、最推荐的是“余弦相似度”,此外还有欧氏距离、曼哈顿距离等。

余弦相似度(重点)

余弦相似度衡量两个向量之间的“夹角”,取值在-1到1之间。

  • 等于1:方向完全一致,语义相同;

  • 等于0:方向垂直,语义无关;

  • 等于-1:方向相反,语义对立。

在文本检索中,通常只关心正数。相似度超过0.7即可认为文本高度相关。

LangChain中计算余弦相似度(代码示例)

from langchain.embeddings import HuggingFaceEmbeddingsfrom sklearn.metrics.pairwise import cosine_similarityimport numpy as np

# 初始化嵌入模型embeddings = HuggingFaceEmbeddings(model_name="all-MiniLM-L6-v2")

# 生成两个文本的嵌入向量text1 = "LangChain向量嵌入"text2 = "LangChain Embedding实战"vec1 = np.array(embeddings.embed_query(text1)).reshape(1, -1)vec2 = np.array(embeddings.embed_query(text2)).reshape(1, -1)

# 计算余弦相似度similarity = cosine_similarity(vec1, vec2)[0][0]print(f"两个文本的余弦相似度:{similarity:.4f}")# 输出约0.8+,高度相关

关键说明

  • 需安装 scikit-learn 包(pip install scikit-learn)。

  • 实际使用中,Chroma、FAISS等向量数据库会自动计算余弦相似度,无需手动实现。

  • 余弦相似度不受向量“长度”影响,只关注方向,非常适合文本语义匹配:长句和短句只要语义相似,计算结果就高。

8.5 缓存嵌入结果避免重复计算

生成嵌入(尤其是调用API或运行本地大模型)非常耗时。如果反复处理同一文本,浪费资源。LangChain内置缓存机制,可以巧妙避免重复计算,提升效率。

8.5.1 两种常用缓存方式

LangChain支持多种缓存,重点介绍两种:内存缓存(适合临时开发)和SQLite缓存(可持久化,程序重启后缓存仍在,适合长期项目)。

方式1:内存缓存(InMemoryCache)

缓存存储在内存中,程序重启后消失。适合临时测试或短期开发。

from langchain.embeddings import OpenAIEmbeddingsfrom langchain.cache import InMemoryCacheimport langchainfrom dotenv import load_dotenv

load_dotenv()

# 启用内存缓存langchain.llm_cache = InMemoryCache()

# 初始化OpenAI嵌入模型embeddings = OpenAIEmbeddings(model="text-embedding-ada-002")

# 第一次生成(调用API)text = "LangChain缓存嵌入实战"emb1 = embeddings.embed_query(text)print("第一次生成:完成")

# 第二次生成同一文本(从缓存读取,不调API)emb2 = embeddings.embed_query(text)print("第二次生成:完成(从缓存读取)")

# 验证结果是否一致print(f"两次嵌入是否相同:{emb1 == emb2}")# 输出True

方式2:SQLite缓存(SQLiteCache)

缓存存储在本地的SQLite数据库文件中,程序重启后依然有效。适合长期开发或生产环境。

from langchain.embeddings import OpenAIEmbeddingsfrom langchain.cache import SQLiteCacheimport langchainfrom dotenv import load_dotenv

load_dotenv()

# 启用SQLite缓存(缓存文件位于当前目录下的langchain_cache.db)langchain.llm_cache = SQLiteCache(database_path="./langchain_cache.db")

# 初始化嵌入模型embeddings = OpenAIEmbeddings(model="text-embedding-ada-002")

# 第二次同样从缓存读取text = "LangChain SQLite缓存"emb1 = embeddings.embed_query(text)emb2 = embeddings.embed_query(text)print(f"两次嵌入是否相同:{emb1 == emb2}")# 输出True

8.5.2 关键提醒

  • 缓存生效的条件:文本必须完全一致(包括空格和大小写),否则视为新文本重新生成。

  • 除上述两种外,LangChain还支持Redis缓存,适合分布式系统,用法相似。

8.6 批量嵌入与性能优化

当需要处理大量文本(如成千上万篇文档)时,逐条生成嵌入显然不切实际。LangChain支持批量嵌入,配合性能优化技巧,可以大幅提升处理效率。这是大型文档检索的必备技能。

8.6.1 批量嵌入(核心操作)

所有LangChain嵌入模型都提供embed_documents方法,可以一次性批量生成多个文本的嵌入。这比逐条处理快5到10倍。

from langchain.embeddings import HuggingFaceEmbeddings

# 初始化嵌入模型embeddings = HuggingFaceEmbeddings(model_name="all-MiniLM-L6-v2")

# 模拟100条文本,批量处理texts = [f"LangChain批量嵌入测试{i}" for i in range(100)]

# 一次调用,完成所有batch_embeddings = embeddings.embed_documents(texts)print(f"批量生成{len(batch_embeddings)}个嵌入,每个维度:{len(batch_embeddings[0])}")

8.6.2 性能优化技巧(实战必备)

技巧1:控制批量大小

批量大小并非越大越好,需根据模型和硬件调整:

  • API模型(OpenAI):建议每次10~100条,避免被限流。

  • 本地模型(BGE、text2vec):CPU上建议32~64条;GPU上可扩展至64~128条,具体视显存与内存而定。

技巧2:异步调用(提升并发效率)

LangChain嵌入模型支持异步调用(ainvoke)。处理大量文本时,异步操作能提高I/O并发效率,特别适合Web服务场景。

from langchain.embeddings import OpenAIEmbeddingsimport asynciofrom dotenv import load_dotenv

load_dotenv()

# 初始化嵌入模型embeddings = OpenAIEmbeddings(model="text-embedding-ada-002")

# 定义异步函数批量生成async def async_batch_embed():texts = [f"异步嵌入测试{i}" for i in range(50)]# 注意使用aembed_documentsbatch_embeddings = await embeddings.aembed_documents(texts)return batch_embeddings

# 运行if __name__ == "__main__":embeddings_list = asyncio.run(async_batch_embed())print(f"异步批量生成{len(embeddings_list)}个嵌入")

技巧3:GPU加速(本地模型首选)

本地部署模型时,使用GPU可提速5~10倍。只需将model_kwargs中的device改为"cuda"即可(需安装PyTorch-GPU)。

embeddings = HuggingFaceEmbeddings(model_name="FlagAI-Open/BGE-M3",model_kwargs={"device": "cuda"},# GPU加速配置encode_kwargs={"normalize_embeddings": True})

技巧4:文本预处理(减少无效计算)

生成嵌入前,对文本进行“清洁”:去除多余空白、换行、重复内容,甚至无效字符。文本缩短,计算成本自然降低。

def preprocess_text(text):# 去除首尾空白,替换换行和多余空格text = text.strip().replace("n", "").replace("", " ")# 剔除过短文本return text if len(text) >= 3 else ""

# 先批量预处理,再生成嵌入texts = [preprocess_text(t) for t in texts if preprocess_text(t)]batch_embeddings = embeddings.embed_documents(texts)

8.7 嵌入质量评估方法

嵌入生成后,如何判断其质量?许多开发者忽略这一步,导致后续检索精度不高。这里介绍三种实用的评估方法,从简单到复杂,适合不同场景。

8.7.1 方法1:人工评估(最简单,适合小批量)

思路:选取几对文本,凭直觉判断语义相似性,然后计算它们嵌入向量的余弦相似度,验证计算结果是否与直觉一致。

from langchain.embeddings import HuggingFaceEmbeddingsfrom sklearn.metrics.pairwise import cosine_similarityimport numpy as np

embeddings = HuggingFaceEmbeddings(model_name="all-MiniLM-L6-v2")

# 人工标注的文本对(标注“相似”或“不相似”)text_pairs = [("LangChain向量嵌入", "LangChain Embedding", "相似"),("猫", "狗", "相似"),("猫", "苹果", "不相似"),("Python编程", "Ja va编程", "相似"),("雨天", "晴天", "不相似")]

# 开始评估correct = 0for text1, text2, label in text_pairs:vec1 = np.array(embeddings.embed_query(text1)).reshape(1, -1)vec2 = np.array(embeddings.embed_query(text2)).reshape(1, -1)sim = cosine_similarity(vec1, vec2)[0][0]# 设置阈值0.7,大于等于视为相似pred = "相似" if sim >= 0.7 else "不相似"if pred == label:correct += 1print(f"{text1} vs {text2}:相似度{sim:.4f},预测{pred},实际{label}")

accuracy = correct / len(text_pairs)print(f"n评估准确率:{accuracy:.2f}")# 准确率高于0.8表示嵌入质量良好

8.7.2 方法2:聚类评估(检查语义簇)

逻辑:将同类文本的嵌入向量聚集,不同类文本分离。聚类效果越好,嵌入质量越高。常用K-Means聚类+UMAP或t-SNE降维可视化。

from langchain.embeddings import HuggingFaceEmbeddingsfrom sklearn.cluster import KMeansfrom sklearn.manifold import TSNEimport matplotlib.pyplot as plt

embeddings = HuggingFaceEmbeddings(model_name="all-MiniLM-L6-v2")

# 构造几类不同的文本texts = ["LangChain向量嵌入", "LangChain RAG实战", "LangChain文档加载","BGE嵌入模型", "text2vec模型", "OpenAI Embeddings","Python编程", "Ja va开发", "Ja vaScript入门"]

embeddings_list = embeddings.embed_documents(texts)

# 使用t-SNE将高维向量降至2维以便可视化tsne = TSNE(n_components=2, random_state=42)embeddings_2d = tsne.fit_transform(embeddings_list)

# 使用K-Means分为3类kmeans = KMeans(n_clusters=3, random_state=42)clusters = kmeans.fit_predict(embeddings_list)

# 绘制散点图plt.scatter(embeddings_2d[:, 0], embeddings_2d[:, 1], c=clusters, cmap="viridis")for i, text in enumerate(texts):plt.annotate(text, (embeddings_2d[i, 0], embeddings_2d[i, 1]), fontsize=8)plt.title("嵌入向量聚类可视化")plt.show()

评估标准

如果图中“LangChain”、“嵌入模型”、“编程语言”三类文本各自聚集、界限清晰,说明嵌入质量良好;若混杂不清,则需考虑更换模型。

8.7.3 方法3:下游任务评估(最实用,生产环境首选)

嵌入最终用于检索或问答,因此直接评估下游任务的表现最实在。例如,评估检索召回率或问答准确率。

示例:用检索召回率评估

from langchain.embeddings import HuggingFaceEmbeddingsfrom langchain.vectorstores import Chromafrom langchain.document_loaders import TextLoader

# 1. 加载文档(假设文档分别涉及LangChain、BGE、Python)loader = TextLoader("test_doc.txt")documents = loader.load()

# 2. 生成嵌入并构建向量库embeddings = HuggingFaceEmbeddings(model_name="all-MiniLM-L6-v2")db = Chroma.from_documents(documents, embeddings)

# 3. 测试查询是否能命中正确文档queries = ["LangChain是什么", "BGE模型怎么用", "Python入门教程"]recall = 0for query in queries:similar_docs = db.similarity_search(query, k=1)# 简单判断:关键词是否出现在结果文档中if query.split(" ")[0] in similar_docs[0].page_content:recall += 1

print(f"检索召回率:{recall / len(queries):.2f}")# 召回率超过0.9表示嵌入质量合格

8.7.4 评估总结

  • 小批量文本:用人工评估,简单高效。

  • 大规模文本:用聚类评估,直观理解语义分布。

  • 生产环境:用下游任务评估,最贴合实际用途。

8.8 【实战】为技术文档生成高质量向量表示

本节将前面所有知识点串联起来,完成一个完整实战:加载技术文档(以LangChain官方文档片段为例),预处理文本,生成嵌入,使用缓存优化,评估质量,最后将文档向量存储到向量数据库中,为后续检索做好准备。

8.8.1 实战目标

  • 加载本地的技术文档(.txt格式);

  • 预处理并分割文本,防止超出模型输入长度;

  • 使用本地BGE-M3模型生成高质量嵌入;

  • 启用缓存,避免重复计算;

  • 评估嵌入质量;

  • 将嵌入向量存入Chroma向量数据库(支持持久化)。

8.8.2 实战步骤(完整代码,可直接运行)

步骤1:准备工作(依赖+文档)

  1. 安装依赖:

    pip install langchain sentence-transformers torch chromadb scikit-learn matplotlib

  2. 准备技术文档:创建一个langchain_docs.txt文件,写入以下内容(LangChain相关介绍):

    LangChain是一个用于构建大语言模型应用的框架,它提供了一系列工具和组件,帮助开发者快速搭建RAG、聊天机器人等应用。LangChain的核心组件包括:文档加载器(Document Loaders)、文本分割器(Text Splitters)、嵌入模型(Embeddings)、向量数据库(Vector Stores)、大语言模型(LLMs)等。向量嵌入(Embedding)是LangChain RAG的核心,它能将文本转化为数值向量,实现语义检索。常用的嵌入模型有OpenAI Embeddings、BGE、text2vec等。BGE-M3是智源AI推出的开源嵌入模型,中文语义理解能力强,支持长文本,适合本地部署,是中文RAG场景的首选模型。Chroma是一个轻量级向量数据库,适合本地开发和小规模数据存储,可与LangChain无缝集成,支持相似性检索。

步骤2:完整实战代码

from langchain.embeddings import HuggingFaceEmbeddingsfrom langchain.document_loaders import TextLoaderfrom langchain.text_splitter import RecursiveCharacterTextSplitterfrom langchain.vectorstores import Chromafrom langchain.cache import SQLiteCacheimport langchainfrom sklearn.metrics.pairwise import cosine_similarityimport numpy as npimport matplotlib.pyplot as pltfrom sklearn.manifold import TSNE

# ---------------------- 1. 启用缓存(避免重复计算) ----------------------langchain.llm_cache = SQLiteCache(database_path="./embedding_cache.db")

# ---------------------- 2. 加载并预处理技术文档 ----------------------loader = TextLoader("langchain_docs.txt")documents = loader.load()

# 文本预处理函数def preprocess_text(text):text = text.strip().replace("n", " ").replace("", " ")return text if len(text) >= 5 else ""

# 预处理内容for doc in documents:doc.page_content = preprocess_text(doc.page_content)

# 分割文本(防止过长,并保留上下文)text_splitter = RecursiveCharacterTextSplitter(chunk_size=200, chunk_overlap=20)split_docs = text_splitter.split_documents(documents)print(f"文档分割后共{len(split_docs)}个文本块")

# ---------------------- 3. 本地部署BGE-M3模型,生成嵌入 ----------------------embeddings = HuggingFaceEmbeddings(model_name="FlagAI-Open/BGE-M3",model_kwargs={"device": "cpu", "trust_remote_code": True},encode_kwargs={"normalize_embeddings": True, "max_length": 8192})

# 批量生成嵌入(相同文本从缓存读取)doc_embeddings = embeddings.embed_documents([doc.page_content for doc in split_docs])print(f"生成{len(doc_embeddings)}个文档嵌入,维度:{len(doc_embeddings[0])}")

# ---------------------- 4. 嵌入质量评估(聚类可视化) ----------------------tsne = TSNE(n_components=2, random_state=42)embeddings_2d = tsne.fit_transform(doc_embeddings)

plt.scatter(embeddings_2d[:, 0], embeddings_2d[:, 1], c="blue", alpha=0.7)for i, doc in enumerate(split_docs):plt.annotate(doc.page_content[:20] + "...", (embeddings_2d[i, 0], embeddings_2d[i, 1]), fontsize=8)plt.title("技术文档嵌入向量聚类可视化")plt.show()

# 人工评估几对文本sample_texts = [split_docs[0].page_content, split_docs[2].page_content, split_docs[3].page_content]sample_embeddings = embeddings.embed_documents(sample_texts)

sim1 = cosine_similarity([sample_embeddings[0]], [sample_embeddings[1]])[0][0]sim2 = cosine_similarity([sample_embeddings[0]], [sample_embeddings[2]])[0][0]sim3 = cosine_similarity([sample_embeddings[1]], [sample_embeddings[2]])[0][0]print(f"n相似度评估:")print(f"LangChain框架 vs 向量嵌入:{sim1:.4f}")print(f"LangChain框架 vs BGE-M3:{sim2:.4f}")print(f"向量嵌入 vs BGE-M3:{sim3:.4f}")# 向量嵌入和BGE-M3应最相似,因同属嵌入话题

# ---------------------- 5. 将嵌入存入Chroma向量数据库(持久化) ----------------------vector_db = Chroma.from_documents(documents=split_docs,embedding=embeddings,persist_directory="./langchain_embedding_db")vector_db.persist()print(f"n向量数据库已持久化,存储路径:./langchain_embedding_db")

# 测试检索效果query = "BGE-M3模型适合什么场景"similar_docs = vector_db.similarity_search(query, k=2)print(f"n检索结果(与'{query}'最相关的2个文本块):")for i, doc in enumerate(similar_docs):print(f"n--- 结果{i+1} ---")print(doc.page_content)

8.8.3 实战结果说明

  1. 文档分割:将长文档切成短块,既能适配模型输入限制,又通过重叠保留上下文信息。

  2. 嵌入生成:使用BGE-M3本地模型,开启缓存,重复文本不再重复计算。

  3. 质量评估:聚类图显示语义相关文本聚集在一起;人工抽查结果符合预期,例如“向量嵌入”与“BGE-M3”相似度最高,因为它们都围绕嵌入话题。

  4. 向量存储:最终存入Chroma数据库并持久化,下次启动可直接加载,无需重新生成。

8.8.4 实战拓展

  • 切换模型:只需修改embeddings初始化代码即可换成OpenAI等模型。

  • 加载其他格式:使用PyPDFLoader加载PDF,WebBaseLoader抓取网页。

  • 大规模文档:结合批量嵌入与GPU加速,大幅提升处理效率。

本章总结

本章从Embedding基础概念出发,到动手实战,全面覆盖了嵌入的核心原理、多种模型调用、本地部署、性能优化和效果评估。最后通过完整示例,将技术文档转化为向量表示。

关键要点回顾:

  • Embedding的本质:将文字转换为机器可计算的向量,这是语义检索的基石。

  • 模型选择:通用高精度选OpenAI,中文场景首选BGE,轻量需求用text2vec,按需抉择。

  • 性能提升:批量处理、启用缓存、GPU加速——三招让效率成倍增长。

  • 质量评估:人工、聚类、下游任务——三选一,确保嵌入可靠而非盲目。

  • 实战闭环:文本预处理→生成嵌入→质量评估→存入数据库,掌握完整流程。

下一章将重点讲解向量数据库的使用,届时可借助本章生成的文档向量,实现完整的LangChain RAG检索功能。

来源:互联网

免责声明

本网站新闻资讯均来自公开渠道,力求准确但不保证绝对无误,内容观点仅代表作者本人,与本站无关。若涉及侵权,请联系我们处理。本站保留对声明的修改权,最终解释权归本站所有。

同类文章推荐

相关文章推荐

更多