跳到主要内容

299 篇博文 含有标签「observability」

查看所有标签

供应商 99.9% 的 SLA 对你的 Agent 来说衡量边界错了

· 阅读需 14 分钟
Tian Pan
Software Engineer

一个模型提供商发布了 99.9% 的可用性 SLA。采购团队将其理解为“三个九,每年四个小时的停机时间,对于非 0 级(非核心)工作负载是可以接受的”。六个月后,智能体(Agent)功能上线,值班仪表板显示用户感知的任务成功率约为 98% —— 这个数字没有写进任何合同,在提供商的状态页面上也找不到,而且没有人为此负责。提供商满足了他们的 SLA,而产品却没达到其 SLO。两者同时成立,而这种差距并不是一个 bug —— 这是一个算术问题。

大多数团队都忽略了算术这部分。提供商的 99.9% 是针对同步请求工作负载进行衡量的 —— 一个用户,一个提示词,一个响应,一个计费事件。而智能体并不会产生这种工作负载。一个用户感知的任务会扇出(fan out)为 8 到 20 次推理调用,它会对瞬时错误进行重试,对慢速调用进行对冲(hedge),并聚合部分输出。每一次调用都是对提供商故障分布的一次独立抽样,如果任何关键调用失败,任务就会失败。SLA 覆盖的边界和用户感受到的边界并不是同一个边界。

你的 API 曾假设一次只有一个人类用户。并行智能体打破了这一契约。

· 阅读需 14 分钟
Tian Pan
Software Engineer

我认识的一位后端工程师在一个周二的下午盯着一个从未有过波动的 Datadog 图表:其内部日历服务的单用户 429 计数器。投诉的客户并没有改变他们的行为。他们只是开启了助手功能,现在每当用户说“帮我找下周的时间”时,该功能就会针对同一个日历 API 并行启动八个规划线程。速率限制器(Rate Limiter)——每用户每分钟 60 次请求,这个设置非常合理,是多年前针对一个在物理上无法点击得那么快的 UI 编写的——在每次请求的前三秒内就会触发,并悄无声息地破坏了助手一半的响应。

速率限制不是 Bug。契约才是 Bug。那个后端,就像大多数在 2024 年之前编写的内部服务一样,在每一层都植入了一个悄然执行的假设:一个用户意味着一条活动流,其节奏受限于人类的反应时间,拥有一个 cookie 罐、一个 CSRF 令牌和一套在出现问题时可以重新提示的凭据。Agent 一次性粉碎了所有这五个假设,故障表现为一系列看似无关的事件——429 风暴、“最后写入者胜”(last-write-wins)导致的数据损坏、无法取证的审计日志、挂起无头工作线程的重新认证循环——在模式被命名之前,没有人会将它们联系起来。

我一直与平台团队沟通的一个简短总结是:你拥有的每一个后端都与它的调用者有一个未记录的契约,而那个契约是与人类协商达成的。现在 Agent 出现了,要求重新协商。你可以选择在代码审查中主动进行协商,也可以选择在下一次事故期间被动进行。

你的模型更新是一次破坏性变更:你欠集成商的“行为变更日志”

· 阅读需 14 分钟
Tian Pan
Software Engineer

某家厂商在周二下午向模型别名推送了一个“小幅更新”。到了周四,四家客户公司正在进行事件响应。他们本周都没有部署代码。他们的仪表板上没有任何关于延迟、错误率或任何其他基础设施维度的指标退化。改变的是,在他们固定的别名背后的模型开始返回略有不同的句子、略有不同的 JSON 以及略有不同的拒绝——而他们的团队针对旧行为编写的每一个提示词(Prompt)现在都成了一份没人履行的合约。

这种不对称性就是问题的核心。供应商将这次发布视为一次部署:经过内部测试,通过了一些聚合评估,并在维护窗口内逐步推向 100%。而消费端将其视为一次语义化版本(semver)违规:一个依赖项在生产环境中自动升级,却没有更改其版本字符串,随后最终用户的错误报告接踵而至,主题还带着轻快的“我们这边什么都没改”。

推理 Span 中缺失的 kWh 列:单次请求的碳归因

· 阅读需 11 分钟
Tian Pan
Software Engineer

你的推理火焰图(inference flame graph)有一个成本轴,但没有能源轴。这种差距在某天早上之前都没问题,直到客户的采购团队给你发来一份包含 23 列供应商可持续性披露信息的电子表格,其中一列是 每 1,000 次推理的 kgCO2e。你没办法填那一格,你的供应商给出的答案是一篇方法论论文,而交易将在 9 天内关闭。你的平台团队磨练了两年的 token 成本仪表盘突然看起来像是解决了一个错误的问题。

这里的转变并非抽象的。可持续性披露正在从公司层面的汇总转向产品层面的颗粒度。第一波浪潮于 2025 年进入了 CSRD 和 ESRS,而第二波浪潮现在正冲击着 B2B 采购合同。构建了成本可观测性的工程组织即将发现,他们需要针对碳排放的可观测性,而这两者在同一个 span 上并非同一列。

可申诉性差距:如何工程化设计用户真正可申诉的 AI 决策

· 阅读需 12 分钟
Tian Pan
Software Engineer

一个用户打开聊天窗口,请求退款,得到“抱歉,此次购买不符合退款条件”的回复后,关闭了标签页,再也没有回来。在内部,智能体生成了一条完美的追踪记录:工具调用、中间推理过程、参考的政策包,以及运行的模型版本。每一个 span(追踪跨度)都进入了可观测性平台。但没有任何内容是用户可以触及的。这里没有标为“请求人工再次审核”的按钮,即使有,后面也没有相应的服务。这个决定在默认情况下就是终局,而非设计使然。

这就是“可争议性差距”(contestability gap),它是监管机构、律师和愤怒的用户接下来要撕开的口子。这也是一个最典型的例子:一个从外部看像是政策问题,而从内部看实际上是工程链路(plumbing)的问题。

双写竞态:当你的智能体与用户同时编辑同一个日历事件时

· 阅读需 14 分钟
Tian Pan
Software Engineer

智能体自信地报告:“我已将会议改至周四下午 3 点。”用户却盯着原本周二上午 10 点的时段发呆,因为在智能体制订计划到提交更改的这段时间内,用户自己编辑了该事件。“最后写入者胜”(Last-write-wins)策略让自动化的操作覆盖了人类的修改,而用户对助手的信任也因这一次事故而崩塌。这就是双写竞争(dual-writer race),也是智能体工具链从未专门设计应对的 bug 类别。

大多数智能体平台都无意中继承了这一问题。工具层将 update_event 视为一个简单的函数调用:获取 ID,获取新字段,返回成功。底层的提供商 API 十多年来一直提供乐观并发原语(optimistic concurrency primitives)——ETags、版本令牌(version tokens)、If-Match 前提条件——但几乎没有人将它们贯通。模型无法知道它一分钟前所推理的世界已不再是现状,因为由于它所获得的抽象层静默地丢弃了这些信息。

主权崩塌:记录你的 Prompt 究竟去了哪里

· 阅读需 11 分钟
Tian Pan
Software Engineer

监管机构问了一个简单的问题:“对于上周二 UTC 时间 14:32 提交的这个特定用户 Prompt,请证明该请求及其派生状态经过了哪些管辖区。”

你的应用日志显示 model=claude-sonnet-4-5, region=eu-west-1, latency=2.1s。你的网关日志也显示同样的内容。供应商的发票确认了请求确实发生了。但这些都无法回答上述问题。该请求进入了一个由欧盟托管的网关,被转发到美国区域的主端点,但在一次区域性故障期间故障转移到了新加坡,并预热了一个第三方 GPU 池上的 KV 缓存,而该 GPU 池的数据驻留声明仅存在于供应商的脚注中。你所需要的审计追踪存在于一个你的团队并不掌握的层级中。

这就是主权崩溃:即你的合同中关于数据位置的承诺与你的运行时在事后能实际证明的情况之间的差距。合规主张的强度取决于链路中最薄弱的那行日志。

你的 Span 名称是未记录的 API:Agent 团队之间的遥测契约

· 阅读需 11 分钟
Tian Pan
Software Engineer

凌晨 3 点让财务部门收到告警的成本飙升其实并不是真正的成本飙升。那只是一个 Span 重命名。Agent 平台团队的某个人觉得 llm.completion.synthesis 应该改为 llm.generate.answer,因为这样读起来更自然。他们提交了一个小的 PR,运行了测试,然后发布了。三天后,财务的月度 Token 消耗仪表盘显示下降了 60%。没有人削减支出。聚合规则仍然按旧名称分组,而新的 Span 流向了一个仪表盘甚至没有渲染的 “其他” 桶中。账单没有变。仪表盘变了。

这是我一直看到团队在重复经历的一类事故。Span 名称和属性键并不是为了让人在追踪 UI 中阅读而存在的标签。它们是一个未公开 API 的公开 Schema,其消费者是生产团队从未谋面的——过滤它们的评估流水线、按它们分组的成本仪表盘、根据其持续时间触发的 SLO 告警、汇总其 Token 属性的 FinOps 报告。一个团队内部 “无害的重命名”,对于另外四个从未看过该 PR 的团队来说,就是一个网络协议破坏。

用户侧概念漂移:当你的提示词依然奏效,但用户已经变了

· 阅读需 11 分钟
Tian Pan
Software Engineer

大多数团队都在契约的错误一端设置了漂移监控(drift monitoring)。他们盯着模型——当供应商发布新的 checkpoint 时发生的性能偏移、提示词重写后的输出分布变化,或是预示着安全过滤器重新调整的拒绝率激增。仪表板非常详尽,告警已接入 PagerDuty,团队也准备好了针对“模型变了”的运维手册。然而,当模型没变而仪表板依然报红时,这些都无济于事,因为真正发生偏移的是你的用户。

用户侧概念漂移是几乎所有评估流水线(eval pipeline)都会忽略的一种问题。你的提示词、模型和工具与发布当天完全一致。你的黄金测试集(golden test set)依然保持 91% 的通过率。但在第一周达到 91% 的提示词,在第三十周的实际效果可能只有 78%,因为底层的输入分布已经发生了变化——用户了解了产品并改变了提问方式、词汇发生了演变、出现了季节性的任务类型、竞争对手重新定义了品类,或者某个热门帖子教给用户一种表达相同意图的新方式。模型和提示词稳住了,契约也稳住了,但契约所针对的那个世界变了。

Agent 的链路追踪采样:每日千万级 Span 中哪些值得保留

· 阅读需 12 分钟
Tian Pan
Software Engineer

一个 Web 服务请求在繁忙时段产生 5 个 Span。而一个现代的 Agent 会话产生 50 个,如果 Planner 决定递归,有时甚至会产生 1000 个。你们平台团队从微服务时代复制粘贴过来的 1% 均匀采样器,从定义上就会丢弃你真正关心的稀有故障——因为故障是稀有的,而均匀采样对稀有性没有任何判断力。

“我们对 Agent 拥有完全的可观测性”的真实版本听起来与营销版本不同。它听起来应该是:我们保留重要的 Trace,丢弃不重要的,并且我们预先知道哪些是哪些。这句话中的每一个词都至关重要,而那些在账单寄来之前一直忽视采样设计的平台团队,现在正被迫反向学习这一学科——在成本压力下,以及在经历了一个季度的故障之后,这些故障本应“在数据中”,但在有人查看之前就被剔除了。

你在无意中为 Prompt 构建了一个功能开关系统 —— 但却缺少治理

· 阅读需 12 分钟
Tian Pan
Software Engineer

打开你团队用来发布提示词(prompt)变更的配置仓库。看看最近的 30 个 commit。其中有多少个经过了代码审查(code review)?有多少个在 CI 中设置了评估门禁(eval gate)?有多少个你能——肯定地——归因为对看到它们的用户的生产环境行为产生了可衡量的变化?如果你的答案是“绝大多数”,那你是个例外。对于其他人来说,这些 commit 此刻正在生产环境中运行,而读取它们的系统所做的事情与特性标志(feature-flag)服务完全一致:热加载一个值,分发给用户,改变产品行为。区别在于,你的特性标志服务拥有审计日志、曝光追踪、熔断开关(kill switches)以及针对特定分群的定向投放。而你的提示词发布流水线只有 git push

这并非隐喻。这是对你团队正在运行的生产系统的准确描述。提示词配置仓库、你的 worker 轮询的 S3 存储桶、数据库中的 “prompts” 集合、你的应用在启动时获取的 LangSmith/PromptLayer/Braintrust 资产——这些全都是特性标志服务。它们具有相同的运行时形态:一个存在于二进制文件之外的值,二进制文件在热路径(hot path)上读取它,更改该值即可在无需部署的情况下改变真实用户的行为。唯一缺少的,是你的 SRE 团队在批准“真正的”特性标志服务之前所要求的所有控制措施。

确认与行动间的鸿沟:智能体的“明白了”并不等同于承诺

· 阅读需 12 分钟
Tian Pan
Software Engineer

Agent 对客户说:“收到——我已经提交了你的退款请求。你应该会在 5–7 个工作日内看到它。”客户关闭了聊天。但退款从未被提交。没有工单,没有 API 调用,退款表中也没有记录。有的只是一段礼貌且自信的英语,以及随后成功的会话终止。

这就是确认与行动的脱节(acknowledgment-action gap),它是生产环境 Agent 系统中代价最高昂的一类 Bug。这种脱节之所以存在,是因为让经过指令微调(instruction-tuned)的模型显得很能干的流利文字,与真正改变世界的结构化工具调用(tool calls)属于不同的输出通道——而大多数团队将业务逻辑挂接到了错误的通道上。

每个发布 Agent 的人最终都会以惨痛的方式意识到这一点。模型生成了一份读起来像承诺的精美确认函,下游系统将其解读为承诺,几周后一份支持工单寄来,询问退款去了哪里。令人尴尬的不是模型撒了谎,而是系统被设计成去信任它所说的话。