Embedding 到底是什么

Embedding 是 RAG 里最容易被神秘化的概念之一。

很多解释会说:Embedding 是把文本映射到高维向量空间,语义相近的文本在空间中距离更近。

这句话没有错,但它对工程实践帮助有限。前端工程师真正需要知道的是:Embedding 让系统可以用“语义相似”而不是“关键词相同”来找内容。

用户问“怎么退款”,文档里写的是“订单取消后款项将在 3 个工作日内原路退回”。这两句话没有共享多少关键词,但语义上相关。Embedding 的价值就在这里:把文本转换成一串数字,让机器可以比较它们在语义上的接近程度。

从前端熟悉的搜索说起

传统关键词搜索更像字符串匹配。

如果用户输入“登录不了”,搜索系统会优先找包含“登录”“不了”的文档。它很擅长精确词、专有名词、错误码、订单号和 API 名称。

但它不擅长这些情况:

  • 用户说“进不去”,文档写“无法登录”。
  • 用户说“钱什么时候回来”,文档写“退款到账时间”。
  • 用户说“页面一直转圈”,文档写“请求超时”。
  • 用户问“怎么让模型别乱编”,文档写“groundedness 和引用约束”。

Embedding 搜索更像“按含义找近邻”。它不要求词完全一样,而是看两段文本在模型学到的语义空间里是否接近。

这并不意味着 embedding 比关键词搜索高级到可以替代一切。它只是解决了另一类问题。真实 RAG 系统通常会把关键词搜索和向量搜索结合起来。

Embedding 的基本过程

Embedding 的输入通常是一段文本,输出是一组数字。

例如一句话经过 embedding model 后,可能得到一个长度为 1536、3072 或其他维度的数组:

type Embedding = number[];

type ChunkVector = {
  chunkId: string;
  text: string;
  embedding: Embedding;
  metadata: {
    documentId: string;
    title: string;
    section: string;
    sourceUrl?: string;
  };
};

这些数字本身不适合人类阅读。你不应该尝试解释“第 23 维代表什么”。它们的工程价值在于可以参与相似度计算。

在 RAG 里,常见流程是:

文档入库时,每个 chunk 都生成一个 embedding。用户提问时,问题也生成一个 embedding。系统再比较 query vector 和 chunk vector 的距离,找出最相近的内容。

相似度到底在比什么

常见的相似度算法包括 cosine similarity、dot product 和 Euclidean distance。你不需要一开始深究数学细节,但要理解它们都在回答同一个工程问题:两个向量有多接近。

可以粗略理解为:

  • 越接近,系统越认为两段文本语义相关。
  • 越远,系统越认为两段文本关系较弱。

但“相关”不等于“正确”,也不等于“足以回答”。

例如用户问:“企业版是否支持 SSO?”

检索结果可能命中:

  1. “企业版支持 SAML SSO 和 SCIM。”
  2. “企业版支持高级审计日志。”
  3. “团队版支持 Google 登录。”

这三条都可能在“企业版、登录、身份”附近,但只有第一条直接回答问题。Embedding 负责粗略召回候选内容,后面还需要 rerank、过滤和上下文组装。

RAG 工程流程

Embedding 不是独立功能,它嵌在 RAG 的入库链路和检索链路里。

这张图里有一个关键点:embedding 之前的处理会强烈影响 embedding 之后的效果。

如果解析出来的文本是乱的,embedding 会忠实地把乱文本变成向量。如果 chunk 切得不完整,embedding 会得到一个不完整语义的向量。如果 metadata 缺失,后面就无法按权限、版本和文档范围过滤。

所以 embedding 不是魔法清洗器。它不会自动修复脏文档。

Chunk 的粒度会影响 Embedding

同一个 embedding model,对不同粒度的文本会产生不同效果。

chunk 太小,语义不完整。

例如只保存一句:“支持导出。”

它缺少主语、对象、条件和范围。用户问“企业版审计日志能导出吗”时,这个 chunk 可能不如完整段落好用。

chunk 太大,语义过于混杂。

一个 chunk 里同时讲登录、计费、审计、权限、导出,向量会变成多个主题的混合表示。用户问某个具体问题时,它可能因为包含相关词被召回,但里面大部分内容都是噪音。

更稳妥的做法是按文档结构切分:

  • 保留标题路径。
  • 尽量按段落、列表、FAQ 问答、表格边界切分。
  • 对长段落做递归切分。
  • 对相邻片段保留少量 overlap。
  • 对代码块和表格使用更谨慎的策略。

Embedding 的质量不只由模型决定,也由 chunk 的语义完整性决定。

Embedding Model 怎么选

选择 embedding model 时,不要只看维度大小。

更应该关注:

维度要问的问题
语言能力中文、英文、多语言表现是否稳定
领域适配技术文档、法律、客服、代码是否合适
成本文档量和更新频率下是否可承受
延迟在线 query embedding 是否影响首 token 时间
上下文长度单次可 embedding 的文本长度是否足够
维度存储成本、索引性能和检索质量如何平衡
版本稳定性模型升级后是否需要重建索引

有一个经常被忽略的点:文档 embedding 和 query embedding 应该使用同一个模型,或者至少使用官方说明中兼容的模型。不要随意混用不同 embedding model。不同模型产生的向量空间不一致,相似度比较会失去意义。

如果需要更换 embedding model,通常要重新生成已有文档的 embedding,并重新建立索引。

Embedding 不能理解什么

Embedding 可以捕捉语义相似,但它不等于理解业务规则。

它通常不能可靠处理这些问题:

权限:向量相似度不知道用户能不能看某段内容。权限必须由 metadata filter 和业务系统控制。

时效:旧文档和新文档如果语义相似,都可能被召回。需要版本、发布时间、有效期和优先级。

真假:错误文档也能生成漂亮的向量。Embedding 不判断事实正确性。

冲突:两段文档观点相反,但都和问题相关。系统需要冲突检测或在回答时显式引用来源。

精确匹配:订单号、错误码、API 名称、变量名、法规条款号,关键词搜索往往更可靠。

数值推理:价格、日期、额度、计算规则不能只靠语义相似。检索到资料后仍需要模型或代码做正确解释。

这就是为什么生产 RAG 常用 hybrid search:向量检索负责语义召回,关键词检索负责精确匹配,两者合并后再 rerank。

面向前端的工程影响

Embedding 听起来像后端或算法概念,但它会影响前端体验。

第一,用户问题可能需要被改写。

用户在界面里问“这个怎么开?”如果当前页面选中了“SSO 设置”,前端应该把页面状态结构化传给后端,让检索 query 能变成“SSO 如何开启”。否则 embedding 只看到“这个怎么开”,召回会很差。

第二,知识范围应该可见。

如果用户只想问当前文件,就不要默认检索整个组织知识库。前端应该提供文件、文件夹、知识库或当前页面范围选择。

第三,引用需要定位到原文。

Embedding 检索返回的是 chunk,不是完整文档。前端展示引用时需要 document id、标题、页码、段落位置、高亮范围等 metadata。

第四,上传后需要索引状态。

文档刚上传不代表马上可问。解析、切分、embedding、索引都可能需要时间。界面应该区分“已上传”和“已可检索”。

第五,调试信息要能暴露给内部用户。

当用户说“文档里明明有答案”时,前端调试面板可以展示:原始 query、改写 query、命中 chunk、分数、过滤原因、最终上下文。没有这些信息,RAG 优化会靠猜。

常见坑

第一个坑:以为 embedding 是压缩后的原文。

Embedding 不是可逆压缩。不能从向量还原原文,也不能只存向量不存文本。生成答案时模型需要读取 chunk 文本,而不是读取向量。

第二个坑:不同模型的向量混在一起。

不同 embedding model 的向量空间通常不兼容。升级模型后,如果只对新文档用新模型,旧文档用旧模型,检索质量会变得很难解释。

第三个坑:只做向量检索,不做 metadata filter。

相似度搜索必须和租户、权限、文档类型、语言、状态、版本等过滤条件配合。否则越相关的敏感内容越容易被召回。

第四个坑:把相似度分数当成答案置信度。

高分只表示 query 和 chunk 在向量空间接近,不表示答案正确。最终仍要看 chunk 是否包含足够证据,以及模型回答是否忠实。

第五个坑:忽略短 query 的歧义。

“怎么配置”“价格多少”“无法打开”这类问题缺少对象。需要结合页面状态、历史对话或追问,而不是直接 embedding 后检索。

第六个坑:没有保留 chunk 的结构信息。

只存纯文本会导致引用体验很差。标题路径、页码、段落编号、表格位置和原文链接,都是 RAG 产品体验的一部分。

小结

Embedding 是把文本转换成语义向量的过程,它让系统可以按含义而不只是关键词检索内容。

但 embedding 不是 RAG 的全部,也不是事实判断器、权限系统或质量保证。它负责把文档片段和用户问题放到可比较的向量空间里,帮助系统召回候选证据。

对前端工程师来说,理解 embedding 的重点不是数学公式,而是工程边界:它依赖干净的文档、合理的 chunk、稳定的模型版本、充分的 metadata、合适的检索范围和可调试的用户界面。

当你把 embedding 看成 RAG 流水线里的一个模块,而不是万能语义魔法,系统设计就会清醒很多。