跳到主要内容

113 篇博文 含有标签「evals」

查看所有标签

AI 功能的 Bug Bash:分布采样,而非猎捕缺陷

· 阅读需 12 分钟
Tian Pan
Software Engineer

经典的 Bug Bash 是一种为确定性软件量身定制的确定性仪式。十名工程师挤在一个 Slack 频道里两小时,对照着黄金路径流程清单疯狂测试,然后提交带有清晰复现步骤的工单:“点击 X,看到 Y,预期 Z。” 这套方法之所以奏效,是因为被测系统是可复现的——相同的输入,相同的输出,相同的 Bug,次次如此。

如果针对 AI 功能运行完全相同的仪式,你最终会得到 200 张工单,其中 180 张会因为“符合预期的随机波动”而被关闭,同时还会漏掉那 20 张预示着真正的群体性回归(cohort regression)的工单。这种形式不仅陈旧,而且完全错位了。针对基于 LLM 的功能进行 Bug Bash 并不是一场捕捉缺陷的会议。它是一场针对概率分布的抽样练习,如果团队像运行确定性测试那样运行它,就是在收集噪声并将其视为信号。

这篇文章讨论的是如何为随机系统重新设计 Bug Bash——包括流程形式、参与者、分级准则以及什么才算“完成”等方面需要做出哪些改变。

蒸馏是一个产品决策,而非研究产物

· 阅读需 11 分钟
Tian Pan
Software Engineer

一个基于前沿模型的聊天功能,单次对话成本大约是 30 美分。而同功能的蒸馏版本,单次对话成本大约只有 0.3 美分。这并不是同一个产品的两种实现方式,而是两个截然不同的产品。它们有着不同的免费层级经济模型、不同的获客成本、不同的市场定位以及不同的竞争护城河。如果一个团队只是将蒸馏版本当作“更便宜的同款功能”发布,那就白费了这一招。

大多数工程组织仍将蒸馏视为研究团队的优化任务,认为是在功能“完成”后,为了挤出推理成本而对已经按前沿模型规格设计好的东西进行的后期处理。这种理解在数量级上就是错误的。Teacher 模型(教师模型)的选择、Student 模型(学生模型)的选择、用于评测 Student 的评估套件,以及 Student 最终部署的产品界面,本质上都是产品决策。它们决定了你同意放弃哪些能力、你为哪种流量形态进行设计,以及你正在开启哪种价格底线。如果把这些交给研究团队去针对 MMLU 进行优化,你最终发布的模型虽然在榜单上表现优异,但对产品本身毫无意义。

Eval-as-Code:当你的发布门禁只是某人笔记本电脑上的一个 Notebook

· 阅读需 14 分钟
Tian Pan
Software Engineer

决定一个模型是否上线生产环境的数字,是由运行在某个工程师 MacBook 上的 Jupyter Notebook 生成的。数据来源是 Slack 私聊中的一个 CSV 文件,评分则由一个没人固定版本的裁判模型完成。两周后,在工程师又动了三次 Notebook,且 API 供应商悄悄发布了一个微小的模型更新后,团队里已经没人能重现那个数字了——包括当初生成它的那个工程师。然而,那个数字就是准入闸门。它决定了 GPT-4o-mini 是否足以在客户支持流程中取代 GPT-4;它决定了新提示词模板的发布;它决定了微调模型的晋升。团队把它视为核心承重构件,却像对待便利贴一样存储它。

这就是“评估差距”(eval gap)。五年来,业界一直在将评估视为一个方法论问题——哪种评分技术、哪种裁判模型、哪种评分标准、哪种数据集——却几乎从未将其视为一个工程问题。但是,一旦你的评估套件开始充当生产发布的守门员,它就继承了生产栈其余部分所遵循的所有要求:可重现性、版本控制、所有权、可观测性、依赖管理、延迟与可靠性预算,以及一套在构建它的工程师离职后依然能运行的流水线。大多数团队完全跳过了这一层,只有在发生重大事故后才发现它的缺失——通常是评估分数显示绿色,而用户体验却是一片红色。

人格叠加(Persona Overlays):当一个智能体需要为不同客户群提供多种声音时

· 阅读需 13 分钟
Tian Pan
Software Engineer

一家世界 500 强公司的采购主管打开了你的支持智能体,询问为什么 SOC 2 报告中提到的某个合规控制项在你的产品中已不再执行。你的智能体用对待免费版个人用户的语气回答了她——带着三个感叹号、一个表情符号,以及一个“联系我们团队”的愉快建议,既没有升级路径,也没有引用出处。采购主管把这张截图转发给了她的首席信息安全官(CISO),只写了一行字:“这就是他们派来处理我们合规问题的东西。”你失去了续约机会,不是因为答案错了,而是因为语气在那个场合不对。

大多数团队之所以只发布一种智能体人格面具,是因为组织架构中只有一个支持团队。然而,客户群体很少是单一的。企业买家期望正式感、引用来源和明确的人员升级路径。自助服务用户想要快速回答和零摩擦。开发者想要代码,而不是长篇大论。单一的人格面具在某些群体看来是居高临下的,而在另一些群体看来则是不专业的。而“让用户选择语气”则是将一个本不该由用户承担的产品决策推卸给了用户。

AI 功能的 PRD:为什么你的旧模板会让你在悬崖边失足

· 阅读需 11 分钟
Tian Pan
Software Engineer

确定性软件的 PRD 模板已经演变成了一种肌肉记忆。问题陈述、用户故事、验收标准、边缘情况、成功指标、范围削减。工程师知道如何阅读它,产品经理(PM)知道如何填写它,设计师知道该从哪些章节提取原型图。这是一个被磨损得恰到好处的产物,它交付了一代又一代的 CRUD 应用、仪表盘和 SaaS 工作流。

它也没有“模型在 5% 的情况下会出错”的字段,没有“我们接受的评估(Eval)合格分”的字段,没有“当模型拒绝回答时用户会看到什么”的字段,也没有“该 PRD 锁定了哪个提示词(Prompt)版本,以及发布后允许谁进行更改”的字段。每一个按照这种模板交付的 AI 功能,都带有一份谁也没写下来的隐性契约。复盘总是让人们在遭遇挫折后才痛苦地意识到这一点。

静默量化:为什么你今天付费的模型不再是上个季度购买的那个

· 阅读需 12 分钟
Tian Pan
Software Engineer

你账单上的模型名称与上季度完全一致。API 响应中的版本字符串也没有改变。模型卡片和定价页面看起来也一模一样。然而,你的评估得分却下降了 0.5 分,拒绝模式以你提示词中未要求的方式发生了偏移,上周二还收到了几起客户投诉,称输出结果“感觉不一样”。你调试了代码,却一无所获。代码没变。权重变了。

静默量化(Silent quantization)是你合同约定的模型与供应商实际交付的模型之间的差距。之所以发生这种情况,是因为推理经济学持续收紧——每一美元的 GPU 算力在本季度必须承载比上季度更多的请求——而消化这种压力的最廉价方式,就是在更廉价的精度层级上重新托管同一个模型。FP16 变成了 FP8。在某些路由中,FP8 变成了 FP4。混合精度分片被替换进来。版本字符串没有变动,因为版本字符串从来都不是精度合约,而是一份营销合约。

当你的模型具有随机性时,快照测试在撒谎

· 阅读需 12 分钟
Tian Pan
Software Engineer

当你团队中的初级工程师第一次输入 --update-snapshots 并推送到 main 分支时,你的测试套件就不再是测试套件了,它变成了一份记录稿。虽然 Diff 依然显示为红绿颜色,CI 徽章依然会变为通过,但信号已经悄然反转:测试套件不再告诉你代码是否正确,而是告诉你是否有人费心看过输出。对于确定性的代码,这种风险尚在可接受范围内,因为大多数 Diff 确实是符合预期的。但当网络调用的另一端是一个随机模型时,同样的流程会让每一个 PR 变成一场硬币投掷,让每一位评审者变成一个橡皮图章。

快照测试曾是确定性世界里的一个美妙构想。你记录下上周二 render(<Button />) 的生成结果,断言本周二它会生成相同的字符串。从定义上讲,任何 Diff 都是值得人工核查的行为变更。这种模式在 Jest、Vitest、Pytest、整个 React 生态系统以及一代又一代的 UI 快照扩展中得以幸存,是因为底层契约依然成立:相同的输入加上相同的代码等于相同的输出。但这个契约对 LLM 调用并不奏效。相同的输入、相同的代码加上相同的提示词(Prompt),却会产生不同的字符串——而且这种差异并非 Bug,而是产品按设计正常运行的结果。

为什么每周会话记录审查优于你的 AI 仪表板

· 阅读需 14 分钟
Tian Pan
Software Engineer

在你的 AI 团队中,被低估最严重的资产是每周一小时,由三个人坐在房间里阅读你的产品实际对用户说了什么。不是综合评分。不是移动平均值。不是仪表盘。而是实际的对话记录。逐字逐句的输出。模型悄然形成的懒散措辞。你的分类体系中未涵盖的意图。用户尝试了三次,用三种不同的方式表达需求,而你的评估准则(eval rubric)却将这三次对话都评为“满意”。

将这一小时制度化的团队,能够建立起仪表盘永远无法呈现的 AI 功能心理模型。跳过这一步的团队,会根据看起来不错的指标发布六个月的产品,然后在下一次季度业务回顾(QBR)中发现,在无人察觉时,中位数体验已经漂移到了令人遗憾的境地。

澄清预算:你的智能体何时应该询问而非猜测

· 阅读需 12 分钟
Tian Pan
Software Engineer

智能体最糟糕的两种失败模式看起来截然相反,但它们其实源于同一种失效的策略(Policy)。第一种智能体在执行任何操作前都会先问四个后续问题,这让它的用户因为繁琐而最终放弃使用。第二种智能体从不提问,它自信地生成用户不得不推倒重做的输出,这让它的用户对其产生不信任感。同样的策略,只是一个缺失参数的不同设置:即提问的成本相对于错误答案成本的比例。

大多数智能体根本没有任何策略。模型只是被要求“提供帮助”,然后被留下来独自应对模糊性。因为下一个 Token 预测(next-token prediction)机制奖励对答案的确定性,所以智能体倾向于猜测。又因为 RLHF 奖励礼貌,智能体偶尔会为了安全而过度纠偏并提出问题。其结果就是一种毫无原则的行为,这种行为在不同会话之间波动不定,团队层面也无法直观地判断智能体何时会暂停、何时会盲目推进。

澄清预算(Clarification budget)正是那个缺失的参数。它是针对每个任务制定的、允许智能体施加摩擦力的配额,并配有一套判断何时值得花费预算去提问的决策规则。你可以把它看作是对话领域的“延迟预算(latency budget)”——每个产品都有一个,即使没人把它写下来;而那些把它写下来的团队,就能停止交付那种让人困惑的智能体。

将 Eval 作为 Pull Request 评论而非任务:在代码审查中嵌入 LLM 质量门禁

· 阅读需 12 分钟
Tian Pan
Software Engineer

许多自称“有评估(evals)”的团队,其实际情况是:有一个仪表板,某人每周运行一次测试套件,然后将数据粘贴到没人看的 Slack 频道。评审人员批准提示词(prompt)更改时,甚至根本没看过它是否影响了测试套件,而回归问题(regression)两周后才在客户反馈单中显现。评估确实存在,但评估并未进入开发循环。

解决办法在于结构,而非意愿。只有当评估存在于变更发生的地方——即 Pull Request(PR)评论中,紧挨着代码差异(diff),并带有单个 PR 的增量变化和评审员无法忽视的回归提醒时,评估才能真正起到质量把关的作用。在其他任何地方,它们都只是表演性的产物:投入了大量精力构建,却什么也拦截不到。

工具调用顺序是偏序,而非集合

· 阅读需 12 分钟
Tian Pan
Software Engineer

“先创建后通知”的序列在开发阶段运行良好。而“先通知后创建”的序列则会为一个尚不存在的实体触发 webhook,导致消费者返回 404,接着你的团队会花上一周时间来调试这个看起来像是不稳定的集成测试。这种不稳定并非随机。它是确定性的,源于你的工具集拥有而你的规划器(planner)却不知晓的隐藏排序不变性。

这就是生产环境中 Agent 工具调用排序 bug 的常见形态:工具集在底层以偏序(partial order)方式组合——某些操作必须先于其他操作执行,而另一些则可以按任意顺序运行——但在规划器看来,它们只是一个无序的能力集合。模型选择了一个昨天行之有效的顺序。而明天,一次提示词修改、模型升级,甚至只是不同的 temperature 采样,都会选出另一个顺序。对于阅读追踪记录(trace)的人来说,这两种顺序看起来都很合理。但其中只有一个是正确的。

如果不声明顺序,团队交付的就是一个最终会被模型的提示词敏感性(prompt sensitivity)触发的 bug 隐患。

Semver 的谎言:为什么 LLM 的次要更新比重大重构更容易搞垮生产环境

· 阅读需 12 分钟
Tian Pan
Software Engineer

在 AI 工程领域流传着一个隐秘的神话:模型的一次“小幅”升级——比如 claude-x.6claude-x.7,或者 gpt-y.0gpt-y.1,甚至是按日期推进的补丁级快照更新——都应该是无缝替换的。厂商发布的更新日志里谈论着推理能力的提升、更低的延迟以及更好的工具调用。版本号轻轻跳动,没有任何迹象表明这些改动会破坏现有系统。

然后更新上线了。值班频道随即被各种警报点亮:摘要生成器莫名其妙多出了一段以前没有的话;JSON 提取器开始对以前不处理的 Unicode 字符进行转义;Agent 循环在以前只需三次调用就能完成的任务上,现在却触碰到了最大步数限制。从整体上看,评估得分似乎没什么问题,但用户可见的功能却在细微之处出了错。