跳到主要内容

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

查看所有标签

先收敛、后悄然崩溃的评估

· 阅读需 12 分钟
Tian Pan
Software Engineer

你的每周评估(eval)仪表盘变平了。曾经在 0.71 到 0.78 之间波动的曲线,已经在连续三个发布周期中紧缩成 0.84 左右的一根细线。团队将其解读为达到了天花板——模型已经达到了评分准则(rubric)允许的上限,进一步的工作需要更难的评估。有人安排了一场规划会议来“设计 eval v2”。

这种解读看似合理,有时也确实正确。但还有第二种解释,它会产生同样的图景,并悄悄摧毁你的发布准入信号:你的标注员(无论是人类还是 LLM 评判员)已经在意见上趋同,评估不再是在衡量模型,而是在衡量模型产出标注员心目中“正确”输出形态的能力。

你的数据驻留政策中遗漏的推理区域锁定

· 阅读需 10 分钟
Tian Pan
Software Engineer

合规审计总是从同一个问题开始,而你的团队也总是以同样的方式回答:“客户数据在哪里处理?”在欧盟(EU)地区。幻灯片是这么说的,SDK 配置截图证实了这一点,DPA(数据处理协议)也做出了承诺。接着,审计员提取了上个季度的请求日志样本,将其与服务商的每请求区域头信息(per-request region header)进行比对,房间里顿时安静了下来。在大约 40 分钟的容量事件期间,大约 4% 的欧盟企业 Prompt 由美国区域的推理节点提供服务,而团队对此一无所知。保存可重用前缀(prefixes)的缓存位于全球池中。支持团队查询的追踪存储(trace store)位于 us-east。DPA 成了幻灯片。合同成了一个路由提示(routing hint)。

这种事件不会出现在事后分析(postmortem)中,因为没有任何服务降级。模型返回了答案,用户得到了响应,延迟图表保持平稳。出故障的是仪表盘从未监测到的东西:请求穿过服务商基础设施的地理路径。那些绝不会将 us-east-1 的 URL 与“请求实际上在 us-east-1 执行”混为一谈的工程师,在 LLM API 层级却经常犯同样的错误,因为服务商的区域参数看起来像 AWS 的参数,在正常路径(happy path)下表现也像 AWS,但一旦首选区域的 GPU 耗尽,它就会静默降级为“尽力而为(best effort)”模式。

带有延迟预算的紧急开关:你的故障处理从未达到的标准

· 阅读需 13 分钟
Tian Pan
Software Engineer

运维手册上写着“禁用代理”。值班人员照做了。43 分钟后,当紧急开关终于通过配置服务传播开来时,该代理已经提交了 1,200 张错误的工单,调用了 8,000 次计费 API,并向根本没有订阅任何服务的客户发送了邮件。运维手册是正确的,但它也是徒劳的,因为没有人衡量过当代理每秒钟都在造成破坏时,“禁用代理”实际上需要多长时间。

!["https://opengraph-image.blockeden.xyz/api/og-tianpan-co?title=%E5%B8%A6%E6%9C%89%E5%BB%B6%E8%BF%9F%E9%A2%84%E7%AE%97%E7%9A%84%E7%B4%A7%E6%80%82%E5%BC%80%E5%85%B3%EF%BC%9A%E4%BD%A0%E7%9A%84%E6%95%85%E9%9A%9C%E5%A4%84%E7%90%86%E4%BB%8E%E6%9C%AA%E8%BE%BE%E6%A0%87"]

大多数 AI 功能都配有紧急开关,就像大多数建筑都配有灭火器一样:有人签字确认它的存在,却没人计时到达它需要多久。合规审查会问“是否有紧急开关?”,答案是肯定的。而故障现场会问“止血有多快?”,答案则取决于底层管道恰好需要的时间——团队中从未有人针对该功能造成破坏的速度测量过这个数字。

这种不匹配正是问题的核心。一个遏制时间长于其破坏扩散时间的功能,交付的只是“遏制剧场”(Containment Theater)。

你的 AI 功能路线图从未计算过的法律审查时间表

· 阅读需 11 分钟
Tian Pan
Software Engineer

你画了一个包含六个季度的 AI 路线图。模型切换、新数据源、多语言发布,以及现在提供建议的提示词,在甘特图上各占一行,并根据工程量的大小确定了尺寸。接着,第一次发布推迟了四周,而复盘报告在三个不同的章节里重复了三次同样的话:“正在等待法务。”路线图原本假设工程能力是关键限制。而实际的瓶颈约束是一堆法务审查队列,每个审查都有自己三到六周的 SLA,且彼此互不知晓,最终全都压在仅有的两名产品法务身上。

错误并不在于任何一项单独的审查。每一项都是有理有据的。错误在于将四个并行功能视为四个并行的时间线,而它们的法务依赖却通过同一个上游资源进行串行处理。到第二次延期时,组织了解了问题的轮廓。到第四次时,它学会了针对此进行规划。那些能够以可预测节奏发布 AI 功能的团队,已经不再将法务吞吐量视为外部的意外,而是开始将其视为与人力和基础设施容量同等地位的规划输入。

那个在你的代码冻结期间送达的模型弃用通知

· 阅读需 9 分钟
Tian Pan
Software Engineer

邮件是在周二发出的。你那两个最重要的功能所依赖的 Checkpoint 进入了 90 天的下线期。你的工程团队正处于为了另一个发布而进行的协同代码冻结(Freeze)的第二周。等到冻结解除时,你将只有不到三十天的时间来针对新模型重新验证两个生产环境的功能——这里的“重新验证”意味着重建评估集、运行影子流量、获得产品负责人签字,并在一个没人关注的 Feature Flag 之后发布,因为发布团队还在忙着处理代码冻结原本针对的那个项目。

这种冲突并不少见。主要供应商发布废弃周期的频率是以月为单位的,每个在托管模型上运行的团队现在都经历过至少一个周期。团队尚未吸收的教训是,供应商的废弃并不是像库升级那样的工程事件——它是一个运行在你无法控制的时钟上的排程事件,任何没有预留预算的路线图都会将这笔成本视为一场意外。

那个把你唯一的硬样本也顺便带走的近似去重过滤器

· 阅读需 12 分钟
Tian Pan
Software Engineer

你的去重步骤报告显示语料库缩减了 28%,训练运行提前六小时结束。评估数值持平甚至略有提升。没人去查看被删除内容的 diff。三周后,客服开始因为一类模型曾经能处理、现在却完全搞砸的退款反转工单进行告警。有 11 条训练数据涉及该特定模式。其中 9 条消失了——它们被合并为一个单一的代表样本,保留了最简洁、最干净的措辞,却丢弃了那些模型实际从中学习如何缓和情绪的、语带敌意的复杂变体。你的去重流水线造成了这一切,而你的评估并没有捕捉到它,因为在构建评估集时,这些例子已经从用于采样评估集的训练集中消失了。

这是关于去重作为一个流水线步骤让我感到困扰的失效模式:它表现为数据清洗,实际上却是分布编辑。删除样板文件的完全重复是清洗。通过相似度阈值删除近重复项则是一种包装成清洗的采样决策。阈值决定了训练分布中哪些切片能存活下来,而最容易丢失的切片正是你起初样本最少的那些——根据定义,这些样本通常是你为了覆盖率而非样本数量而保留的。

你的编程智能体生成的那些人类已经不再阅读的 PR 描述

· 阅读需 12 分钟
Tian Pan
Software Engineer

一年前,你的团队采用了 PR 描述模板。它包含 ## Summary## Changes## Test plan 和一排复选框。审查者非常喜欢它:每个 PR 都有上下文,每个 PR 都有测试计划,每个 PR 都有结构。六个月后,编程助手学会了填写它。现在,每个 PR 依然有 ## Summary## Changes## Test plan 和一排复选框 —— 但审查者不再阅读标题以外的内容了。曾经聚焦注意力的格式,现在反而成了“此处不值得关注”的信号。结构比它所承载的信号寿命更长。

这不是代码质量问题。这些 PR 中的代码通常是没问题的。问题在于,撰写描述的行为已经从思考变更的行为中被剥离,而描述正是审查者用来分级处理(triage)其有限注意力的工具。当该工具变得格式统一、措辞合理,且与其他所有 PR 毫无区别时,审查者的注意力分级机制就失效了。曾经用于挖掘异常情况的系统,现在将所有内容摊平成了同样的形状。

提供商故障转移:在对话中途替换了你安全策略的隐忧

· 阅读需 12 分钟
Tian Pan
Software Engineer

用户正与你的助手进行一场关于受控物质处方模式的谨慎对话,已经进行了十二轮。模型表现得很有分寸,提出澄清性问题,引用指南,并拒绝进行文献之外的推演。在第十三轮,用户提出了一个后续问题,按理说应该得到与前十二轮相同的回应。然而,他们得到的却是一个生硬的拒绝:“我无法提供相关帮助。”对话结束了。他们怒气冲冲地给支持团队写信——他们并没有问任何不同的内容,助手刚才还在帮助他们,到底发生了什么变化。

你的日志解释了变化的原因。在第十三轮进行到一半时,你的主供应商在流式传输过程中返回了 503 错误。你的网关按照配置执行了操作:在请求的剩余部分故障转移(failover)到了备用供应商。备用供应商对该类查询的拒绝阈值校准得比主供应商更保守。用户并没有问任何不同的问题——他们在同一个品牌下对不同的模型提出了相同的问题,而新模型说了“不”。

你那两个独立的评估指标正不断破坏拒绝校准

· 阅读需 14 分钟
Tian Pan
Software Engineer

调出过去四次模型升级的仪表盘,查看安全指数(safety number)旁边对应的帮助指数(helpfulness number)。在每次发布中,总有一个指数在变动,而且几乎从不是同一个。负责安全评估的团队发布了一个“将拒绝加固提升了 6 个点”的修复程序,三周后,负责帮助性评估的团队发布了一个“在合法查询完成度上恢复了 5 个点”的修复程序。然后,循环再次开始。

这并不是两个团队在各自取得独立进展。而是一个模型在沿着同一个轴摆动,而组织却在用两把相反的尺子测量它,每把尺子上所谓的胜利都是另一把尺子上无声的损失。刚刚庆祝了安全性能提升的团队,在不经意间发布了一个拒绝更多合法医疗问题、法律问题和“如何做”问题的模型——而这些问题的词干恰好看起来像训练数据中的不安全内容。由于这种帮助性的倒退属于不同的冲刺周期、不同的负责人和不同的仪表盘,因此它被忽视了。

擦除模型仍在读取的上下文:数据保留策略带来的隐患

· 阅读需 13 分钟
Tian Pan
Software Engineer

一个每晚运行的数据留存 worker(retention worker)会删除任何超过 30 天的用户消息。一个从 3 月初开始的长周期企业支持会话,到 5 月底仍然处于活跃状态。在第 41 轮对话请求进来时,你的 Prompt 组装器(prompt assembler)从同一个消息表中读取数据,而那个留存 worker 一直在悄悄地清理这个表。第 1 到 28 轮已经消失了。模型接收到的对话是从第 29 轮开始的,没有任何信号表明之前的对话曾经存在过。用户问道:“我们之前商定的 SLA 是什么?”模型自信地编造了一个数字,因为真正的答案在第 4 轮——而留存 worker 在前一天晚上把它删除了。

这不是模型故障。模型完全按照其应有的方式运行:从交给它的上下文中生成一个看似合理的答案。故障发生在更上游,处于两个团队之间的鸿沟中——每个团队都认为自己拥有消息表。

你的仪表盘以三种不同方式统计了那次重试

· 阅读需 13 分钟
Tian Pan
Software Engineer

一个 Agent 运行了。计划步骤(plan-step)崩溃了。工具调用(tool-call)步骤在经历了两次 500 错误重试后,在第四次尝试时成功了。用户得到了他们的答案。

那算是多少个事件?问产品,这是一个事件 —— 用户得到了有效结果,因此转化漏斗统计了一次转化。问 SRE,那是三个失败加上一个成功,底层步骤的错误率是 75%。问财务,那是四次计费推理,两次重试的工具调用,以及大约四倍于产品部门预测的单位成本。每个团队的仪表盘都是正确的。但它们也是不可调和的,一旦有人试图调和它们 —— 通常是在事故回顾期间 —— 他们会发现团队已经基于三个相互矛盾的可信度图景运行了数月之久。

与验证器共享盲点的自我修正循环

· 阅读需 10 分钟
Tian Pan
Software Engineer

在智能体复盘中流传的截图每次看起来都一模一样。一段长长的追踪记录。一个单一的任务。十二次迭代。智能体生成了草稿,进行了评估,发现了一个小瑕疵,生成了修订版,进行了评估,发现了一个略有不同的微小瑕疵,接着又生成了另一个修订版。验证器返回的分数一直徘徊在 0.78 到 0.84 之间。它从未跨越门槛。智能体从未上报异常。三小时后,任务因超时而终止,产生了一笔足以支付一名高级工程师四分之一日薪的 Token 账单。

团队将其称为“自我修正”问题,因为架构图上就是这么标注的。实际的失败是结构性的。验证器其实就是换了一个提示词的生成器。收敛准则是模型自己的意见。重试预算是隐式的,受限于智能体的超时时间,而不是由智能体本身推理决定的。这三个失败孤立来看都不像是 Bug,这正是团队会将其上线的原因。