跳到主要内容

23 篇博文 含有标签「slo」

查看所有标签

供应商移除的 Logprobs 字段如何静默地破坏了你的置信度路由

· 阅读需 13 分钟
Tian Pan
Software Engineer

在事故复盘报告中,最昂贵的代码行反而是没人写出的那一行:一个字段缺失的 200 OK。原本应该将难题上报(Escalate)给更强模型的路由,在整整六周的时间里上报的流量为零。成本看板在欢庆,质量看板却在下滑——但仅限于那组被现有评估集低估的难题切片。直到客户投诉系统以前能正确处理的特定问题时,一切看起来都还像是场胜利。

起因是协议栈上层的一个响应结构变化。供应商的中级方案取消了逐 Token 的 logprobs,这在发行说明中被称作“特定层级的特性对等调整”。客户端收到的仍是有效的 JSON,HTTP 状态码依然是 200,响应中的模型标识符与请求中的模型标识符也完全匹配。唯一的变化是,路由用来做上报决策的字段消失了,而一年前在一次事故中添加的防御性默认设置,悄然变成了每个请求的生产环境默认行为。

你的延迟 SLO 取决于其他团队的 Prompt 大小

· 阅读需 11 分钟
Tian Pan
Software Engineer

你的聊天产品已经在 1.5 秒的 p99 延迟 SLO 下平静地运行了数月。请求率平稳,prompt 大小平稳,模型也未曾改变。接着,在某个周二下午,p99 突然飙升至 4.8 秒并保持在那里。值班排查发现聊天路径(chat path)没有任何异常:同样的每分钟请求数,同样的中位 prompt 长度(约 800 token),SDK 的重试行为也完全一致。聊天服务当天的部署日志为空。故障持续了六个小时。

原因出在另一个团队的代码库中。那天早上,一个长文本摘要功能上线了,使用的是同一个组织密钥(organization key),其平均 prompt 为 12,000 token。他们的请求率并不高 —— 每分钟仅几百次 —— 但每次调用消耗共享的每分钟 token(TPM)预算的速度比你的快 15 倍。供应商的限流在聊天路径上触发了,因为聊天路径与摘要团队共用同一个刚刚被掏空的“桶”。没人动过你的代码,没人超出计划的容量,而你的 SLO 现在却成了你的团队从未读过的工作负载的函数。

你的 AI 功能无法使用 CDN 边缘缓存,因为响应因用户而异

· 阅读需 10 分钟
Tian Pan
Software Engineer

产品团队将新 AI 摘要器的 SLO 设置为 200ms TTFB,因为这是产品其他部分在 p50 下的表现。会议上没人问这 200ms 是怎么来的。它源于十年来通过 CDN 边缘缓存提供的静态资源和 JSON 响应,其缓存命中率为 85%,大多数请求从未到达源站,即便到达了,数据量也很小。而这个摘要器是针对每个用户的,每次调用都是重新生成的,且每次请求都要经过“边缘 → 源站 → 模型提供商”的路径。从第一天起,这个 SLO 在结构上就是无法实现的。团队在第六周才发现这一点,而此时仪表盘已经红了整整六周。

这是 AI 功能发布中反复出现的一种模式。组织在某种物理规律基础上建立的延迟标准,被一个遵循完全不同物理规律的功能所继承。于是,继承目标与可实现底线之间的差距,变成了一个长达数月的缓解项目,而不是第 0 天的设计约束。数字并不关心你是否出于诚意与客户协商了该 SLO。

披着“延迟预算路由器”外衣的“质量损失路由器”

· 阅读需 11 分钟
Tian Pan
Software Engineer

一个优化单一损失函数的模型路由器会准确地交付该损失函数所要求的结果,除此之外别无他求。当该函数的目标是“保持在 p95 延迟目标之下”时,每一个本可以从深度推理(extended reasoning)中获益的查询都会被强行分配到路由器能辩护的最廉价路径上,因为快速模型能在 SLO 范围内返回,而缓慢但正确的模型则不能。延迟仪表板变绿了。综合评估指标(aggregate eval)仅波动了不到一个百分点,团队便将其视为噪声忽略不计。而没人绘图的分片视图(per-slice view)才是真正发生质量回归(regression)的地方:它集中在那些多步骤、模糊且分布外(out-of-distribution)的查询中,这些查询本应被路由到推理模型,结果却分配给了那些运行迅速但错误得很有底气的模型。

这不是路由 bug。路由器正在准确地执行其设计任务。Bug 出在框架设定上——如果一个系统的优化器完全以延迟为基准,它就会产生质量回归,而这些回归在团队为了 KPI 而维持“绿色”的指标中是不可见的。随后,它会默默地发布这些回归,因为盯仪表板的人并不是盯答案的人。

你的编排器在规划步骤上消耗的延迟预算

· 阅读需 12 分钟
Tian Pan
Software Engineer

我上季度合作的一个团队对一个客户支持智能体(Agent)进行了为期一周的埋点分析。从纸面上看,该智能体的中值延迟非常合理:P50 在 SLO 范围内,P95 虽然偏高但尚可解释,工具调用的追踪(traces)看起来也很健康。然而,当有人按类型对 span 进行分桶统计时,全场陷入了沉默。该智能体每次运行的墙钟时间(wall-clock time)中,约有 58% 耗在了标记为“规划(plan)”、“反思(reflect)”、“决定下一步(decide-next-step)”和“自我检查(self-check)”的 span 中。而真正的工具执行——数据库查询、CRM 写入、权限检查——占比不足 30%。这个智能体在核心业务逻辑上花费的精力,竟然比那些没人关注的中间步骤还要少。

这个比例并非偶然。它是任何你不主动监管的“规划-行动-观察(plan-act-observe)”循环的自然状态。编排器(Orchestrator)为了思考和行动支付延迟代价,而增加思考步骤几乎总是比增加行动步骤更容易,因此它会野蛮生长。当你意识到这一点时,“决定下一步做什么”已经变成了一个独立的预算大头——甚至比你最初构建智能体要服务的业务逻辑还要大。

你的供应商通过更小的分块达成的 Tokens-Per-Second SLO

· 阅读需 12 分钟
Tian Pan
Software Engineer

你的供应商状态页面显示为绿色。每秒 token 数 (TPS) 仪表盘显示的曲线一如既往地平稳。SLA 报告显示你完全处于合同约定的速率范围内。然而,支持队列里挤满了用户,他们形容聊天输出“一跳一跳的”、“断断续续”、“比上周还差”。你的监控指标中没有任何一项能证实他们的说法,因为你的监控根本没有在测量他们真正在关注的东西。

这是没有人察觉到的供应商交付故障模式。他们没有突破速率限制,而是重新定义了单位。每秒到达的 token 数量没变,但它们是以单 token 块的形式流式传输的,而不是针对渲染器优化过的 4 token 块。平均吞吐量依然完好,但感知质量却被毁掉了。SLO 依然达标,因为 SLO 是针对网络传输(wire)制定的,而网络传输是供应商控制的那部分系统。

语音代理 SLO 定义为首个音频时间,而你的服务商则以首个 Token 时间衡量

· 阅读需 11 分钟
Tian Pan
Software Engineer

产品规格说明书规定用户在说完话后的 600 毫秒内听到回复。LLM 供应商的仪表盘显示首个 Token 时间(TTFT)为 280 毫秒。你查看的每一张图表都在 SLO 范围内。但用户仍然抱怨智能体有延迟,当你亲自拨打电话时,确实能感觉到明显的停顿——每次都在 600 毫秒以上。仪表盘没有撒谎。它测量的是一个不包含 TTS 流水线、音频传输或接收端抖动缓冲(jitter buffer)的数值。流式传输的最后一个 Token 与第一帧音频之间存在的 350 毫秒差距是真实存在的,只是它没有出现在 LLM 团队的图表上。

Bug 不在模型中。Bug 出在 SLO 上。它被定义在了错误的堆栈层级。供应商的出站(egress)并不是用户的耳朵,任何忽视这一点的延迟契约都会在生产环境中显得数据健康,而产品体验却是一团糟。

你定义‘首个 Token’的位置决定了你的延迟 SLO 是否真实

· 阅读需 11 分钟
Tian Pan
Software Engineer

我上季度合作的一个团队在周二发布了推理层升级,周三就开始收到支持工单。用户反映助手感觉“坏了”、“冻结了”或“卡住了”。值班工程师查看了延迟仪表盘,没发现任何异常。p99 首字延迟(first-token latency)为 612 毫秒——远低于团队花了一个季度建立的 800 毫秒 SLO。仪表盘是一片绿色。电话却响个不停。

问题的根源在于 14 个月前做出的一个埋点决策,当时生产环境中还没有推理模型。标记为 “first token” 的指标测量的是供应商发出的第一个数据块(chunk)的时间戳。升级后,第一个 chunk 变成了推理 token——这对用户不可见,也从未渲染,但在 SLO 中却被计为“首个”。模型在流式传输第一个用户可见字符之前,会先发出 4 到 7 秒的内部思考过程。每个图表依然是绿色的。每个用户却在黑暗中等待。

这不是一个关于指标好坏的故事。指标对于它最初设计的模型来说是正确的。这是一个关于当你的埋点边界不再是用户的感知边界时会发生什么的故事——以及在不知不觉中发布这种偏差是多么容易且危险。

第四方风险:当供应商的供应商掌控了你客户的故障

· 阅读需 13 分钟
Tian Pan
Software Engineer

你与模型提供商签订了合同。你的运行手册(runbook)处理了该提供商降级的情况。当他们的仪表板变黄时,你的状态页订阅会向你发送告警。你觉得万无一失。然后,在某个周三下午,你提供商运行的基础云区域开始出现局部降级,你提供商的故障转移区域也受到了影响,因为他们为了控制单位经济效益而整合了容量。由于签署合同时上游两层的供应商决策,你的产品在 90 分钟内处于半瘫痪状态。

第二天早上,客户的事后分析(postmortem)请求出现在你的收件箱里。他们想要找到根本原因。根本原因存在于你的状态页无法看到的层级,也是你的合同无法约束的层级。这一层级正是所谓的第四方风险——它不是一个采购复选框,而是一个无形的依赖层,它会向上层传导故障,只会衰减而不会被吸收。

变成关键路径的审批队列

· 阅读需 12 分钟
Tian Pan
Software Engineer

设计文档写着“人机回环”。发布演示稿写着“默认安全”。六个月后的事故回顾则写道,由于审批人在吃午饭,智能体(Agent)花了 90 分钟才给客户发送发票。这些文档都没有撒谎。它们只是在描述同一个组件在负载曲线不同位置的表现——而其中只有一份准确抓住了全貌。

当你在智能体与不可逆操作之间加入人工干预时,你并没有增加一个安全原语(safety primitive)。你实际上是增加了一个服务,它带有队列、吞吐量限制、质量负载曲线以及可用性概况。如果一个团队在发布智能体时没有命名那个服务,那么他们交付的产品的关键路径将取决于一段他们拒绝去运维的基础设施。

向量索引存在一个没人定义的陈旧度 SLO

· 阅读需 11 分钟
Tian Pan
Software Engineer

一个用户询问你的智能体(agent)企业版的当前价格档位。智能体检索了一个分块(chunk),读取并回答:“每月 2,000 美元。” 信心满满,来源明确,格式优美。问题在于价格在四天前已经变了。智能体引用的数字在上周是真实的。它检索到的分块是在变更之前嵌入的,而索引还没有赶上进度。

没人决定让这种情况发生。没有设计评审说“智能体可以根据长达四天前的数据进行回答”。只是有一个每晚或每周运行的重新索引任务,以及一个随心所欲编辑内容的团队,而这两个时钟之间存在一个没人衡量的缺口。那个缺口就是一个服务等级目标(SLO)。无论你是否写下来,它都存在。唯一的问题是你是有意设定它的,还是由于意外继承下来的。

具有两种延迟的 AI 功能:你衡量的是一种,用户感知的是另一种

· 阅读需 10 分钟
Tian Pan
Software Engineer

传统的 HTTP 请求只有一个关键的延迟:从请求到响应的时间。那个数字的 p95 就是契约。SRE 监视它,SLO 是针对它编写的,当它退化时就会有人收到告警。一个数字,一个仪表盘,一个真相。

流式 AI 功能在响应变为流的一刻就打破了这一模型,而大多数团队还未察觉。现在有了两种延迟,而且它们是发散的。首字延迟(Time-to-first-token) 是用户在任何事情发生前盯着加载图标的时间。完成时间(Time-to-completion) 是直到回答完全写完的时间。它们受不同力量的影响,由不同的杠杆修复,并且用户感受到的情感权重完全不同 —— 而几乎每个团队都只衡量第二个指标,因为那是 HTTP 框架免费提供给他们的数字。