跳到主要内容

31 篇博文 含有标签「embeddings」

查看所有标签

让你的 A/B 测试整整一个季度都失效的嵌入模型轮换

· 阅读需 11 分钟
Tian Pan
Software Engineer

你干净利落地运行了实验。两个实验组,一个功能开关,一个明确的指标,统计团队也认可了该设计。十二周后,你上线了胜出的方案,然而提升效果却在一个 Sprint 内悄然消失。复盘(Post-mortem)结果显示代码没问题,功能开关的滚动发布没问题,分析端也没问题。发生变动的是实验清单上没人负责的东西:你检索调用背后的托管嵌入模型(embedding model),在第三周、第七周,以及你开会审阅结果的那个早上,为同一个查询返回了略微不同的向量。你的 A/B 测试是真实的,但它运行的底层基座却不是。

这是每一个运行检索增强生成(RAG)的团队最终都会遇到的失败模式,而且几乎没人针对它进行设计。嵌入端点被视为像 Postgres 一样的稳定基座。但它不是。它是一个模型,其发布节奏由厂商控制,你不会去阅读它的更新日志,它的行为表现面(behavior surface)可能会发生偏移,而无需改变维度数量、SLA 或你签署的 API 合约。你以为实验测量的是功能变化,实际上测量的是检索机制的变迁,而功能开关带来的波动只是其上的噪声。

你的嵌入模型在训练中从未见过的专业术语检索库

· 阅读需 10 分钟
Tian Pan
Software Engineer

一个检索团队针对其产品目录发布了一个开箱即用的嵌入模型 (embedding model)。评估集——从上个月搜索日志中抓取的几百个查询——回传的 recall@10 达到了 0.91。他们将其推向生产环境。三周后,支持部门开始转发工单:一位用户搜索了某个零件的具体 SKU,结果得到了五个看起来很有道理但错误的零件。另一位用户搜索了一个功能的内部代号,结果得到了一个无关功能的营销名称。评估集从未捕捉到这一点,因为评估集是从系统已经处理过的查询中提取的——即关于常用术语的查询。作为业务核心的长尾术语 (jargon) 从未被采样。

模型并没有失败。模型完全按照其训练要求执行了任务,只是针对的是一个不包含团队提供语料库的词汇分布。团队将嵌入视为一种领域中性的原语 (domain-neutral primitive)——一个从文本到向量的函数——而实际上,它是一份关于它可以解析哪些词汇的契约,是与别人的训练语料库签署的。

源文档更新从未同步到向量索引的那些 Embedding

· 阅读需 12 分钟
Tian Pan
Software Engineer

一名支持工程师在值班频道发了消息。一位客户粘贴了助手上周检索到的一个句子,合规团队回复说:我们已经不再这么说了。他们已经停用这句话四个月了。CMS 中的文档显示是正确的。但向量索引中的嵌入分块(chunk)仍然是旧的内容,且拥有极高的相似度得分,并在每次相关查询时被提供给模型。没人改过检索代码。没人改过模型。真相源(source-of-truth)变了,而索引却对此一无所知。

这是摄取流水线(ingestion pipeline)的一种失败模式:它最初是为“创建”而设计的,后来演变成了一个也要处理“更新”的系统,却没有人专门为“更新”进行设计。“创建时嵌入”的任务在每份文档首次写入的那天运行。一个季度后,CMS 团队发布了一个编辑端点,由另一个团队负责,他们将其接入了搜索、面向公众的渲染器和变更日志 feed —— 接入了每一个消费者,除了那个隐藏在不同名称下的派生数据集。数月过去,语料库发生了漂移。检索系统开始回答那些公司早已正式抛弃的问题,而唯一的信号来自于一位困惑的客户。

被切分边界拦腰截断的关键句,以及随之消失的答案

· 阅读需 11 分钟
Tian Pan
Software Engineer

你的 RAG 流水线将文档切分为 512 个 token 的片段,并带有 50 个 token 的重叠。这是一个标准的行业默认设置。在你的语料库中,有这样一句话——“除非订单来自欧盟地区(在这种情况下监管窗口为 14 天),否则退款将在 5 个工作日内处理”——它恰好跨越了分块边界。分块 N 包含前半部分。分块 N+1 包含后半部分。

用户提问“欧盟退款需要多长时间”。检索系统给分块 N 打分最高,因为查询嵌入与第一段碎片中的“欧盟地区”对齐。而包含唯一实际答案的分块 N+1 排名太低,无法同时被检索到。智能体回答“5 个工作日”,并自信地引用了分块 N。客户人在法兰克福。答案是错误的。流水线完全按照设计运行。

这种故障模式不会出现在你的分块质量评估中。分块是格式良好的。语料库是格式良好的。嵌入模型是格式良好的。分块之间的边界——你在自己文档中划下的那些线——才是答案所在。

语义过时的 Embedding:当向量不再理解当下

· 阅读需 10 分钟
Tian Pan
Software Engineer

你曾在十八个月前嵌入了知识库。模型没变。分块(chunks)没变。索引很健康,延迟也正常,召回率仪表盘是一条 0.86 的水平线。然而,客服团队正悄无声息地在工单回复中粘贴错误的文章链接,销售机器人在潜在客户询问新产品时不断翻出已弃用的 SKU,而一名内部用户刚告诉你助手“感觉变笨了”,却说不出具体原因。

一切都没坏。是你的嵌入(embeddings)老了。在你的领域中,“post”一词以前指的是博客文章;现在,语料库中有一半的地方用它指代 Slack 帖子、论坛帖子和职位发布(job posting),而你那十八个月前的向量仍将其视为同一个概念。编码这些向量的模型从未见过这些新含义,从未见过新的产品名称,从未见过品牌重塑,也从未见过引入了三个新术语的监管规定——而你的客户现在正不假思索地使用这些术语。检索系统回答了它知道如何回答的问题,但这已不再是你的用户正在提出的问题。

那些在悄无声息中重新排列你整个语料库的嵌入模型升级

· 阅读需 11 分钟
Tian Pan
Software Engineer

一个新的嵌入模型登上了排行榜。它比你 18 个月前发布的模型得分更高,API 只需更改一行代码,甚至维度也一致。有人提了一个工单:“升级嵌入模型”。这看起来就像更换一个日志库一样简单。

事实并非如此。嵌入模型并不是你检索系统的一个普通组件——它就是你检索系统所处的坐标系。更换它并不会改进你的索引,而是会让索引失效。而最残酷的地方在于,系统并不会崩溃。没有异常,没有失败的健康检查。你的搜索只是开始返回微妙不同的结果,而在 RAG 管道中,“微妙不同”意味着不同的文档被喂给了模型,也就意味着不同的答案最终传达给用户。

嵌入模型迁移黑洞:向量模型升级如何悄然重写你的业务规则

· 阅读需 12 分钟
Tian Pan
Software Engineer

迁移工单只有一行:“将 Embedding 模型从 v3-small 升级到 v3-large。”新模型在公开基准测试(Benchmark)中胜出 12%。流水线代码改动只有六行 Python。团队预计需要两天的开发时间,加上一个周末就能跑完的重嵌入(Re-embedding)任务。两个月后,查重功能的误报率比更换前翻了一倍,“相关项目”栏目悄然变成了废话生成器,语义缓存的命中率更是断崖式下跌,因为在旧空间运行良好的 0.95 阈值在现在几乎匹配不到任何内容。

没人动过这些功能。没人提交过 Bug。这个在迁移计划中被归类为“基础设施”的模型切换,悄无声息地改写了每一个使用相似度得分的业务规则。

代码专用 RAG:为什么通用检索在代码库中会失败

· 阅读需 11 分钟
Tian Pan
Software Engineer

大多数构建 AI 编程助手的团队都会采用与文档检索相同的现成 RAG 流水线:根据 token 数量对源文件进行分块(chunking),对块进行嵌入(embedding),将其存储在向量数据库中,并通过语义相似性进行查询。这种流水线在处理散文(prose)时表现良好。但在处理代码时,它会悄无声息地失败——而且这些失败很难在聚合指标中显现,因为检索到的代码块看起来似乎合情合理,直到模型生成了错误返回类型的代码、调用了签名错误的函数,或者遗漏了调用图中三层之后才存在的依赖项。

问题不在于嵌入模型或向量数据库,而在于分块策略。代码不是散文。它具有结构属性——依赖图、调用链、类型签名、作用域层级——而基于 token 的分块在检索器看到它们之前就破坏了这些属性。修复这个问题需要重新思考在进入嵌入步骤之前如何分解代码。

嵌入模型更迭:当你的提供商悄然导致整个向量索引失效

· 阅读需 10 分钟
Tian Pan
Software Engineer

你花了数周时间构建检索流水线。分块策略已调整,相似度阈值已校准,用户反馈看起来很积极。然后,在某个周一的早晨,在你没有任何部署的情况下,检索质量开始下降。以前能搜出正确文档的查询,现在返回的却是关联度极低的噪音。没有错误日志。没有异常。流水线运行顺畅。

发生变化的是你的嵌入(Embedding)提供商更新了模型。你的整个向量索引——那些费尽心力嵌入的数百万个文档——现在填充的是来自一套坐标系统的向量,而这套系统与你的查询编码器生成的向量已不再匹配。结果不是系统崩溃,而是不可见的垃圾数据。

向量维度税:嵌入维度如何悄然侵蚀你的预算

· 阅读需 9 分钟
Tian Pan
Software Engineer

大多数构建 RAG 系统的团队从不思考嵌入维度的问题。他们直接选用 text-embedding-3-large,保留默认的 3072 维度,然后继续推进。在处理 1 万份文档时,这无关紧要。但在处理 1000 万份文档时,你已经给云服务商每月多付了 30 美元的存储费用,而实际上只需 3.75 美元。在处理 1 亿份文档时,你面对的是 1TB 的 float32 数据,其中大部分并没有物尽其用。

嵌入维度与实际检索质量之间的关系,远弱于维度与运营成本之间的关系。这个差距——你实际支付的成本与所获得的质量之间的鸿沟——就是向量维度税。

嵌入微调差距:通用向量并不理解你特定领域的“相关性”含义

· 阅读需 13 分钟
Tian Pan
Software Engineer

你的 RAG 流水线在理论上看起来很扎实:分块很清晰,向量库已建立索引,延迟也在可接受范围内。但用户一直在抱怨结果是错的 —— 并不是完全错误,而是在关键细节上“稍微”有些偏差。检索到的片段讨论了正确的概念,但时间点不对。它涵盖了正确的主题,但司法管辖区不对。它提到了正确的产品,但缺少了使其真正有用的库存信号。

这就是嵌入微调鸿沟。通用嵌入模型被训练用来编码语义相似性 —— 即两个文本意思大致相同的属性。但这并不等同于相关性。相关性是特定于领域的、对上下文敏感的,并且对于在互联网规模的通用语料库上训练的模型来说通常是不可见的。

多语言 RAG 检索鸿沟:为什么跨语言查询会悄无声息地破坏你的向量搜索

· 阅读需 14 分钟
Tian Pan
Software Engineer

一个团队构建了一个 RAG 系统。英语检索召回率达到了 94%。他们发布了产品。三个月后,来自法国和德国用户的支持工单堆积如山——聊天机器人不断返回无关结果或根本没有结果。工程师们查看他们的监控仪表盘。整体召回率:91%。看起来一切正常。

语料库是英语。嵌入模型(Embedding model)仅支持英语。用户则不然。每一个法语查询都被嵌入到一个向量空间中,而这个空间的设计初衷从未考虑过与它所检索的英语文档共享坐标。余弦相似度并不低——但它们在几何上毫无意义。而且因为聚合指标掩盖了分布问题,在用户大声抱怨之前,这个问题是不可见的。

这就是多语言 RAG 检索差距,也是服务于非英语受众的生产级 AI 系统中最常见的静默失败模式之一。