跳到主要内容

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

查看所有标签

浏览器 Agent 会话泄漏:当单个 Profile 服务于多个租户时

· 阅读需 12 分钟
Tian Pan
Software Engineer

一个计算机使用型智能体(computer-use agent)在客户的 CRM 上完成了一项任务,工作线程池将浏览器返回到空闲环中,几百毫秒后下一个请求到达,仪表板导航成功——唯一的问题是,它是作为错误的用户登录成功的。前一个会话的 OAuth cookie 仍留在配置文件(profile)中。追踪记录显示 navigation succeeded(导航成功)、screenshot captured(截图已捕获)、action performed(操作已执行)。运行日志中没有任何内容表明,智能体正在以一个从未授权过它的用户身份进行操作。

这是浏览器智能体从其构建所用的库中悄然继承的一类故障。无头浏览器(headless browser)框架被设计为每个配置文件仅供一个用户使用,因为这是浏览器三十年来的工作方式。当工作池为了摊销全新的 Chromium 实例长达八秒的冷启动时间而重用配置文件时,这种“单用户”假设就破裂了,而且这种破裂对于团队通常信任的每一层遥测数据来说都是不可见的。

评估天花板:当你的黄金测试用例失去区分度时

· 阅读需 11 分钟
Tian Pan
Software Engineer

一年前,你的评估套件(eval suite)表现得非常出色。候选模型的得分分布在 60 到 80 分之间,排名结果能为你提供有效的参考。新的微调模型比基准模型高出 6 分;更廉价的模型则低了 3 分。决策依据这些数字而产生。而今天,在同样的评估套件下,每个候选模型的得分都是 95、96 或 97 分,得分差距已经缩小成了噪音。你的团队仍在运行评估,仍在阅读报告,仍在利用它为迁移亮绿灯——但这份报告已经不再包含任何有效信息。

这不是基准测试污染(benchmark contamination),也不是世界漂移引起的衰减(world-drift decay)。这是一个测量工具的问题:你的测试用例是针对平台已经超越的难度水平而校准的。尺子没有坏;而是你正在测量的东西已经超出了它的量程。那些没有意识到这一点的团队,仍然在使用一个辨别范围与所比较的候选模型不再重叠的工具来进行模型决策。

评估数据集是附带正确答案的客户数据

· 阅读需 13 分钟
Tian Pan
Software Engineer

你的黄金评估集(Golden eval set)是一个你的安全团队甚至不知道其存在的隐私边界。它是通过对生产环境的 Trace 进行采样构建的,这意味着它是一系列精心挑选的真实客户查询集合——通常包含姓名、电子邮件、账号、愤怒的通话记录、输入了一半的信用卡卡号——并配有标准正确回复,最后提交到评估流水线读取的任何存储桶中。

最后一部分正是评估数据具有独特危险性的原因。原始的生产 Trace 之所以敏感,是因为它记录了客户所说的话。而评估案例则以一种全新的方式变得敏感,因为它记录了客户所说的话 加上标注的正确答案。这个标签是一个衍生作品,由某人(通常是标注员或领域专家)有目的地添加。它标志着“这是标准答案”。它赋予了 Trace 原始日志从未有过的生命力——日志保留策略最终会将 Trace 轮转删除,但评估案例现在成为了一个永久的测试 fixture(固定数据),团队致力于保持其测试通过(keeping green)。

备用方案变成了默认方案:为什么你的分层配比需要 SLO

· 阅读需 12 分钟
Tian Pan
Software Engineer

仪表盘显示 0.5% 的请求触发了回退(fallback)。仪表盘这么显示已经持续六个月了。直到有人从头重新运行遥测数据(telemetry),发现次级模型正承载着 38% 的流量,而预设回复(canned-response)层级则处理了另外 9% 的流量。团队在路线图评审中一直讨论的尖端模型“主路径”,实际上已沦为少数派体验。没有人注意到这一点,因为没有任何警报被触发 —— 每次降级都是一个小规模的、理由充分的、局部正确的决定,而累积的偏差从未超过任何人事先设定的阈值。

这就是我想要定义的失效模式:成了默认项的回退机制。这不是故障,也不是单个组件的回归。它是产品表面的缓慢轮转,退而求其次的路径不再是安全网,而成了核心体验。团队的心理模型与生产现实渐行渐远,而这种差距是隐形的,因为现有的度量指标(meters)旨在检测失败,而非检测组合(mix)。

我要提出一个更强有力的观点:如果你的 AI 功能拥有两个以上的服务层级,那么你的层级组合(tier mix)本身就是一个 SLO。如果你没有测量它,你其实并不知道你发布了什么。

流式推理中的海勒姆定律:节奏、停顿和中间 Token 是未成文的契约

· 阅读需 12 分钟
Tian Pan
Software Engineer

一个团队从前沿模型升级到了其更快的后继版本。评估套件(eval suite)全绿。最终答案一致。工具调用的 Schema 完全相同。结构化输出通过了与以往一样的 JSON Schema 验证。他们发布了。不到一天,支持票据就堆积如山:“助手感觉太匆忙了”,“它不再真正思考了”,“感觉不对劲”。产品经理调取了遥测数据,发现任务完成率没有变化。工程团队反复检查了评估和 Schema,没发现任何问题。投诉是真实的,但团队定义的契约——就如团队所定义的那样——依然完好无损。

改变的是流的纹理(texture)。旧模型在调用工具前会停顿 800 毫秒,发出一句“让我查一下……”的前导词,并以每秒约 35 个 Token 的速度输出,在子句边界处有自然的节奏。新模型以每秒 90 个 Token 的速度输出,从不停顿,且完全跳过了前导词。这些都没有出现在任何文档记录的契约中。但所有这些都是不可或缺的“承重”部分。

这就是海勒姆定律(Hyrum's Law),而流式传输(streaming)让它的表面积变得巨大。系统的任何可观察行为都会被某人所依赖——而流式 AI 界面暴露的可观察行为远比团队意识到的要多。

混合 PR 队列:审查者吞吐量已成为瓶颈约束

· 阅读需 10 分钟
Tian Pan
Software Engineer

在过去的二十年里,制约理论(Theory of Constraints)在软件交付中的答案始终如一:瓶颈在于编写代码。我们围绕这一假设构建了一切——结对编程、IDE 自动补全、更快的 CI、更小的微服务,所有这些都是为了让更多的代码通过固定宽度的审阅管道。接着,编程 Agent 出现了,管道的生产端拓宽了 5–10 倍,而审阅管道的宽度却纹丝不动。一位过去每周提交 3 个 PR 的资深工程师,现在正监督着一群在一个下午就能提交 30 个 PR 的智能体。团队的交付速度不再取决于编写代码的速度,而是取决于人类阅读代码的速度。

这并非未来的问题。据测量,在某些样本中,PR 审阅时间的中位数同比增长了 441%,并且在未经任何审阅的情况下就被合并的 PR 增加了 31%——这并非出于政策规定,而是因为审阅者已经放弃了跟上进度。Stripe 每周交付超过一千个由 Agent 生成的 PR。在一项基准测试中,特性分支(feature-branch)的吞吐量同比增长了 59%,而主分支(main-branch)的吞吐量却下降了 7%——代码正在被编写,但没有被发布,因为它们卡在了审阅环节。

Prompt 卧推:对“快乐路径”之外的提示词进行压力测试

· 阅读需 11 分钟
Tian Pan
Software Engineer

一个在你的评估集(eval set)上得分 92%,但在真实生产流量中得分 60% 的提示词(prompt),并不是一个有 bug 的提示词。它是一个评估集在结构上无法发现 bug 的提示词。这种差距并非噪声,而是针对那些与提示词设计意图共享语域(register)、长度分布、语言和礼貌程度的示例进行优化的结果——而这些示例正是由编写评估案例的同一个意图所创作的。

真实用户不会配合你的设计意图。他们会发送三个词的片段、十二个段落的文章、作为问题粘贴的代码块、省略冠词的非正式语域、添加敬语的正式语域,以及你的 few-shot 示例从未涉及的语言查询。这些都不是攻击性的,这只是输入分布(input distribution)。如果你的评估集是由编写提示词的同一个人策划的,那么它几乎肯定与这种分布毫无相似之处。

缩小这一差距的学科不是“更多评估”,而是一种不同类型的评估——一个压力矩阵(stress matrix),它刻意改变你策划的集合中保持不变的维度,并对退化曲线(degradation curves)进行评分,而不是单一的准确率数字。称之为提示词卧推(prompt bench press):你不是在测试提示词能否完成工作,而是在测试随着输入变得更难,它是如何失败的。

区域模型发布的“彩票”效应:当你的产品在不同大洲表现各异时

· 阅读需 12 分钟
Tian Pan
Software Engineer

周五下午,一封客户成功(customer-success)邮件发了过来:“德国用户的模型效果变差了。”团队打开评估仪表板,评分没变,p95 延迟也很正常。配置中的模型名称还是三周前发布的那一个。一切都没变。但其实有些东西变了。上个迭代中,美国的端点悄悄上线了新一代模型,而欧洲的端点由于供应商还没完成地区性的分阶段发布,仍在使用旧版本。而位于两者之前的负载均衡器,则在团队的所有仪表板上掩盖了这一差异。

这就是所谓的区域性模型发布博弈。你的“单一模型”抽象并不是单一的。当供应商跨大洲分阶段发布时,它就开始分化了——而在大多数年份、对大多数供应商而言,这种情况在大多数时间里都在发生。当这种情况发生时,客户端 SDK 中的版本字符串并不会改变。你的追踪(traces)看起来一模一样。你与供应商签订的合同也没有做出其他承诺。而你赖以捕捉行为回归的评估套件,几乎肯定运行在某个地区的 CI 机器上,并访问地理位置最近的端点。

采样漂移:当 Temperature 和 Top-P 变成团队内部的“口头传说”

· 阅读需 10 分钟
Tian Pan
Software Engineer

打开任何上线超过一年的 AI 功能的生产环境配置,你会发现一个考古挖掘现场。temperature: 0.7 是因为有人想让演示看起来不那么机械。top_p: 0.85 是因为一个客户抱怨输出太普通。frequency_penalty: 0.4 是因为 2024 年有那么糟糕的一周,一个现在已经退役的模型一直在重复自己。这些决定都没有记录。它们都没有针对当前的基座模型进行重新测试。它们在每一次请求、每一次评估、每一次 A/B 测试中运行,塑造着自原始工单关闭以来再也没有人会有意识选择的行为。

这就是采样漂移(Sampling Drift)。它是由于权宜之计而进行的采样器微调的缓慢积累,这些微调最初的理由已经消失,而其效果却在不断叠加。你配置中的数值并不是经过“调优”的——它们是过去事故的化石记录,被缩放到了你当前的流量规模。

它之所以不可见,是结构性原因造成的。你运行的每一次评估都是针对当前的采样配置进行评分的,所以头条数据看起来总是没问题。当 Temperature 值比基座模型落后两个版本时,不会触发报警。也没有日历邀请会提醒你“在本季度重新网格化采样参数”。这种衰减是无声的,直到有人运行了一个干净的实验,发现一个质量提升、Token 减少,或者两者兼而有之的机会,就摆在眼前,且不需要任何工程成本。

需求文档、代码、测试皆出自一人:你正在悄然失去的独立性

· 阅读需 12 分钟
Tian Pan
Software Engineer

当同一个模型负责编写需求、实现代码并编写用于验证正确性的断言时,“所有测试通过”不再是功能正常工作的证据,而仅仅证明了模型是内部一致的。这是两回事,而这种区别正是编写测试的初衷。

我们通常对测试套件的理解是,它们提供了“第二意见”。作者带着一种对需求的心理模型编写代码,而测试编写者则带着略有不同的心理模型编写断言。这两个模型不一致的地方,往往就是 Bug 潜伏之处。这种说法的前提是测试编写者与代码作者拥有不同的认知视角。如果去掉了视角的差异,测试套件就不再携带关于正确性的任何独立信息——它只携带关于一致性的信息。

规范翻译税:当规范、提示词和评估发生漂移时

· 阅读需 12 分钟
Tian Pan
Software Engineer

一名 PM 用英文写了一份功能规范 (feature spec)。一名工程师将其翻译成带有惯用 LLM 模式的系统提示词 (system prompt) —— 思维链 (CoT) 脚手架、输出格式强制,以及一些涵盖规范中从未提到的失败模式的避险条款。一位评估 (eval) 作者打开同一份规范,冷读一遍,并根据自己的理解编写 JSON 测试用例。三周后,这三个产物各不相同,没人能说清楚一个回归到底是提示词的 bug、规范与实现的差异,还是从第一天就写错的评估。

这就是规范翻译税 (specification translation tax)。传统软件也有这种问题 —— PRD 与代码之间、代码与测试之间的差距 —— 但编译器和类型系统缩小了这种差距。AI 功能没有这种兜底保障。提示词是系统实际阅读的文档。评估是没人签署的合同。规范是没人执行的意图描述。每一项都是将同一意图翻译成不同的媒介,如果没有双向的一致性,行为就会通过那个最容易编辑的产物泄露进来。

语音智能体轮次切换:重塑架构的 250 毫秒门槛

· 阅读需 13 分钟
Tian Pan
Software Engineer

研究跨语言话次转换(turn-taking)的语言学家们得出的结论惊人地一致:日常对话中说话者之间的间隙大约为 200 到 300 毫秒。任何更长的停顿都会被解读为犹豫、疏远或顺从;任何更短的停顿则会被视为打断。这个窗口是如此狭窄,以至于人类显然在对方说完之前就开始构思回复了 —— 倾听和计划是并行发生的,而非顺序进行。

错过这个窗口的语音智能体并不仅仅是让人觉得有点慢,而是让人觉得“不对劲”。在聊天产品中没人会注意到的 700 毫秒延迟,在语音交互中会让智能体显得迟钝、心不在焉,或者导致用户因失去耐心而打断它。1.5 秒的间隙足以让用户开始重复他们说过的话。满足这一时间预算并非简单的打磨工作 —— 它迫使开发者做出文本智能体从未面临过的架构选择,而这些选择重塑了整个技术栈的构建方式。