跳到主要内容

你的 APM 正在悄悄丢弃 LLM 遥测数据,而 Bug 就隐藏在这些缝隙中

· 阅读需 12 分钟
Tian Pan
Software Engineer

目前你的系统中有一个损坏的 prompt 影响了约 3% 的流量,但你的仪表盘根本察觉不到它的存在。p99 延迟图表是绿色的。错误率保持平稳。模型调用成功率指标高达四个九。唯一的故障迹象出现在一张平台团队无法复现的客户支持工单中,而等这张工单进入调试环节时,相关的 trace 已经因为采样而被丢弃了。

这不是监控缺失,而是一个分类错误。你正在运行的 APM 是为维度受限(如 endpointstatus_coderegionservice)的世界设计的,在这种情况下,增加一个标签的成本最多只是增加几个新的时间序列。LLM 工作负载完全不符合这种模式。真正有趣的维度是用户的 prompt、检索到的 context ID、工具调用序列、模型版本、prompt 模板版本、租户(tenant)、语言区域(locale),以及请求所属的 eval bucket。每一个维度都是高基数(high-cardinality)的,只要你用其中任何一个子集来标记 span,指标存储瞬间就会爆炸。

团队的反应每次都如出一辙:聚合掉那些有问题的字段。为了防止成本曲线翻倍,放弃按租户细分的视图。从指标中剥离 prompt_hash,以阻止时间序列数量持续攀升。每一个决定在局部看都是理性的,但在全局看却是灾难性的,因为刚刚被移除的正是唯一能让故障可见的维度。聚合后的 p99 对一个群体取了平均值,在这个群体中,简单的查询总是通过,而困难的查询总是失败;损坏的 prompt 正隐身在“总是失败”的尾部,而这个尾部恰恰被平滑处理掉了。

为什么 LLM 遥测具有产品分析类的基数特征

典型的服务发出的遥测数据看起来像是一个低秩矩阵(low-rank matrix)。通常只有几百个端点、少数几个状态码、几个区域以及同时运行的少数几个服务版本。将它们相乘,你会得到数万个唯一的标签组合。Prometheus、Datadog 以及其他的指标栈正是为此设计的,且表现极其出色。只要每个维度的唯一值保持在大约一百个以内,单位基数的成本曲线是平缓的。

LLM 遥测则完全不同。每个 prompt 都是唯一的字符串。检索层为几乎每个请求返回不同的文档 ID 组合。工具调用的 trace 是一棵树,其形状取决于模型的决策。Prompt 模板本周在 eval 套件中已经更新到了第 14 个版本。模型本身有三个版本同时在线,因为金丝雀、对照和影子评估(canary, control, and shadow eval)正在同步运行。租户集包含数千个客户。语言区域集有几十个。将所有这些相乘,你得到的不是数万个序列,而是一个实际上无界的结果 —— 它更接近点击流分析(clickstream analytics),而非服务指标。

一个典型的检索增强生成(RAG)流水线 —— 向量查询、重排序(rerank)、模型调用、后处理 —— 发出的遥测数据量是同等无状态 API 调用的 10 到 50 倍,且遥测数据以高基数维度为主。这些基数没有一个是“多余的”。每个字段都是工程师调试特定类别故障时必须切分的维度。检索团队需要知道哪些文档 ID 出现在 context 中。Prompt 团队需要知道哪个模板版本处于激活状态。模型团队需要知道是哪个版本给出的回答。产品团队需要知道是哪个租户在投诉。剥离其中任何一个都不是优化,而是在有计划地破坏某人所需的信号。

指标层的悄然崩塌

这种失败在实践中很少表现为宕机。它是一种缓慢的漂移,仪表盘保持绿色,而操作人员虽然嘴上不说,但内心逐渐不再信任它们。通常会依次发生三件事。

首先,指标存储预算超支,告警层开始丢弃序列。在大多数平台上,这是静默发生的。Datadog 的自定义指标超额费用随基数线性增长,增加一个具有 1000 个唯一值的标签可能会使指标数量翻万倍,账单每月每项指标增加数千美元。一个简单的 prompt.template_id 标签(包含 200 个模板)加上一个 tenant_id 标签(包含 500 个租户)就会为一个指标创建 10 万个序列。财务团队往往比运维团队更早察觉到账单异常,而非数据丢失。

其次,团队通过聚合来应对。高基数维度从标签变成了丢弃规则,从丢弃规则变成了“我们会把它们留在日志里”,从日志变成了“我们会把它们留在采样率为 1% 的 trace 里”。每一步都保留了全局指标,却摧毁了细分指标。仪表盘上的数据形状保持不变,但它能回答的问题却随着每一次迭代而变得越来越窄。

最后,长尾变得不可见。当一个模板针对某个特定租户在特定语言区域下损坏时,全局质量指标不会波动,因为该故障仅占总请求量的一小部分。故障只有在客户投诉升级时才会浮出水面,而投诉转交到的团队,其工具链已被静默配置为不显示刚才发生的情况。平台团队开始说“我们无法复现”,因为他们确实无法复现 —— 采样层在他们介入之前就已经把 trace 丢弃了。

加载中…
References:Let's stay in touch and Follow me for more thoughts and updates