当前位置: 首页 > news >正文

Embedding:文本怎么变成向量?语义检索为什么能工作?

Embedding 不是可有可无的组件,它是 RAG 的地基。地基歪了,后面 Retriever、Rerank、Prompt 再漂亮也救不回来。

一、Embedding 到底是什么?

Embedding,就是把一段文字变成一串数字。

这串数字不是随机数,而是语义坐标。意思相近的文本,向量距离更近;意思差得远的文本,距离更远。

LangChain 官方文档对 Embedding 的解释也很直接:Embedding 模型会把原始文本转换成固定长度的数字向量,这些向量能表达语义含义,让机器按“意思”比较文本,而不是只按关键词匹配。

这就是语义检索能工作的原因。

用户问“提前还款怎么操作”,知识库里写的是“如何结清贷款”,关键词不一样,但意思接近。Embedding 能把它们拉到同一个语义区域,向量库就能召回。

如果没有 Embedding,RAG 很容易退化成普通搜索。只能找关键词,找不到意思。

二、Embedding 在 RAG 里处在哪一层?

前面几章已经讲过:Loader 把资料读进来,Splitter 把长文档切成 Chunk。接下来,就轮到 Embedding。

它做一件事:把每个 Chunk Document 的 page_content 转成向量,然后交给 VectorStore 入库。

离线建库和在线查询两条链路,都要经过 Embedding

离线建库时,Embedding 面向的是一批文档。在线查询时,Embedding 面向的是用户的一句话。

所以 LangChain 在接口上故意拆成两个方法:

embed_documents(texts):文档批量向量化。

embed_query(text):问题单条向量化。

这两个方法看起来简单,但这是整个语义检索的分水岭。文档侧是“建索引”,问题侧是“查索引”。

三、Embeddings 抽象接口

打开 LangChain Core 的源码,可以看到 Embeddings 是一个抽象基类。它不是 OpenAI,也不是 HuggingFace。它只是规定:一个 Embedding 模型必须能把文档和查询变成向量。

源码的设计非常克制。核心就是四个方法:

class Embeddings(ABC):

def embed_documents(self, texts: list[str]) -> list[list[float]]: ...

def embed_query(self, text: str) -> list[float]: ...

async def aembed_documents(self, texts: list[str]) -> list[list[float]]: ...

async def aembed_query(self, text: str) -> list[float]: ...

这里最关键的是返回类型。

文档是 list[str],所以返回 list[list[float]]。一个文本,对应一个向量。

查询是 str,所以返回 list[float]。一个问题,对应一个向量。

这就是 LangChain 抽象层的好处:上层 VectorStore 和 Retriever 不需要知道你底下接的是哪个模型。只要实现这个接口,就能被接入 RAG 流水线。

四、为什么要区分 embed_documents 和 embed_query?

很多人第一次看源码会疑惑:文档是文本,问题也是文本,为什么不统一叫 embed_text?

不同 Embedding 模型可能会对“文档”和“查询”使用不同提示方式。比如某些检索模型会要求:

文档侧:把这段内容编码成可检索资料。

查询侧:把这个问题编码成检索意图。

有些模型内部路径一样,有些模型内部路径不一样。LangChain 先把接口拆开,给不同模型留下扩展空间。

这就是好的框架设计:看起来多写了一个方法,实际是在给未来兼容性留口子。

五、OpenAIEmbeddings 怎么实现?

以 OpenAIEmbeddings 为例,源码链路很清晰。

它的 embed_documents 大致分两种情况:

如果不检查上下文长度:直接按 chunk_size 分批调用 embedding API。

如果检查上下文长度:先 tokenize,再按 embedding_ctx_length 切分,再批量请求。

源码里有一个细节很重要:长文本不会直接硬塞给 embedding API。它会被分成 token chunks,再请求向量,最后把多段结果合并。

embed_query 更直接。源码逻辑可以压缩成一句话:

def embed_query(self, text: str) -> list[float]:

return self.embed_documents([text])[0]

也就是说:问题向量化,本质上还是复用文档向量化能力。先把单个问题包装成列表,再取第一个结果。

这不是偷懒。恰恰是工程复用。

六、从源码看 VectorStore 为什么能自动调用 Embedding?

很多人写代码时会发现,自己明明只写了 from_texts、add_documents 或 retriever.invoke,为什么 Embedding 就自动被调用了?

因为 VectorStore 和 Retriever 在内部已经接上了 Embeddings 接口。

文档入库时:

VectorStore.add_documents(documents)

-> 取出 page_content

-> embeddings.embed_documents(texts)

-> 向量 + metadata + id 入库

查询检索时:

retriever.invoke(query)

-> vectorstore.similarity_search(query)

-> embeddings.embed_query(query)

-> 用 query_vector 去向量库查近邻

-> 返回 List[Document]

所以,Embedding 是隐藏在 RAG 后面的发动机。你看不到它转,但它一直在转。

七、向量怎么比较?三个常见相似度指标

文本变成向量后,下一步就是比较。LangChain 官方文档列出了常见的三类距离或相似度指标:余弦相似度、欧氏距离、点积。

余弦相似度:看两个向量方向是否接近。常用于语义相似度。

欧氏距离:看两个点在空间里的直线距离。

点积:看一个向量在另一个方向上的投影强度。

实际项目里,你不一定要自己手写这些公式。向量库会帮你算。但你必须知道:不同指标会影响召回结果,向量是否归一化也会影响结果。

八、Embedding 模型怎么选?这张图比参数更重要

选 Embedding 模型,不要只看榜单。

真正上线时,最关键的是业务评测。你要拿自己的问题、自己的知识库、自己的标准答案去测。

比如智能客服要测:用户口语化提问能不能召回制度文档。股票研报助手要测:同一公司不同公告、行业新闻、研报摘要之间能不能建立语义关联。

如果只拿通用 benchmark 选模型,很容易线上翻车。

九、缓存为什么重要?Embedding 不是一次性成本

很多人以为 Embedding 只在建库时花钱。错。

查询也要 embed_query。每个用户问题都可能触发一次向量化。高并发下,延迟和成本都会上来。

所以生产系统至少要做三类缓存:

文档向量缓存:同一 Chunk 内容不重复向量化。

查询向量缓存:高频问题不重复调用 embedding 模型。

索引版本缓存:模型版本、切分版本、向量库版本要绑定。

只要文档内容、切分策略、Embedding 模型版本任何一个变了,历史向量就可能需要重建。

十、企业级落地:Embedding 不该只是一个函数

如果只是 Demo,Embedding 可以写成一行代码。

如果是企业系统,Embedding 必须进入数据流水线。

Java 主服务负责文档上传、任务调度、权限审计、索引版本。

Python AI 服务负责 Loader、Splitter、Embedding、Retriever。

Milvus / ES 负责向量和关键词索引。

Redis 做缓存,MySQL 记录元数据和版本。

日志系统记录每次向量化耗时、模型名称、维度、token、失败原因。

Embedding 是基础设施,不是工具函数。

十一、Embedding 最容易踩的坑

RAG 效果差,很多时候不是大模型的问题,而是 Embedding 链路的问题。

最常见的就是:文档切得不好、模型版本乱换、向量没有重建、metadata 没带、只做向量检索不做关键词融合。

尤其是模型版本。

同一个向量库里,不能混着放不同 Embedding 模型生成的向量。维度可能不同,语义空间也可能不同。哪怕维度一样,距离也不一定有可比性。

十二、总结

Embedding 把文本变成向量,VectorStore 按距离找资料,Retriever 把相关 Document 交给 Prompt,Model 再基于资料生成答案。

所以,RAG 的第一性原理不是“把资料塞给大模型”,而是:先把资料变成可计算的语义坐标,再按问题找到最相关的上下文。

学 LangChain,Embedding 这一章必须吃透。因为从这里开始,RAG 才真正从“文本处理”进入“语义计算”。


内容来源:Embedding:文本怎么变成向量?语义检索为什么能工作?:功能变化与行业影响解析_热闻岛

http://www.gsyq.cn/news/1522292.html

相关文章:

  • WordPress评论AI自动回复插件开发实战
  • 2026年推荐一下推进式搅拌器厂家前十名,专业的淬火搅拌器定制厂家靠谱吗 - mypinpai
  • 成都名酒回收公司可靠度排行:核心维度实测对比 - 优质品牌商家
  • 告别命令行恐惧:在统信UOS上用RapidSVN图形化搞定SVN客户端连接
  • 成都主题火锅店的商业落地与空间营造——从“前任的火锅店”看品牌化与场景化趋势 - 优质品牌商家
  • 从梯度下降到牛顿下山:机器学习优化算法选哪个?实战对比与避坑指南
  • 2026年正规反渗透设备厂商行业调研与技术能力评估 - 优质品牌商家
  • 2026年6月北京十大装修公司排行榜推荐:价格透明防增项评测专业特点选择指南 - 品牌推荐
  • AI不是取代工作,而是重构职业能力权重
  • 5分钟终极指南:快速安装Windows包管理器Winget的智能方案
  • 2026年6月金属复合板厂家实力评测:从生产工艺到工程应用,谁才是“高标准项目”的可靠选择? - 品牌推荐
  • 聊聊家具板材定制厂服务,选购时需注意哪些费用 - 工业品牌热点
  • STM32F103驱动DDSM210直驱电机做轮腿机器人:从硬件接线到按键调速全流程
  • 如何在3分钟内将Chrome变成强大的Markdown阅读器?终极配置指南
  • 2026年矿用风机性价比对比,口碑好的矿用风机厂家排名 - 工业品牌热点
  • Language AI:一款基于大模型与多模态技术的全能型人工智能语言学习与翻译工具详解
  • 在 Oracle EBS 里,借项通知单(Debit Memo)和贷项通知单(Credit Memo)是应收(AR)、应付(AP)模块用于调整往来余额的标准单据,核心区别:
  • 2026年服装网站建设公司排名,于安专家创新思维强吗,价格选购指南 - 工业品牌热点
  • Perplexity AI深度体验:它真的能取代Google搜索吗?我用这3个真实场景测给你看
  • 3分钟搞定B站视频下载!哔哩下载姬DownKyi终极免费方案揭秘
  • 无机纤维吸音涂料厂家综合能力分析与行业观察 - 优质品牌商家
  • ML自动化工作流:DagsHub+GitHub Actions+CML实践指南
  • Java SpringBoot+Vue3+MyBatis Web鲜牛奶订购系统系统源码|前后端分离+MySQL数据库
  • Oracle EBS 里 “子模块(AR/AP)多做 / 少做了凭证”,本质是 “发票 / 交易录错了金额”,用的还是
  • 大型行为模型(LBM)的技术突破与应用实践
  • XDP程序的性能分析与优化
  • UKF、EKF、PF怎么选?一张图看懂非线性滤波器的选型指南与避坑要点
  • 如何选择北京老房改造装修公司?2026年6月推荐TOP5评测格局重塑空间特点市场份额 - 品牌推荐
  • 别再死记硬背对比学习论文了!从InstDisc到DINO,我用一张图帮你理清发展脉络
  • 2026年6月金属复合板厂家深度评测:从标准制定到智能制造,谁是行业实力派? - 品牌推荐