跳到主要内容

67 篇博文 含有标签「llmops」

查看所有标签

闭环升级漏洞:当你的专精型智能体陷入循环路由

· 阅读需 13 分钟
Tian Pan
Software Engineer

一个用于市场数据研究的多智能体系统在无人察觉的情况下,在四周内悄悄烧掉了 47,000 美元的推理成本。原本的每周账单仅为 127 美元。原因既不是流量激增,也不是模型升级——而是两个智能体在十一天里来回传递同一个对话,每个智能体都确信对方才是处理该请求的正确位置。没有任何报错。没有任何警报触发。一个机器人的“队列已转移”指标和另一个机器人的“任务已接收”指标都在同步增长,两边的仪表盘看起来都很健康。

这就是闭环升级漏洞 (closed-loop escalation bug)。它是两个热心的同事互相坚持“不,你来处理”的多智能体版本,只不过他们谁都不会感到厌烦并走开。你在设计时画的架构图中,每个专业智能体都拥有一块清晰的问题领域。而运行时实际执行的架构却包含了一个房间里没人能看到的路由循环。

生产级智能体的 90 秒冷启动:当 LLM 不再是瓶颈时

· 阅读需 12 分钟
Tian Pan
Software Engineer

用户点击按钮。90 秒后,他们才收到第一个 token。团队的反应几乎是条件反射式的,即要求模型厂商提供更快的 TTFT —— 而厂商的 TTFT 其实只有 800 毫秒。模型从来都不是慢的那一部分。请求花了 30 秒等待工具注册表(tool registry)加载,20 秒等待向量数据库客户端协商首次连接,15 秒用于新鲜容器上的 Prompt 缓存预热,还有 10 秒让智能体框架针对一个初次使用的 JSON Schema 校验器验证注册表中的每个工具模式(tool schema)。

这就是智能体冷启动,它几乎与模型无关。仅对 LLM 调用进行性能分析的团队是在优化请求中本就不慢的部分。更糟糕的是,冷启动在稳态下是不可见的 —— 针对热池(warm pool)的负载测试结果看起来很棒,中位数指标图表看起来也很棒,只有那些在部署、自动扩缩容事件或因低流量导致资源回收后触发首个请求的用户才会察觉到问题。

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

· 阅读需 14 分钟
Tian Pan
Software Engineer

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

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

单用户 AI 配额:成本看板无法察觉的 UX 层

· 阅读需 11 分钟
Tian Pan
Software Engineer

一个用户在周二下午 3 点打开了你的 AI 功能。他们已经轻度使用了三周。这次请求卡住了 8 秒钟,然后返回了一个红色的横幅:“出错了。请稍后再试。”他们又试了一次。还是同样的横幅。他们关闭了标签页,回去做之前在做的事情 —— 并在第二天早上的站会上告诉队友,“那个 AI 功能坏了。”

实际发生的情况是:他们触碰到了一个隐形的单用户配额,这是你的成本团队在六个月前为了防止单个重度用户刷爆 GPU 预算而设置的。配额起作用了。支出保持平稳。仪表盘显示绿色。按照你的工程组织追踪的每一个指标来看,这项功能都是健康的。但它也已经名存实亡了,因为看到那个横幅的用户再也不会回来了,而且他们在站会上告知的那三个队友也永远不会去尝试它。

这就是你的成本仪表盘看不见的鸿沟。单用户 AI 配额是一个产品界面(product surface)。那些将其隐藏在 HTTP 429 错误代码中的团队,正任由其成本控制系统默默地塑造用户对产品的认知,而且直到流失率在季度回顾中显现出来且没有明显原因时,他们才会发现这一点。

运行时 Prompt 热重载:为什么你的 Prompt 不该被锁定在构建流程中

· 阅读需 12 分钟
Tian Pan
Software Engineer

大多数公司的第一次 AI 事故都遵循一个剧本:一名提示词工程师发现模型对刚刚开始出现在实际流量中的某个类别进行了错误分类,于是提交了一个 PR,对系统提示词(system prompt)进行了一行微调,然后在模型继续在生产环境中进行错误分类的这 23 分钟里,盯着构建队列。修复手段只是一个字符串。而部署却是一个二进制文件。这种不匹配并不是工具层面的疏忽 —— 而是团队在将系统提示词与应用程序代码一同放入 .py 文件的那天起,就隐含做出的架构决策。

将提示词更改与部署管道耦合是你强加给自己的限制。分布式系统中没有任何定律规定模型的行为契约必须与编排代码封装在同一个制品(artifact)中。运行时提示词热重载模式通过像对待功能开关(feature flags)、路由规则和价格表那样对待提示词,从而切断了这种耦合 —— 即将其视为在请求时从版本化存储中拉取的配置,并辅以短效的本地缓存和定义明确的安全原语(safety primitives)。这样做的好处是事故响应时间从以分钟计的构建时长缩短到以秒计,而代价是你必须正视一个你的发布流程可能忽略的第三个部署平面。

模型回滚速度:从“这次升级有问题”到“旧模型完全恢复”之间的七小时鸿沟

· 阅读需 14 分钟
Tian Pan
Software Engineer

针对糟糕的代码部署,标准流程是在一分钟内完成回滚。针对错误的配置推送,标准流程是亚秒级的开关切换。而针对糟糕的模型升级,应对方案则是值班工程师在早上 09:14 临时想出的法子,而且通常需要耗时 7 小时才能完成。在这 7 小时内,性能倒退持续累积——错误的答案被发送给客户,支持工单堆积如山,而监控面板显示的只是缓慢的倾斜曲线,而非迅速回归绿色的断崖式好转。

差距之所以长达 7 小时,并非因为团队动作缓慢,而是因为模型升级的“回滚”与代码的“回滚”并非同一种原语。它更接近于数据库模式(schema)迁移:局部的、滞后的,且无法通过按下你希望存在的那个按钮来撤销。围绕“一个按钮”编写事故应对方案的团队,并不具备实际回滚所需的控制能力。

这篇文章将探讨这些控制能力具体是什么样的,为什么必须提前为此付出代价,以及当你第一次尝试在负载下回滚模型时,你会对你的平台有哪些新发现。

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

· 阅读需 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)出现在仪表盘上。

工具重入:你的函数调用层尚未察觉的 Bug 类别

· 阅读需 13 分钟
Tian Pan
Software Engineer

智能体用 400 毫秒回答了一个简单的问题,然后因递归限制错误(recursion-limit error)崩溃。Trace 显示了 25 次工具调用。从上到下阅读 Trace,工程师会得出结论:智能体糊涂了 —— 以略有不同的顺序反复调用那几个工具,始终无法收敛。这个结论是错误的。智能体并没有糊涂。它陷入了一个死循环:工具 A 调用了模型,模型选择了工具 B,工具 B 的实现再次调用模型来格式化其输出,而格式化程序又选择了工具 A。Trace UI 将四个嵌套调用渲染为扁平列表中的四个兄弟调用,导致唯一能发现问题的开发者也无法察觉这个循环。

这就是工具重入(tool reentrancy),这是一种你的函数调用层几乎肯定没有建模的 Bug 类别。并发安全的代码对此已有数十年的原语支持:记录同一线程嵌套获取次数的重入互斥锁(reentrant mutexes)、语言层面的递归限制、堆栈检查 API,以及一种文化共识:任何回调运行时的函数都需要一个明确的契约,规定允许何种重入。工具调用层默认采用“发后即忘”(fire-and-forget)模式。运行时没有可供检查的调用栈,调度前没有循环检测器,工具定义上没有重入属性,Trace UI 的形式像日志而非图。结果就是,任何超过十几个条目的工具目录都会悄悄变成框架无法察觉的递归。

AI 功能的 RACI 模型:为什么四个绿色仪表盘组合在一起却是一个破碎的产品

· 阅读需 13 分钟
Tian Pan
Software Engineer

一个 AI 功能在周二出现了回归。评估(eval)CI 是绿色的。护栏(guardrail)仪表盘很干净。检索(retrieval)P95 指标正常。模型供应商没有任何故障。然而,支持队列中挤满了用户,他们反映助手“本周感觉变差了”。产品经理(PM)是房间里唯一能说出哪里回归的人,但即便是她也无法告诉你哪个仪表盘能捕获到这个回归。欢迎来到“接缝 Bug”(seam bug)的世界——这种故障中,每个单独的产出物负责人(artifact owner)都能证明自己的部分没问题,但集成后的体验依然是坏的。

这是 AI 功能人员分配方式的必然结果。纸面上的负责人名单看起来很合理:提示词作者负责系统提示词,评估负责人负责离线测试集和 CI 门禁,工具/检索负责人负责函数调用和搜索索引,护栏负责人负责审核和策略过滤器。此外,还有一个模型选择决策,通常游离在这四者之外——有时归属于平台团队,有时归属于最近提交采购单的那个工程师。五个负责人,却没人对“这个功能对用户是否有用”负责。

评估作者的单一文化:为什么你的基准测试会变成一张自画像

· 阅读需 12 分钟
Tian Pan
Software Engineer

绿色 CI 并不意味着“这个提示词有效”。绿色 CI 的本质是“编写评测的工程师想不出这个提示词会如何出错”。这是两个截然不同的断言,而它们之间的差距正是生产事故的温床。一个评测套件并不是对模型的测量——它是对编写者的冰冷写照。他们的方言、领域知识、资历、偏好的失败模式,以及他们在编写测试用例时恰好使用的模型。根据构造,工程师没想到的测试内容统统未经测试。更糟糕的是:他们会从同一个视角不断扩展套件,因此随着套件的增长,盲点并不会缩小,反而会变得根深蒂固。

这就是评测作者单一化(eval-author monoculture)问题,也是当今 AI 工程中讨论最少、风险最高的可靠性问题。团队痴迷于裁判偏差、位置偏差、冗长偏差、泄漏和污染——但上游偏差其实是最初决定测试用例的人的偏见。其他任何评测误差来源都会被它放大。如果你的套件是由一个人编写的,那么你就拥有了一个带有性格的基准测试,而这种性格正是你的 CI 能够捕获风险的无形天花板。

提示词资产贬值:你团队中缺失的 AI 维护时间表

· 阅读需 10 分钟
Tian Pan
Software Engineer

工程主管们对“代码腐烂”这一概念已经习以为常。依赖项需要更新,基础设施有生命周期管理,证书会在无人质疑的日期过期。然而,提示词仓库(prompt repository)却往往被视为一种“一次编写,多次读取”的产物——尽管它定义了你的产品如何与一个每六周就发布一次行为变更的概率引擎进行对话。

六个月前针对当时主流模型调优的系统提示词,现在依然在生产环境中使用。针对早已变更的分词器(tokenizer)挑选的 Few-shot 示例,仍在每次调用时被注入。重排序提示词是针对供应商上季度已废弃的嵌入端点调优的。没有人安排审查。也没有人打算去安排。

这并非假设性的失效模式。当一个团队将其精心针对 GPT-4-32k 稳定化的提示词套件迁移到 GPT-4.1 和 GPT-4.5-preview 时,其回归测试的通过率分别仅为 95.1% 和 97.3%。在生产环境中,3-5% 的隐性质量退化绝非可以忽略的误差;在任何具有一定规模的场景下,这都是一种用户可见的退化,而团队中没人是有意发布这种退化的。而且,这些还是拥有回归测试套件的团队。中等水平团队的“回归测试”,不过是值班工程师在处理上一次事故时凭感觉形成的印象。

我们缺失的范畴是提示词资产折旧(prompt asset depreciation):这是一种维护纪律,它将每个生产环境中的提示词视为具有已知寿命的折旧资产,而非一成不变的常数。

共享提示词的“夺旗日”:当一次修改引发三十个团队的性能回归

· 阅读需 12 分钟
Tian Pan
Software Engineer

对共享系统提示词的第一次修改感觉就像是优秀的工程实践。三个团队都在各自智能体的顶部粘贴了相同的 18 行安全前导指令,有人注意到了这一点,内部平台团队说了一个显而易见的提议:让我们把它中心化吧。于是 prompts.common.safety_preamble@v1 出现在了注册仓库中。由于这是阻力最小的路径,加上安全团队很高兴能由一个团队统一负责措辞,30 个团队在短短一个季度内就采用了它。在接下来的两个季度里,这看起来就像是一个完美的 DRY (Don't Repeat Yourself) 胜利。

随后,安全团队需要对措辞进行微调。可能是新的合规条例收紧了助手可以主动提供的用户信息范围,也可能是红队发现需要向拒绝条款中增加一句话。平台团队完成了修改,发布了 v2 版本。不到一天,支持队列就充满了消费团队的消息:我们的评估 (eval) 下降了、我们的格式崩了、我们的工具调用率减半了、我们的语气变了、延迟增加了(因为模型开始进行更多推理)。每个团队都希望回退修改。而安全团队需要发布它。没有人能在不进行重新评估的情况下升级,但又没有人负责重新评估。欢迎来到共享提示词的“旗帜日 (flag day)”。