跳到主要内容

553 篇博文 含有标签「ai-engineering」

查看所有标签

LLM 模型路由是伪装成成本优化的市场细分

· 阅读需 11 分钟
Tian Pan
Software Engineer

成本仪表盘本身就很有说服力。60% 的流量是“简单”的,快速评估显示较小模型在全局准确率指标上仅落后几个百分点,路由层在同一周内通过特性开关(feature flag)上线。成本曲线开始下行。财务部皆大欢喜。团队继续推进后续工作。

没有人注意到的是,周二下午走廉价路径、周三上午走昂贵路径的客户,现在实际上在使用两种不同的产品。这两个模型的失败方式不同。格式化方式不同。拒绝的内容不同。它们以不同的默认逻辑处理歧义、追问和部分输入。从客户的角度来看,助手一夜之间失忆了,而且没人能告诉他们原因——因为在公司内部,这次变更被归档为一次 FinOps 的胜利,而不是一次产品发布。

多语言评估成本放大效应:为什么七个语种的成本不只是 7 倍

· 阅读需 16 分钟
Tian Pan
Software Engineer

在国际化发布的财务规划电子表格中,有一个清晰的项目:“将评估覆盖范围扩展到七个新语言区域 —— 假设为当前评估成本的 7 倍。”英语评估套件耗时两周,花费 4 万美元构建,因此七个语言区域将花费 28 万美元和一个季度的工程时间。CFO 签字了。产品 VP 签字了。发布启动了。

六个月后,实际的评估账单已经突破 31 万美元,团队仍在搭建最后两个语言区域。标注供应商在葡萄牙语(巴西)人员库中已经换了三批人,因为前两批产生的人员间一致性(inter-rater agreement)分数,任何诚实的审查都会称其为随机。德语裁判模型(judge model)在相同内容上的评分比英语模型低 6% —— 团队最初将其解读为德语模型的退化(regression),直到人工审核发现裁判模型本身才是退化的根源。评估负责人每周要花 40% 的时间处理一个没人预算过的问题:我们如何知道语言区域 A 的通过率确实比语言区域 B 差,而不是因为跨语言区域的测量比差距本身的噪声更大?

你的值班轮换需要 AI 素养作为前提,否则不要在凌晨 2 点给任何人发报警

· 阅读需 13 分钟
Tian Pan
Software Engineer

一位拥有 8 年事故响应经验的平台工程师打开了一条凌晨 2 点的报警信息:“AI 助手性能下降 —— 错误率 12%”。她检查了模型延迟仪表盘:绿色。检查了模型 API 状态页:绿色。检查了部署日志:过去 72 小时内没有任何变更。她做了任何称职的值班人员接下来会做的事 —— 呼叫 AI 团队。AI 工程师醒来,打开了平台工程师甚至不知道存在的追踪 (trace) 仪表盘,发现一个检索工具在过去 4 小时内一直超时,原因是一个下游搜索索引丢失了一个副本,并在 11 分钟内解决了事故。AI 工程师在凌晨 3:14 重新入睡。第二天早上的复盘记录写道:“AI 功能故障,由 AI 团队解决”。没有人写下真正的教训:如果这位值班工程师曾被教导过 AI 功能的故障面 (failure surface) 长什么样,她本可以在 5 分钟内完成分流 (triage)。

这是 AI 功能在过去两年中,向我合作过的每一个工程团队悄悄征收的“轮换税”。曾经完美适用于无状态服务堆栈和几个数据库的共享值班轮换,在其中一个“服务”变成由 LLM 驱动的功能时就会崩溃。你的 SRE 团队通过十年的事故复盘建立的值班手册,是为一个“某处出错了”可以分解为 CPU、内存、网络、部署和依赖超时的世界而校准的。AI 功能增加了三个维度 —— 模型、提示词 (prompt)、检索管道 —— 以及四种值班人员从未接受过识别培训的故障形态,这些故障不会出现在他们习惯查看的仪表盘上。

端侧 AI 需要的是机群管理器,而非模型卡片

· 阅读需 13 分钟
Tian Pan
Software Engineer

上一季度发布的端侧 AI 演示在单台测试手机上运行了一个 4-bit Llama 变体,表现出色。六个月后,同样的功能却收到了一连串的一星差评,用户抱怨发热、耗电,或者更糟糕的是——无声的质量下降,用户只觉得“老手机上的 AI 变傻了”。模型没变,但机群(fleet)变了。那些原本以为是在交付模型的团队后来才发现,他们交付的其实是一个机群。

这就是导致大多数端侧 AI 发布失败的鸿沟:策略是围着选择“那个”模型转,而真正的难点在于如何为每类设备交付“合适的模型”,观察其运行情况,并在出问题时回滚。弥合这一鸿沟的学科更像是 CDN 运营,而非 ML 研究——清单驱动(manifest-driven)的交付、按分群的遥测、解耦的发布渠道,以及能从一个训练好的检查点生成 N 个量化分级的模型变体流水线。大多数团队并不具备这些,他们只有一个模型卡(model card)和一个构建产物。

提示词弃用合约:为什么措辞清理是一项破坏性更新

· 阅读需 11 分钟
Tian Pan
Software Engineer

系统提示词(system prompt)上一个四个词的修改——用 "respond using clean JSON"(使用干净的 JSON 响应)替换 "output strictly valid JSON"(输出严格有效的 JSON)——在评估(eval)中一度没有引起任何波动。它在周四发布,却在周五凌晨 4 点被回滚,因为结构化输出的错误率从 0.3% 飙升到了 11%。提示词并没有变糟。它只是变得“不同”了,而下游解析器在无人察觉的情况下,已经固化(pinned)在了 "strictly valid" 这个词组上。

这是大多数提示词工程(prompt-engineering)团队尚未建立工具来应对的失效模式:提示词被视为作者拥有的文本,而实际上它是与作者从未见过的消费者之间的一份合约。这些消费者中,有些是逐字引用原句的其他提示词;有些是 JSON 模式(JSON schema)字段锚定在特定形容词上的工具描述;有些是其评分标准(rubrics)要求裁判(judge)检查“严格有效格式”的评估(evals);还有一些是解析器——最脆弱的一类——其正则表达式是根据模型输出的精确前导语(preamble)进行校准的。

一次“小小的措辞清理”会悄无声息地破坏解析器、导致裁判校准偏移,并使数周的评估运行失效。这些失败都不会在 PR(拉取请求)中显示出来,而是在一周后作为“偏移”(drift)出现在仪表盘上。

Prompt Linting 是 Eval 与生产环境之间缺失的一层

· 阅读需 12 分钟
Tian Pan
Software Engineer

事故报告读起来就像一个单元测试的恐怖故事。一次 Prompt 编辑作为“前置说明清理(preamble cleanup)”的一部分,删除了一段五行的安全条款。测试套件中的每个 Eval(评估)都通过了。每个 Judge(裁判)评分都保持在容差范围内。两周后,一个面向客户的助手产生了一个本该被拒绝的响应,这种响应会在深夜 11 pm 触发信任与安全(Trust & Safety)页面的报警。复盘将这次回归追溯到了一个 PR 中的单处删除,而当时没有任何人标记它,因为负责捕捉回归的套件对安全条款是否存在没有意见——它只对模型在套件记得询问的情况下的表现有意见。

!["https://opengraph-image.blockeden.xyz/api/og-tianpan-co?title=Prompt%20Linting%20%E6%98%AF%20Eval%20%E4%B8%8E%E7%94%9F%E4%BA%A7%E7%8E%AF%E5%A2%83%E4%B9%8B%E9%97%B4%E7%BC%BA%E5%A4%B1%E7%9A%84%E9%82%A3%E4%B8%80%E5%B1%82"]

这就是行为评估(behavioral evals)与结构正确性之间的鸿沟。Eval 衡量的是模型生成的内容;它们不衡量 Prompt 本身是什么。而 Prompt 就像代码一样,有一个独立于行为而存在的结构层——必须存在的章节、必须解析的引用、必须插值的变量、必须遵守的长度预算、以及绝不能出现的弃用标识符。当结构层断裂时,行为表现通常会在一段时间内保持绿色,直到生产环境中的某个边缘情况将故障暴露为事故。

潜伏在 Few-Shot 提示词模板中的客户记录

· 阅读需 12 分钟
Tian Pan
Software Engineer

隐私审计员在 SOC 2 续期前两天提出了一个问题:“为什么你入门引导提示词示例中的电子邮件字段是一个真实客户的地址?”产品团队在脑海中回溯了整个流程。一年前,当他们发布 AI 摘要功能时,有人需要为 few-shot 模板找一个“看看它是如何工作的”示例。他们从预发布环境(staging)中选取了一条具有代表性的客户记录,清理了明显的字段——姓名、账户 ID、电话——并提交了文件。该客户在六个月后流失了。根据数据保留政策,他们的记录已从数据库中删除。但该记录并没有从提示词模板中删除,而该模板已发布到了生产环境中的每一个租户。

团队曾像大多数团队一样,认为隐私边界就是数据库。提示词模板是代码。代码要经过评审。评审并不会标记 PII(个人身份信息),因为评审人员不会在标记为 example_input: 的 YAML 字符串中寻找它。能在 Slack 消息和邮件附件中捕捉 PII 的 DLP(数据泄露防护)扫描器不会扫描提交的代码,即使扫描,它也不会将部分清理过的客户记录识别为个人数据,因为它知道要查找的字段已被移除。剩下的所有内容——公司规模、行业、稀有的职位名称、特定的城市——都是扫描器没有规则去处理的数据。

拒绝延迟税:为什么分层护栏会侵蚀你的 p95 延迟预算

· 阅读需 11 分钟
Tian Pan
Software Engineer

我最近交流的一个团队为他们的 AI 助手构建了一个所谓的“深度防御”(defense in depth)流水线。一个输入分类器检查提示词注入;一个越狱过滤器扫描对抗性模式;模型生成回复;一个输出审核环节扫描结果;一个拒绝检测器检查模型是否回避了问题,如果是,则通过重新表述步骤,用更委婉的框架再次提问。评估套件显示该提示词在 1.4 秒内生成了答案,但真实用户的等待时间中值是 3.8 秒,p95 则超过了 9 秒。

每一个安全层都是一次往返。每一次往返都包含网络跳数、排队时间、模型加载和解码。当你将它们串行地堆叠在生成调用前后时,你为产品设定的延迟预算就会灰飞烟灭——而几乎没人在设计评审时考虑到这一点。更糟糕的是:流水线中最慢、最昂贵的路径往往是那些触发了安全边缘提示词的路径,而这恰恰是你的安全机制存在所要处理的长尾场景。你正在默默地用普通用户的账单来补贴这些长尾流量。

停用 AI 功能是一次信任事件,而非简单的功能弃用

· 阅读需 14 分钟
Tian Pan
Software Engineer

数据指标告诉你该砍掉它了。3% 的月活跃用户。评估(Eval)刷新已经推迟了两个周期。Prompt 中还有一个一年前留下的 // TODO: 在脱离旧版工单架构时重新审视。你的资深 AI 工程师每月要花整整一周的时间来照看这个功能 —— 模型升级、标签偏移,还有一个只要上游 API 更改日期格式就会挂掉的工具集成。每次季度评审,总有人会问为什么这个助手仍然存在,而每个季度的回答都是“我们还没顾上处理它”。

于是你写了一份弃用备忘录。你参考了平台团队完善的 API 停用手册:提前 6 个月的公告、迁移指南、产品内横幅提示、面向合作伙伴的 Webhook,以及常见的 Sunset: HTTP 标头。你在周二发布了它。到了周四下午,你的客户成功经理(CSM)转发来的邮件听起来完全不像是对 API 弃用的投诉。它们听起来更像是分手信。

在那一刻,大多数团队才意识到他们将一个类别错误带到了生产环境。你要弃用的不是一个 API,而是用户与一个能够回应他们的实体建立的关系。

检索膨胀:当“加个 RAG 就行”变成架构上的干扰

· 阅读需 12 分钟
Tian Pan
Software Engineer

这种模式太熟悉了,以至于被视而不见。模型幻觉出了一个事实,于是团队增加了一个检索步骤。三周后,模型从不断增加的工具库中选错了工具,于是他们在工具目录上增加了一个检索步骤。模型的回答感觉太笼统,于是他们在过去的高质量回答上增加了一个检索步骤。一个季度过去了,系统现在变成了一堆检索器拼接在一起的提示词,而本质上,最初的问题依然存在。

改变的不是失败率 —— 而是失败模式的名称。“模型出错了”变成了“检索未命中”,这听起来更易处理,但事实并非如此。评估套件的分数更高了,因为从构造上讲,检索到的上下文对于测试集来说是分布内(in-distribution)的。生产环境的情况则截然不同,但到那时,架构已经有了三个检索层,每一层都有自己的嵌入模型、索引刷新频率和值班轮换,而且没有人想成为那个提议拆除它们的工程师。

这就是检索膨胀(retrieval sprawl)。这是一种架构上的分心:一种将难题(提示词设计、模型能力、模糊的规范)转移到更舒适的问题(信息检索工程)上,而实际上没有解决任何问题的方式。

你的审核队列是自主权承诺消亡之地

· 阅读需 10 分钟
Tian Pan
Software Engineer

发布的 AI 功能带有一个完美的“安全方案”。任何置信度高于阈值的请求都会自动执行。任何低于阈值的请求都会进入人工审核队列。刚发布时,每天下午 5 点队列就会被清空。市场部门在幻灯片上写下“人工参与(human-in-the-loop)”。合规部门签字批准。大家打道回府。

六个月后,该功能的使用量增长了 10 倍,但审核团队并没有。队列里堆积了 72 小时的待办任务。一个需要“人工审核”的项目在未读状态下躺了三天,然后被一名疲惫的审核员批准——他平均处理一个决策只需 11 秒,因为只有这样才能保证队列不会在夜里翻倍。产品依然宣称“每项操作都经过审核”。现实情况是,“人工参与”已经退化成了“人工最终会在队列里看到”——这在功能上其实就是带有文书延迟的自主运行。

安全方案并不是因为 Bug 而失效,而是因为一个没人负责的人力资源计划而崩溃。

下午 3 点和凌晨 3 点的同一个 Prompt 并不是同一个 Prompt:LLM 评估中的昼夜漂移

· 阅读需 13 分钟
Tian Pan
Software Engineer

评估套件在凌晨 2 点运行。流量很低。缓存是冷的,但队列是空的。供应商的连续批处理程序有空闲插槽,并将以接近其 TTFT(首 Token 延迟)底线的水平处理每个请求。延迟分布很紧凑,评测模型分数稳定,仪表盘显示一片绿色。团队发布上线。

六个小时后,太平洋时间上午 8 点,同样的 Prompt 在美国早高峰期间进入生产环境。p95 延迟是评估报告的 2.4 倍。相当一部分请求从一个供应商那里收到了 529 错误,并回退到另一个供应商的较小路由层级。流式传输的节奏更加断断续续。评测模型(当天晚上对生产环境追踪样本进行重新运行)给出的中位数得分比凌晨 2 点给出的相同 Prompt 的得分低了半分。代码库没有变化。Prompt 没有变化。只是挂钟时间变了。

必须意识到的架构真相是:LLM 调用不是其输入 Token 的纯函数。它是一个随机分布式系统调用,其输入包括挂钟时间、供应商集群的负载、Prompt 缓存的状态、当前解码批次的大小,以及供应商负载均衡器在你的请求到达的那一毫秒所做出的路由决策。在凌晨 2 点运行评估的团队,是在一种用户永远无法体验到的条件下校准仪器。