编程与 AI12 分钟阅读更新于 2026-07-30

Embedding 是什么:把文本变成能检索的语义向量

Vectorstores and Embeddings 章节,讲清 Embedding 如何把文本片段转成实数向量,为什么语义相近的文本距离更近,以及向量检索有哪些常见失败场景。

相关工具

Embedding 不是把文本压缩,而是换一种表示方式

前面几篇文章讲了文档加载和文档切分。资料被拆成 chunk 之后,还不能直接做语义检索。计算机擅长比较数字,不擅长直接理解“退款规则”和“能不能退钱”这种自然语言表达的关系。Embedding 要做的事,就是把文本片段转换成一组实数向量,让系统可以用数学方式比较语义相似度。

相关概念 在 Embeddings 小节里解释得很清楚:Embedding 是把单词、句子或整个文档转化为实数向量的技术。它背后的想法是,相似或相关的对象在向量空间里的距离应该更近。也就是说,Embedding 不要求两句话字面一样,而是希望意思相近的文本在向量空间中靠近。

这一步是 RAG 能处理自然语言问法的关键。用户问“这个套餐还能退吗”,文档里可能写的是“购买后 7 日内可申请退款”。如果只靠关键词,用户没有输入“7 日内”“申请退款”,系统未必能稳定命中;如果文本和问题都转成向量,语义接近就有机会被召回。

Embedding 文本向量和语义相似度示意图
Embedding 把文本映射到语义向量空间

语义相近的文本向量距离更近,RAG 可以根据用户问题向量召回 Top-K 相关片段。

相似度来自向量比较,不是关键词重合

文中用三个中文句子做了一个很直观的例子:“我喜欢狗”“我喜欢犬科动物”“外面的天气很糟糕”。前两个句子字面并不完全一样,但语义接近;第三句讨论天气,和前两个明显不是一类。教程把三句话分别转成 embedding,再用点积比较,前两个的分数约为 0.94,明显高于它们和天气句子的分数。

这个例子好在它不神秘。Embedding 模型没有把“狗”和“犬科动物”简单当成同一个词,而是把整句话放到语义空间里比较。分数高,说明两个向量方向更接近;分数低,说明语义关联弱一些。做知识库检索时,系统也是类似逻辑:把用户问题和文档 chunk 都转成向量,再找距离近的片段。

当然,分数不是绝对真理。0.94 和 0.79 这样的数值,只能在同一个模型和同一套比较方式下理解。换 Embedding 模型、换文本长度、换语言,分数分布都可能变化。工程上更常用的是排序:同一个问题下,哪些 chunk 更相似,Top-K 里有没有正确依据。

关键词和语义检索的差别
关键词匹配

更依赖字面词重合,适合精确名称、编号、术语检索。

Embedding 检索

更关注语义接近,适合自然语言问题和同义表达。

混合使用

企业知识库常把关键词、向量和元数据过滤一起用。

Embedding 模型负责表示,向量库负责存和找

很多初学者会把 Embedding 和向量数据库混在一起。它们确实经常一起出现,但职责不同。Embedding 模型负责把文本变成向量;向量数据库负责保存这些向量和对应文本,并在用户提问时快速找出相似向量。一个是转换器,一个是索引和检索系统。

文中先加载 Matplotlib 资料,再用 RecursiveCharacterTextSplitter 切成 27 个片段,接着用 OpenAIEmbeddings 创建 embedding,最后用 Chroma.from_documents 把切分后的文档和 embedding 写入向量库。这个流程很典型:文档加载、文档切分、Embedding、向量存储,顺序不能乱。

向量库里保存的不是孤立数字。每个向量通常都要对应原始 chunk、metadata、来源页码等信息。否则即使检索命中了,也不知道该把哪段文字交给模型,更无法给用户标注来源。Embedding 让文本可比较,向量库让比较可以在大量片段中快速完成。

相似性搜索能解决很多问题,但不是万能

文中用问题“Matplotlib 是什么?”做相似性搜索,向量库返回了 3 个相关文档,其中第一个 chunk 就包含 Matplotlib 的定义。这正是 RAG 的理想情况:用户问题转成向量,向量库找出相关片段,模型拿着片段回答。对于大量文档问答,这个流程能覆盖很多高频需求。

但教程也马上展示了失败场景。第一个问题是重复块:示例里故意把同一份 资料 加载了两遍,搜索时 Top-K 里出现重复内容。语义搜索会找相似文档,但默认不保证结果多样性。如果知识库里有大量重复资料,召回结果可能被重复 chunk 占满,真正有用的补充信息反而排不到前面。

第二个问题是错召回。用户问“第二讲中对 Figure 说了些什么”,结果前几个召回里混入了第一讲内容,第三个结果才是更想要的第二讲片段。这说明向量相似度只看语义接近,不一定理解“第二讲”这种结构条件。遇到这类问题,需要结合 metadata 过滤、章节字段、文件来源、重排策略,而不是只怪模型回答不准。

Embedding 检索常见失败点
步骤 1
重复资料

相同或近似 chunk 占据 Top-K,答案来源单一。

步骤 2
条件漏掉

问题里的章节、时间、版本没有在检索前过滤。

步骤 3
片段太宽

chunk 包含多个主题,向量相似但答案不精确。

步骤 4
语义相近但业务不同

相关不等于正确,需要重排和人工评估。

Embedding 的效果受文本质量影响很大

Embedding 模型再好,也是在给输入文本做表示。如果 chunk 里有乱码、页眉页脚、重复目录、错位表格、无关导航,向量也会带着这些噪声。前面讲文档加载和切分,并不是绕远路,而是在为 Embedding 准备干净输入。

比如一个 chunk 里同时包含“退款规则”“发票说明”“账户注销”和“联系客服”,它的向量会变成混合主题。用户问退款时,它可能被召回,但模型拿到后还要自己挑其中一小段。相反,如果 chunk 只围绕退款条件,并保留标题和适当上下文,Embedding 更容易把它放到正确的语义位置。

因此,调 Embedding 效果时,不要一上来就换模型。先看资料清洗是否干净,切分是否合理,metadata 是否完整,重复资料是否过多。很多知识库不是输在向量模型,而是输在输入给向量模型的文本本身。

如何判断 Embedding 检索有没有做好

最直接的方法是准备一批真实问题,每个问题标注理想命中的资料。然后只看检索结果,不看模型生成。比如用户问“Matplotlib 是什么”,理想命中应该包含定义;用户问“第二讲里的 Figure 容器”,理想命中应该来自第二讲,而不是第一讲的相似概念。

评估时可以看几个指标:Top-1 是否命中,Top-3 是否包含正确资料,Top-K 是否被重复片段挤占,召回片段是否带有可引用来源,错误命中主要来自资料重复、切分不当还是缺少 metadata 过滤。这个过程比只看最终回答更费一点工夫,但能把问题定位到检索层。

上线后也要持续看失败样本。用户问法会比测试集更杂,有人会用口语,有人会省略上下文,有人会把多个问题塞进一句话。Embedding 检索不是一次建库就结束,而是随着资料更新、问题积累和失败分析不断调整。RAG 的稳定性,很多时候就藏在这些看起来细碎的检索评估里。

常见问题

Embedding 和向量数据库是一回事吗?

不是。Embedding 模型把文本转成向量,向量数据库负责保存向量并进行相似性搜索。

Embedding 能完全替代关键词搜索吗?

不能。Embedding 擅长语义相似,关键词适合精确词、编号、专有名词。实际知识库常常混合使用。

相似度最高的片段一定是正确答案吗?

不一定。语义相似不等于业务正确,还要结合 metadata 过滤、去重、重排和测试集评估。

RAG、知识库与长期记忆

继续阅读

返回专题