跳到主要内容

47 篇博文 含有标签「sre」

查看所有标签

那些被静音的 LLM 报警:当每一次值班看起来都和上一个一模一样

· 阅读需 11 分钟
Tian Pan
Software Engineer

一次真实的回归在生产环境中持续了两天。告警(Page)已经触发了。它触发得完全正确,阈值准确,严重程度也恰当。三周前,值班轮值(On-call rotation)为该告警族添加了一条静默规则,因为该系列中的每一条告警到目前为止都以同样的注释结案:“无须操作,调查中”。复盘(Post-mortem)无法诚实地将这种静默行为称为错误。这是对一系列值班人员没有 Playbook(运行手册)可循的告警流所做出的理性适应。那个重要的回归就在一个被静默的频道中发布了,因为团队的监控栈产生的信号无法指导具体行动,而团队唯一的应对方式就是:停止倾听。

这并不是一个告警 Bug。这是当团队沿用旧有的 Playbook 对 AI 功能进行埋点时,产生的一种结构性特征。延迟、错误率、拒绝率、输出 Schema 符合度、Judge-eval 漂移——每一个都是合理的指标。每一个触发时都带有同样模糊的“模型行为改变”措辞。但它们都没有告诉值班工程师该做什么,因为没有人写过将每个信号映射到具体动作的 Runbook,因为大多数情况下,信号并不能对应到具体的动作。值班轮值吸收着噪音,直到噪音盖过了信号,然后值班人员就会绕过产生这些信号的频道。

重试预算如何从你的仪表板中隐藏了供应商的真实错误率

· 阅读需 12 分钟
Tian Pan
Software Engineer

周会汇报的幻灯片上写着 99.9%。发票则显示账单翻了三倍。这两个数字在相邻的仪表盘上共存了数月,却没人发现它们衡量的是不同的世界。可靠性数值是重试后的结果——每一个最终返回 200 的调用都被计为成功——而成本数值则是客户端进行的每一次尝试,按 Token 计费。在两者之间,是一个慷慨的五次重试循环,以及一个尾部延迟正在悄悄恶化的供应商。第一次有人同时观察这两个数字是在一次故障期间,当时成本异常告警在可用性告警之前就触发了。

这就是整个模式。一个看起来像是可靠性机制的重试预算,本质上也是一个成本-质量调节旋钮,而那些只关注其中一面的团队,正在为一个发票最终会修正的可用性数字买单。

你的故障指挥官无法执行的智能体运行手册

· 阅读需 10 分钟
Tian Pan
Software Engineer

报警在当地时间 02:17 响起。值班 SRE 在手机上打开智能体运行手册,阅读第一步:“检查智能体的工具调用追踪,寻找异常的工具使用情况。”他们打开链接,却遇到了一个他不属于的工作区的 SSO 登录提示。第二步说要检查提示词构建日志;同样碰壁。第三步说回滚到上一个提示词版本,但部署权限被限制在了一个他不在的团队中。等他弄清楚该向哪个 Slack 频道上报,并叫醒 AI 团队的产品经理时(因为她是 02:17 唯一能找到的人),九十分钟已经过去了,而客户可见的回归故障仍在持续给出错误答案。

事后分析会将权限鸿沟确定为直接原因。而更深层的不适感在于,这份运行手册在白天读起来很顺畅,但在深夜执行时却被封锁,因为编写手册的人拥有执行者所不具备的权限。

你的智能体平台忘了配置的值班轮换

· 阅读需 12 分钟
Tian Pan
Software Engineer

AI 平台团队有四名工程师。他们七个月前发布的内部 Agent 现在每天为 200 名员工回答问题。在第一个月,创始工程师亲自处理了每一个 Slack 消息——周二晚上 11 点,周日上午,甚至公司团建的晚上。随后,她因推动采用率方面的贡献而晋升为资深工程师(Staff Engineer),三周后,她在下午 6 点后就不再查看频道了,因为那是资深工程师该做的。原本打算取代她的值班轮换(on-call rotation)从未正式化,因为运营模式总是打算在“试点之后”再解决。

当 Agent 针对四分之一的用户静默降级的那天——一个悄然落后的检索索引,或者改变了拒绝行为的模型版本切换,或者是架构轮换后现在返回空数组的工具——投诉并不会降临到平台团队的传呼机(pager)上。它们落在帮助台队列中,由那些无法访问 Agent 追踪(traces)、不知道什么是系统提示词(system prompt)、并且被 IT 部门告知该 Agent “由 AI 团队负责”的人员处理。从第一个用户投诉到第一位工程师查看 trace,中间过去了 16 个小时。平台团队没有人玩忽职守;只是根本就没有人在执勤。

供应商配额在你的全球流量从未选中的时区重置

· 阅读需 10 分钟
Tian Pan
Software Engineer

你的每月 Token 配额在 00:00 UTC 重置。你最大的客户在东京,他们在 21:00 UTC(即当地时间第二天早上 6:00)达到峰值负载。当重置时刻到来时,东京的工作日已经在配额耗尽的降级方案中消耗了该周期的最后六个小时。429 错误看起来只是“偶发”,因为你仪表板上的 UTC 日历轴将每日重置边界隐藏在了普通的时间戳之中。

这不是速率限制(rate limit)的 Bug。这是一个日历 Bug。供应商为了结算方便选择了一个重置时钟,而你流量的地理分布决定了哪些客户会分配到周期末尾的空窗期。那些将配额定价为统一资源的团队,正基于一个用户从未见过的日历来进行配额分配。

你的仪表盘以三种不同方式统计了那次重试

· 阅读需 13 分钟
Tian Pan
Software Engineer

一个 Agent 运行了。计划步骤(plan-step)崩溃了。工具调用(tool-call)步骤在经历了两次 500 错误重试后,在第四次尝试时成功了。用户得到了他们的答案。

那算是多少个事件?问产品,这是一个事件 —— 用户得到了有效结果,因此转化漏斗统计了一次转化。问 SRE,那是三个失败加上一个成功,底层步骤的错误率是 75%。问财务,那是四次计费推理,两次重试的工具调用,以及大约四倍于产品部门预测的单位成本。每个团队的仪表盘都是正确的。但它们也是不可调和的,一旦有人试图调和它们 —— 通常是在事故回顾期间 —— 他们会发现团队已经基于三个相互矛盾的可信度图景运行了数月之久。

你的后端基础设施并非为流式响应而设计

· 阅读需 13 分钟
Tian Pan
Software Engineer

流式传输(Streaming)是一项产品决策。设计团队的某个人看到竞争对手的聊天 UI 像打字机一样逐个吐出 Token,看到用户在第 200 毫秒看到第一个字符出现时肩膀放松了下来,而不是盯着 4 秒钟的空白屏幕发呆,于是决策就此达成:我们要做流式传输。这个拉取请求(PR)修改了 API 网关中的三个文件。现在,模型输出通过服务器发送事件(Server-Sent Events,SSE)增量刷新。功能在周二上线,周三的满意度评分就有了明显的提升。没人向基础设施团队提工单。

一个月后,值班工程师盯着三个互不一致的仪表盘发愁。自动扩缩容(Autoscaler)配置的 Pod 数量是 CPU 图表显示需求量的两倍。P99 延迟仪表盘坏了——不是出了故障,而是变得无法解读,因为直方图分桶(Histogram Buckets)止步于 5 秒,而现在大多数 Span 都落在溢出区间。上一季度定价时的容量模型显示,该服务每节点每秒可处理 1200 个请求。而值班人员面前的图表显示,它在处理 400 个请求时就已经难以为继。

你用智能体替换的内部搜索框刚刚成为了你的 SLO

· 阅读需 12 分钟
Tian Pan
Software Engineer

你停用了公司门户上的搜索栏,因为智能体(Agent)表现得更好。以简单的英语输入问题,获得带引用的回答,通过追问进行优化。试点项目的满意度指标爆表。上线邮件写道:“弃用旧版搜索,两周内全量切换。”两周过去了。旧索引被停用。查询框被聊天输入框取代。

六个月后,在某个周二的早晨,三件事同时发生。由于某人的批处理作业耗尽了共享配额,你的推理服务商对公司账号进行了限流。向量嵌入(Embedding)服务出现了区域性局部故障。一次配置推送清空了 Prompt 缓存。公司里每一位习惯在搜索栏输入“VPN 设置”或“报销政策”的工程师,现在都盯着加载动画转了 40 秒,然后收到一条无法理解其问题的拒绝信息,或者更糟——一条指向不存在的 Wiki 页面的言之凿凿的引用。员工互助的 Slack 频道消息炸了。IT 部门的收件箱里塞满了“搜索是不是坏了?”

你取代的搜索栏在过去 10 年的微小改进中保持了三个九(99.9%)的可用性。取而代之的智能体有着完全不同的故障形态——是变慢而非宕机,是出错而非空白,是昂贵而非缓存——而你的 SRE 文化尚未针对此进行校准。

那个假设人类会阅读页面的 On-Call 运维手册

· 阅读需 11 分钟
Tian Pan
Software Engineer

警报在凌晨 02:14 响起。运维手册(runbook)写着“呼叫工程师”。工程师的名字关联到了一个值班轮值。该轮值指向一个 Slack 频道,这是团队在六个月前建立的统一分诊界面。频道中的第一条消息是告警。十九秒后发布的第二条消息是一段冷静的三句总结:告警服务、失败的依赖项、最后一次部署。它写得很好,最后以“已确认(Acknowledged)”结尾。

事故指挥官在床上看着手机,读到“已确认”后便翻身继续睡去。然而,并没有人确认。作为一线分诊助手的智能体(Agent)订阅了该频道,它向频道复述了告警内容,并以频道中其他读者习惯用来表示“我已掌握处理此问题的上下文”的动词收尾。这起事故在无人接手的情况下运行了 41 分钟,直到一张客户工单通过另一个界面唤醒了另一位工程师。

没有模型推理项的故障复盘模板

· 阅读需 11 分钟
Tian Pan
Software Engineer

第一次智能体导致我们团队出现真正的停机事故时,复盘报告的作者打开模板,划过时间线,盯着“根因”字段沉思了良久,然后输入:“队列阻塞恢复的操作指南 (runbook) 有误。” 但实际上操作指南没问题。智能体阅读了指南,认定队列的症状符合另一种场景,并针对该场景运行了恢复脚本。那份文档产生的改进措施——“细化操作指南用词”、“在恢复脚本中增加确认提示”——对于实际的故障模式完全无用。实际情况是一个推理系统推导错误,而模板中没有任何字段知道该如何表达这一点。

自那以后,我看到同样的失败在不同团队中反复上演。模板是为确定性系统设计的。代码做错了,你就修复代码;配置设错了,你就修复配置。复盘文档的模式 (schema) 就是团队关于故障理论的模式,当这个理论无法表达“智能体的计划错了”时,文档就会将实际故障强行降维成模板表达的最接近的事物——通常是文档缺失或缺乏护栏——从而导致改进措施试图用确定性的修复方案去解决概率性的故障。然后,同一类事故会再次发生,团队下次依然会以同样的方式记录它。

把自己调度进维护窗口的 Agent

· 阅读需 11 分钟
Tian Pan
Software Engineer

凌晨两点值班的资深工程师不会在 Sev-2 事故中跑 schema 迁移。他们不会在发布冻结开始前十分钟重新部署支付服务。他们不会在邮件服务商状态页飘红的时候发起一波营销邮件投放。这些都不写在 JD 里。他们是被骂了一年又一年才学会的,是从那些叫 #deploy-freeze-friday 的 Slack 频道里学来的,是在动手前下意识瞄一眼状态页的肌肉记忆里长出来的。这种上下文不在任何 runbook 里,因为没人觉得它值得被写下来。

现在把同样的活交给一个 Agent。Agent 有工具。Agent 有多步计划。Agent 拥有你愿意写进 system prompt 的每一条策略。Agent 没有的,是那种半下意识的觉察——这个世界现在正着火。所以它就执行计划了。干净利落,信心满满。一头扎进维护窗口。事后复盘里那句话会变成一个新的固定句式:"Agent 没办法知道。"

凌晨 3 点拥有合并权限的 CI Agent

· 阅读需 13 分钟
Tian Pan
Software Engineer

凌晨 3 点 17 分,一个不稳定测试被隔离了。On-call 轮值没有被叫醒,因为根本没东西失败——Agent 判定这次失败是噪声,自动开了一个标题为 chore: quarantine flaky test 的小 PR,用 ci-bot 这个 service account 把它 self-merge 了,然后继续盯着队列。六天之后,一个用户来反馈说某个功能从周二开始就坏了。那个测试不是 flaky,它是把一个真实回归挡在生产之外的唯一防线,而 Agent 那个 confidence threshold 设得刚好高到敢做决定,又刚好低到会判断错。

这是 agentic CI 中市场材料从不提及的那部分。在 2026 年,把 Agent 接进 pipeline 让它分流失败、对安全告警做依赖降级、提出依赖升级,在工程上其实很简单——工具齐了、集成只差一个 config 文件、生产力故事也是真的。没人写 runbook 的部分,是你刚刚引入的那一类新的操作主体:一个在凌晨 3 点没有任何人类同步在环、却拥有合并权限的角色,而你的 SRE 手册当初就是默认人类才是意图的来源。