跳到主要内容

141 篇博文 含有标签「rag」

查看所有标签

第三份副本:向量存储、删除完整性以及 RAG 团队一直忽视的 GDPR 缺口

· 阅读需 12 分钟
Tian Pan
Software Engineer

用户根据 GDPR 第 17 条提交了删除请求。你的团队删除了 Postgres 中的行,清除了 S3 中的缓存文档,并从 CDN 中轮换掉了缓存的 PDF。搞定。隐私团队签字,安全团队签字,工单关闭。六个月后,一名拥有向量索引读取权限的数据分析工程师为了一项聚类实验提取了一组 float[1536] 数组样本,通过公开可用的反演模型(inversion model)运行这些数据,并重建了原始 32-token 文本块中大约十分之九的内容——包括你已经“删除”的文档。没人预料到这一点。没人怀有恶意。流水线完全按照设计运行,只是威胁模型从未将向量存储视为数据副本。

在我见过的几乎每个 RAG 团队中,这种思维误区都是一致的:嵌入(embeddings)被视为不透明的数值产物——是衍生品,而非数据。安全评估批准上线是因为“嵌入不是 PII(个人身份信息)”。隐私评估批准了删除处理,是因为“源文本已不存在”。这两个团队都错了,谁都没有将向量存储建模为用户数据的第三份副本——它紧挨着源数据库和分析仓库,任何拥有索引读取权限的人都可以查询,且由于没有任何工具能识别出 1536 维的浮点向量属于敏感数据,它完全处于所有 DLP(数据泄露防护)扫描器的范围之外。

RAG 流水线中被你忽略的查询重写层

· 阅读需 12 分钟
Tian Pan
Software Engineer

当 RAG 系统回答错误时,大多数团队的第一反应是归咎于编码器(encoder)。更换更大的嵌入模型(embedding model)。尝试针对特定领域微调过的模型。增加维度。三个迭代周期(sprint)后,召回率曲线只提升了几个百分点,而用户的投诉看起来还是老样子。

诊断错了。大多数检索失败并非嵌入失败。它们是查询形状(query-shape)失败——在编码器运行之前就存在的词汇不匹配,无论如何调整向量都无法修复。

用户输入“如何取消”。相关的文档标题却是“订阅生命周期管理”,并使用了“终止”、“计费周期结束”和“服务停用”等词汇。世界上没有任何编码器能靠词汇运气将这两个字符串拉入同一个邻域。余弦相似度(cosine similarity)的差距是真实存在的,它存在于输入中,而非模型中。位于检索之前的查询重写层是大多数流水线跳过的步骤,随后他们却要花一个季度的时间试图在下游进行补偿。

Embedding API 的 “隐藏税”:为什么向量支出在不知不觉中超过了生成成本

· 阅读需 14 分钟
Tian Pan
Software Engineer

我在上个季度交谈过的一个团队在财务伙伴指出 AI 账单时陷入了短暂的恐慌。他们原以为,像大多数团队一样,昂贵的支出项会是生成——即聊天、总结和智能体推理背后的 GPT 级调用。事实并非如此。他们的每月 Embedding 支出在 1 月悄然超过了生成支出,到 3 月翻了一番,并有望在年中翻两番。没有人为此建模,因为 Embedding 模型的每 Token 定价看起来就像舍入误差:小型模型每百万 Token 2 美分,大型模型 13 美分。按照这个费率,谁会为此做预算?

答案是:任何产品度过了原型阶段并开始大规模索引内容的团队。在不断增长的语料库上进行语义搜索、重复检测、分类、聚类、更换模型时的重新索引——每一个工作负载消耗的 Embedding Token 都是以十亿计,而不是以百万计。与受用户请求限制的生成不同,Embedding 的吞吐量仅受你决定索引的内容限制。而这一决定很少经过成本审查。

本篇文章将探讨 Embedding 支出升级的具体机制、改变成本曲线的架构杠杆,以及从托管 API 转向自建服务的盈亏平衡计算。

Embedding 模型轮换是数据库迁移,而非代码部署

· 阅读需 12 分钟
Tian Pan
Software Engineer

在某个预发布(staging)频道里,一位工程师写道:“将嵌入模型(embedder)升级到 v3,新模型在 MTEB 上的得分提高了 4 分,冒烟测试通过后合并。”两天后,客服工单开始陆陆续续出现,反馈搜索结果感觉“莫名其妙地不对劲”。一周后,检索精度下降了 14 个百分点,余弦相似度分数从 0.85 暴跌至 0.65 左右,而且没人能解释原因——因为这次部署看起来与过去五次模型升级完全一样。这根本不是一次普通的部署。而是一次披着部署外衣的数据库迁移。

嵌入模型轮转是 AI 基础设施中最容易被归类错误的变更类型。它通过与提示词(prompt)微调或生成模型版本更新相同的渠道进入你的系统——配置文件、PR、CI 检查——因此它遵循配置变更的治理流程。但从底层来看,新的嵌入模型并不会产生旧向量的更好版本。它产生的向量完全存在于不同的坐标系中,跨两个流形计算余弦相似度是一个范畴错误(category error)。正确的心理模型不是“升级依赖版本”,而是“在提供读取服务的同时,为一个拥有 5000 万行的表更换主键编码”。

模型账单仅占你推理成本的 30%

· 阅读需 10 分钟
Tian Pan
Software Engineer

一家中型 AI 公司的财务负责人在上个季度告诉我,他们通过将 Agent 骨干模型从 Sonnet 切换到 Haiku,“优化了他们的 LLM 支出”。Token 账单下降了 22%,而每个已解决工单的总推理成本仅下降了 4%。当我们进行完整的成本拆解时发现,模型这一项支出大约仅占单次请求成本的三分之一。检索、重排序(reranking)、可观测性、重试放大以及人工介入(human-in-the-loop)审核队列吃掉了剩下的部分——而且当你更换模型时,这些环节都没有变得更便宜。

这是我目前在 AI 团队中看到的最常见的财务核算错误。Token 成本是你每月支付的发票上的分项,因此它成了每个人都在优化的数字。但对于任何非平凡的生产系统——RAG、Agent、任何带有工具调用或评估门控的系统——模型推理往往只占实际单位经济效益的 30% 到 50%。剩下的部分隐藏在你的工程仪表盘不会显示、且财务团队不会将其归类为 “AI 支出”的地方。

无结果并不代表不存在:为什么智能体将检索失败视为证明

· 阅读需 11 分钟
Tian Pan
Software Engineer

智能体对话记录中最危险的一句话不是幻觉。而是四个冷静的词:“我没有找到。”智能体听起来在认知上表现出谦逊。听起来像是完成了尽职调查。对于任何下游读者或调用者来说,这听起来完全像是一个事实。然而,这句话并没有提供关于该事物是否存在的信息。它只提供了关于特定工具在使用特定查询、咨询特定索引(而智能体恰好在那个时刻有权访问该索引)时发生了什么的信息。

在这两种解读之间,隐藏着一个随时可能发生的生产事故。支持智能体告诉客户“我们没有你的订单记录”,因为同步延迟导致写入只读副本的时间推迟了 90 秒。编码智能体声明“该模块没有测试”,因为它搜索了一个不包含测试文件夹的目录。合规智能体回答“档案中没有先前的违规记录”,因为审计索引尚未摄取上周的报告。在每种情况下,智能体的输出在语法上都是一种否定,但在认知上,它只是一个被重新表述为断言的“耸肩”。

向量检索中的流行度偏见:为什么相同的五个文本块总是主导每个查询

· 阅读需 13 分钟
Tian Pan
Software Engineer

从任何成熟的 RAG 系统中提取一周的检索日志,并按分块(chunks)被返回的频率进行排序。其分布形态几乎总是相同的:一小部分分块出现在数千次查询中,而语料库中的绝大多数内容仅出现几次,甚至从未出现过。系统没有故障。它正在精准地执行索引构建时的预期功能 —— 而这恰恰是问题所在。

这就是向量检索中的流行度偏差(popularity bias),而且随着语料库的增长,这种情况会变得更加严重。少数分块变成了“引力井”,在互不相关的查询中频频胜出,而长尾内容则悄然消失在 top-k 截断值之下。你的 RAG 系统开始让人感觉“平庸” —— 用户提出具体问题,得到的回答听起来却像是为别人写的一样。等到产品部门开始投诉时,这种分布不均的情况往往已经持续数周了。

你的 RAG 分块器是一项无人 Review 代码的数据库 Schema

· 阅读需 13 分钟
Tian Pan
Software Engineer

当检索质量回退(retrieval quality regression)第一次出现在你的值班频道(on-call channel)时,调试路径几乎总是指向一些令人意外的地方。不是嵌入模型(embedding model),不是重排序器(reranker),也不是提示词(prompt)。罪魁祸首通常是对分块器(chunker)的一行改动——比如更换了分词器、调整了边界规则或步幅(stride)——而这行代码是三个冲刺(sprint)前有人合并进预处理 notebook 的。这次修复没有触及任何生产代码。它在夜间重建了索引。而现在,所有租户的准确率都下降了四个百分点。

分块器就是数据库 Schema。你提取的每个字段、划定的每个边界、选择的每个步幅,都定义了存入向量索引的“行”的形状。修改其中任何一项,你就在改变索引的 Schema。而你系统的其他部分——检索逻辑、重排序特征、评估框架、下游提示词——都依赖于这个索引,并假设它是稳定的。但由于分块器通常存在于 notebook 或一个没人将其视为“基础设施”的小型 Python 模块中,这些改动在上线时往往只被当作配置微调,但其爆炸半径却相当于执行了一次 ALTER TABLE

为什么你的 RAG 引用在撒谎:源归因中的事后合理化

· 阅读需 12 分钟
Tian Pan
Software Engineer

向用户展示一个带有 AI 答案的界面,且每句话末尾都附有链接,还没等他们读完任何一个引用的段落,他们的信任度就已经飙升。这正是企业级 RAG 的全部营销卖点:“有据可查”、“有源可循”、“可验证”。这也是 AI 工程领域中交付最多、但测试最少的说法。最近的基准测试发现,50% 到 90% 的 LLM 回复并未得到其引用来源的完全支持,有时甚至与来源相矛盾。在对抗性评估集中,最先进模型生成的引用中有高达 57% 是不忠实的:模型根本没有真正使用它指向的文档。这些引用是事后补上去的,目的是为了让模型已经决定给出的答案显得合理。

这不是检索层面的 Bug。即便你拥有完美的检索系统,仍然会得到虚假的引用,因为这种失效是架构性的。生成器先写出文字,然后再缝补链接。这些链接看起来像证据,实则只是装饰。

归因鸿沟:如何将用户投诉追溯到具体的模型决策

· 阅读需 13 分钟
Tian Pan
Software Engineer

一张支持工单送达:「你们的 AI 对我的保险条款给出了完全错误的建议。」你查看日志,找到了时间戳和用户 ID,最终模型响应也原文呈现在那里。但你根本不知道是哪个提示词版本产生了这条输出、检索步骤取回了哪些上下文片段、中间是否调用过工具,也不知道你过去一个月部署的三个模型版本中究竟是哪个处理了这个请求。你能读到输出,却无法解释它。

这就是归因鸿沟——大多数 AI 团队在首次上线模型功能后六到十八个月都会撞上这道墙。问题不在模型或提示词,而在可观测性基础设施。传统日志记录的是请求-响应对,而 LLM 流水线并非请求-响应对,它是一棵决策树:上下文检索、提示词组装、可选工具调用、模型推理、后处理、条件分支。出现问题时,你需要看到完整的树,而不仅仅是叶子节点。

摊销上下文:持久化智能体记忆 vs 长上下文窗口

· 阅读需 10 分钟
Tian Pan
Software Engineer

当 100 万 token 的上下文窗口实现商业化时,许多团队悄然认定,他们已经解决了智能体记忆(agent memory)的问题。当你可以把所有内容都丢进去并让模型自己处理时,为什么还要构建检索系统、管理向量数据库或设计淘汰策略(eviction policy)呢?答案就在你的基础设施账单中。在每天 1 万次交互、拥有 10 万 token 知识库的情况下,这种暴力的上下文内(in-context)方法每天的成本约为 5,000 美元。而处理同样负载的检索增强记忆系统的成本约为每天 333 美元 —— 随着用户群的增长,这 15 倍的差距会产生复利效应。

真正的问题不仅仅是成本。更严重的是,更长的上下文会导致答案质量显著下降。研究一致表明,模型会丢失位于极长输入中间位置的信息;当相关的证据被埋没在无关的代码块(chunks)中时,准确率会如预见般下降;且延迟的攀升会使交互式智能体显得反应迟钝。这种“塞进一切”的方法不仅浪费金钱 —— 它还以牺牲准确性为代价换取了简单化的假象。

AI缓存失效:为什么答案可以改变时每个缓存层都更难处理

· 阅读需 11 分钟
Tian Pan
Software Engineer

Phil Karlton有句名言——"计算机科学中只有两件难事:缓存失效和命名"——这句话诞生于语言模型进入生产之前。将AI加入技术栈后,缓存失效不只是变得更难;它在每一层同时变得更难,而且每一层的原因从根本上不同。

传统缓存存储的是确定性输出:数据库行、渲染的HTML、计算出的价格。当源数据变化时,你使该键失效,下一个请求获取新数据。契约很简单,因为答案是一个事实。

AI缓存存储的是不同的东西:对查询的响应,而这些响应的"正确"答案取决于上下文、时效性、模型行为以及模型所获取的源文档。这里的"陈旧"不意味着过时——它意味着在语义上出错,而你的监控不会发现,直到用户注意到为止。