跳到主要内容

161 篇博文 含有标签「observability」

查看所有标签

Reranker 是你 RAG 评估中从未衡量的“静默”第二个模型

· 阅读需 12 分钟
Tian Pan
Software Engineer

一个典型的 RAG 流水线包含两个模型,而不是一个。检索器从向量数据库中提取 50 到 100 个候选文档,而重排序器(reranker)——无论是交叉编码器(cross-encoder)、LLM-as-judge 提示词还是混合方案——都会对这些候选文档进行重新评分,并将前 5 个结果交给回答模型。你的评估套件测量端到端的回答质量,测量检索器的 recall@k,但它并不测量重排序器。因此,当重排序器发生隐性偏移(drift)时,仪表盘上显示的“回答质量下降了 4 个点”却没有任何因果线索,团队会花费三天时间去调试一个根本不是问题的提示词。

重排序器是那个隐性的第二个模型。它介于检索器和生成器之间,拥有自己的评分分布、自己的提示词(如果是基于 LLM)或自己的权重(如果是交叉编码器),并且它可以独立于其他任何组件发生性能退化(regress)。大多数团队从未单独对它进行评分。他们编写的评估套件将流水线视为一个具有长上下文窗口的单一模型,而实际上它是两个串联的模型,且其中间接口并不属于任何一个团队。

重试并非免费:大模型重试策略的 FinOps 数学逻辑

· 阅读需 12 分钟
Tian Pan
Software Engineer

我在上季度接触的一个团队在他们的推理账单上发现了一笔 4200 美元的条目,没人能解释其来源。控制面板显示的流量正常,延迟图表也很平稳。原因最终被发现是一个 Agent 陷入了长达 6 小时的“礼貌”重试循环中,它不断地通过指数退避(最高限制为 30 秒后重启)来重放一个包含 4 万个 Token 的工具链。这套重试策略是直接从 2019 年为基于 HTTP 的 JSON 服务编写的内部 SRE 手册中照搬过来的。它运行得非常完美——只是用错了系统。

这就是那种不会出现在容量规划表中的账单。行业标准化的无状态 REST API 重试策略模式默认了三个前提,而 LLM 工作负载在悄无声息中违背了这些前提:故障是瞬时的、单次额外尝试的成本是有限的,以及重试有合理的成功机会。每一个前提曾是关键的支撑,而现在每一个都是错的。这种成本模型从未捕获的偏差,正潜伏在每一份月度账单的底部。

那些还没有根据 Token 经济学重建重试策略的团队,正在缴纳一种隐形税。这种税收随着你本就最担心的查询难度而增加——那些长文本、Agent 类以及带有深层工具链的查询。在 LLM 技术栈中,经典韧性工程提供给你的安全网,反而成了勒紧脖子的绞索。

下午 3 点和凌晨 3 点的同一个 Prompt 并不是同一个 Prompt:LLM 评估中的昼夜漂移

· 阅读需 13 分钟
Tian Pan
Software Engineer

评估套件在凌晨 2 点运行。流量很低。缓存是冷的,但队列是空的。供应商的连续批处理程序有空闲插槽,并将以接近其 TTFT(首 Token 延迟)底线的水平处理每个请求。延迟分布很紧凑,评测模型分数稳定,仪表盘显示一片绿色。团队发布上线。

六个小时后,太平洋时间上午 8 点,同样的 Prompt 在美国早高峰期间进入生产环境。p95 延迟是评估报告的 2.4 倍。相当一部分请求从一个供应商那里收到了 529 错误,并回退到另一个供应商的较小路由层级。流式传输的节奏更加断断续续。评测模型(当天晚上对生产环境追踪样本进行重新运行)给出的中位数得分比凌晨 2 点给出的相同 Prompt 的得分低了半分。代码库没有变化。Prompt 没有变化。只是挂钟时间变了。

必须意识到的架构真相是:LLM 调用不是其输入 Token 的纯函数。它是一个随机分布式系统调用,其输入包括挂钟时间、供应商集群的负载、Prompt 缓存的状态、当前解码批次的大小,以及供应商负载均衡器在你的请求到达的那一毫秒所做出的路由决策。在凌晨 2 点运行评估的团队,是在一种用户永远无法体验到的条件下校准仪器。

结构化输出重试循环:你被忽视的算力浪费

· 阅读需 13 分钟
Tian Pan
Software Engineer

打开你的结构化输出仪表盘。它自豪地显示着类似 “98.4% 的 Schema 合规率” 这样的数字。这就是成功率——即第一次尝试就生成有效 JSON 对象的请求比例。团队为剩下的 1.6% 构建了一个重试封装器(retry wrapper),发布上线,然后就没再管了。两个季度后,推理费用增长了 15%,而请求量仅增长了 4%。首席财务官(CFO)想要个解释。工程师们给不出解释,因为跟踪结构化输出成功率的仪表盘并不跟踪结构化输出的成本。

仪表盘隐藏的部分在于:失败路径并非只有一次重试。第一次重新提示(re-prompt)修复了缺失的 enum 字段,但引入了一个格式错误的嵌套数组。第二次重新提示修复了数组,但丢掉了一个必填键。第三次尝试终于通过了验证,但到那时,该请求已经消耗了四次完整的推理调用加上最初的生成过程,而你的单次请求 Token 计数器显示的是 总和,而不是循环过程。从计数器的角度来看,这是一个昂贵的请求。从成本线的角度来看,这是一个你从未定价的随机循环。

这篇文章将探讨该循环究竟对你的算力预算产生了什么影响,为什么你现有的观测能力(observability)无法察觉到它,以及哪些规范可以使其变得可见且可控。

Token-Per-Watt:你的仪表盘无法计算的 AI 可持续性指标

· 阅读需 12 分钟
Tian Pan
Software Engineer

你的可持续发展仪表盘报告显示:“本季度 AI 能耗:2.3 GWh,同比下降 4%”,这张幻灯片在 ESG 评审中得到了礼貌性的认可。六个月后,CFO 走出分析师电话会议,向平台负责人提出了一个听起来很简单的问题:“我们的每瓦特 Token 数(token-per-watt)是多少?与竞争对手相比如何?”仪表盘无法回答。这并不是因为数据缺失——仪表盘里堆满了数据——而是因为它将推理视为单一的条目,将任务视为产品概念,而 AI 可持续性唯一真实的单位存在于这两者的交汇点。

这种错位并不是报告中的 Bug。这是一个分类错误,现有的碳核算指南(为基于 CPU 小时和每台虚拟机 kWh 的云工作负载而完善)无法独自解决。推理并不是一种具有稳定能量特征的工作负载。每 Token 的瓦特数会根据响应请求的模型层级(model tier)产生 30 倍的变化,根据调用时的批处理大小(batch size)产生 4 倍的变化,并根据前缀缓存(prefix cache)是否命中而产生另一个数量级的差异。将这些汇总成一个单一的 GWh 数字,就像在包含踏板车、轿车和 18 轮大卡车的车队中报告“平均汽车燃油效率”一样——在最无用的层面上,它是准确的。

分词器漂移:你的本地计数在撒谎,账单才说真话

· 阅读需 10 分钟
Tian Pan
Software Engineer

我认识的一个团队花了三周时间追踪一个“上下文截断”的 Bug,这个 Bug 只在针对日本客户的生产环境中触发。他们的 CI 测试用例是英文的。他们的 tiktoken 计数显示 Prompt 符合 8K 的限制,且留有 600 个 Token 的余量。但供应商的账单显示,该请求因超过限制而被拒绝。这两个数字相差 11%,而安全余量正好落在在那 11% 之内,而且从未有人衡量过中日韩 (CJK) 文本上的这种差异。修复方案不是换一个新模型——而是不再将本地计数器作为事实标准。

这就是 Tokenizer 漂移那种隐蔽且昂贵的形式:不是一个简单的错误数字,而是一类在被你忽略的测试边界处累积的小型系统性误差。你 IDE 中的本地计数器、网关中的预算计算器、重试中间件中的速率限制评估器,以及供应商据以收费的权威计数——这些都不一致,而且差距恰恰在你用户所在的领域扩大。

工具重入:你的函数调用层尚未察觉的 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 的形式像日志而非图。结果就是,任何超过十几个条目的工具目录都会悄悄变成框架无法察觉的递归。

Agent 飞行记录仪:在第一次事故发生前必须捕获的字段

· 阅读需 14 分钟
Tian Pan
Software Engineer

当 agent 在生产环境中第一次失控时——它删错了行,给错误的客户发了邮件,在单个任务上烧掉了 400 美元的推理费用,或者对受监管的用户说了法律风险极高的话——团队打开日志,却发现他们实际上拥有的是:一串参数被截断的 CloudWatch 工具调用名,一个只捕获了最新一轮对话的“用户提示词”字段,而且没有记录实际运行的是哪个模型版本。供应商在两周前滚动更新了别名。系统提示词存在于一个没有快照的配置服务中。由于框架默认值是 0.7 且“人尽皆知”,因此没有记录温度。触发错误操作的工具结果超过了日志行大小限制,并被截断为“...”。

你无法重现决策过程。你只能猜测。六个月后,你堆积了一堆无解的“它为什么这么做”的报告,团队开始像对待天气一样对待 agent——把它当作一种发生在你身上的事情,而不是你可以调试的东西。

飞行记录仪准则(Flight recorder discipline)是你为了防止这种情况所能交付的最廉价的东西,但如果你等到第一次事故发生才开始,它也将是你交付的最昂贵的东西。以下字段是最低要求,存储形式不容商量,采样和隐私边界必须同步设计,而不是事后修补。

无真值情况下的智能体 SLO:为无法实时评分的输出建立错误预算

· 阅读需 13 分钟
Tian Pan
Software Engineer

你的智能体平台连续一年每季度都达到了 99.9% 的“响应成功率”SLO。但工单量增加了 40%。受智能体引导的用户群体的留存率却在下降。轮值运维感到无聊,产品经理在恐慌,而管理层评审一直在问,为什么仪表盘显示一切正常,而支持队列却显示情况一团糟。仪表盘没有撒谎。它只是衡量了错误的东西 —— 因为编写 SLO 的 SRE 将成功定义为“模型 API 返回了 200”,而这正是遥测系统最初唯一能表达的成功定义。

这是智能体可靠性工程的核心问题:成功的信号不是状态码。它是一种关于智能体是否针对特定任务做了正确事情的判断,而这种判断在请求时是无法获得的,通常在会话时也无法获得,有时只有在几天后,当用户提交工单、修改输出或悄无声息地流失时,才能揭晓。你无法在一个尚不存在的列上标记“200 对比 500”的布尔值。

常见的反应是等待获得基准真相(ground truth)后再宣布 SLO。这是错误的。可靠性工作不会在你构建标注流水线时暂停。正确的做法是针对你明知不完美的代理指标(proxies)编写错误预算,将它们命名为代理指标,设定团队在指标触发时的响应策略,并在产生基准真相后将其回填到计算中。这篇文章将探讨如何在不自欺欺人的情况下做到这一点。

30 秒都去哪了:APM 无法察觉的 Agent 步骤内部延迟归因

· 阅读需 13 分钟
Tian Pan
Software Engineer

仪表盘显示 p95 的 agent.run = 28s。用户反馈该功能感觉已经挂了。值班工程师打开 Trace(追踪),看到一个没有任何值得调查的子节点的“肥大”长条,然后开始盲猜。当有人重建出足够的心理模型,搞清楚瓶颈到底是模型、检索器,还是某个没人添加 Span 的工具调用时,故障已经变成了积压的任务单,而用户早已放弃了。

这就是 2026 年 Agent 运营核心的失败模式:传统的 APM 将 Agent 步骤视为一个黑盒,而“Agent 延迟”并不是一个单一指标——它是七个指标的总和,这些指标根据 Agent 在该轮次中的决策,以不同的方式分解实际用时 (Wall-clock time)。如果一个团队不暴露这七个数字,他们交付的功能虽然大家都能感觉到慢,但谁也无法修复。

智能体流量不等同于人类流量:为两类调用者设计 API

· 阅读需 13 分钟
Tian Pan
Software Engineer

你两年前发布的 API 是为单一类别的调用者设计的:浏览器或移动客户端背后的人,点击一次,然后等待响应。现在,大约一半的关键端点上,这个假设都是错误的。另一半流量是智能体(Agents)——你自己的、你客户的,或者是将你的端点作为工具使用的第三方集成——它们具有不同的运行逻辑。它们会产生爆发式流量。它们会无限重试。它们会并行处理。它们会逐字解析错误字符串。它们代表人类行事,而当出现问题时,人类无法即时提供意图说明。

今年出现在复盘报告(postmortems)中的大多数生产环境异常,都可以追溯到一个架构错误:将这两类调用者视为同一种类别。为人类步调设置的频率限制(Rate limits)会被智能体的并行扇出瞬间击穿。为人类可读而设计的错误消息,会被一个在 400 错误上无限重试的智能体解析错误。人类默认会满足的幂等性假设,在智能体从恢复的检查点重试相同的负载时会被打破。身份验证日志失去了区分“用户执行了此操作”与“用户的智能体代表用户执行了此操作”的能力。

解决方法不是更智能的 WAF 或更大的频率限制桶。而是一种深思熟虑的 API 设计,它定义了两类调用者,将它们的流量视为不同的形态,并记录委托链,以便在间接层级中保持可追溯性。

Agent 工作流的碳计算:Token 预算现已成为 ESG 披露

· 阅读需 12 分钟
Tian Pan
Software Engineer

无状态的聊天补全(Stateless chat completion)耗电量极低。一次中等规模的 Gemini 文本提示耗电约为 0.24 Wh;一次简短的 GPT-4o 查询约为 0.3–0.4 Wh。这些数字微乎其微,甚至没人会把它们放进董事会演示文稿里。

智能体任务(Agent task)并非普通的聊天补全。一个典型的“研究该客户并起草回复”的工作流可以扇出(Fan out)到 30 多个工具调用、10–15 次模型调用,且上下文窗口随着每一步不断增长。能源成本随调用图(Call graph)呈复合增长。当智能体返回结果时,你消耗的不是一个推理单元,而是五十到两百个。突然之间,每个任务的碳足迹便与视频流达到了同一数量级。

这种算术题很快就会在工程部门之外产生影响。欧盟的 CSRD 使范围 3(Scope 3)排放披露成为受规制公司的强制要求,并要求从 2026 年起提交机器可读的 iXBRL 报告。尽管 SEC 在其最终规则中删除了范围 3,但任何在欧盟有业务的跨国公司仍然必须回答这个问题。采购团队已经开始在供应商调查问卷中加入“你的 AI 功能每个用户任务的碳足迹是多少?”这类问题。大多数工程团队无法回答,因为从来没有人测量(Instrumented)过它。