AI 遥测高基数预算:控制租户、Prompt 与 Trace 标签爆炸
AI 请求天然携带模型、租户、Prompt 版本和工具链等高维信息。本文给出指标标签分层、基数预算、OpenTelemetry 属性裁剪、Prometheus 验收与超限回滚方案。
本文要点
- 主题聚焦:AI、大模型、DevOps
- 适合人群:独立开发者、全栈工程师、AI 应用开发者
- 核心价值:快速理解背景、实践路径、常见误区和工程建议
AI 遥测最容易出现的事故,不是少采一个指标,而是把本来适合放在 Trace 里的值塞进 Prometheus 标签。tenant_id、user_id、request_id、完整模型名、Prompt 哈希、会话 ID 和工具参数各自看起来都有诊断价值,组合后却会让活跃时间序列按乘法增长。存储费用和查询延迟先上升,随后 Collector 排队、远端写入限流,最终连真正用于告警的基础指标也被淹没。
这不是通用的“接入 Prometheus”教程。Prometheus 与 Grafana 可观测性 已说明监控栈基础,LLM 可观测性 也覆盖 trace、eval 与 metric。本篇只解决一个生产约束:每个新增 AI 遥测维度必须先证明其基数可控,并在失控时能够单独切断。
先把信号分成三个承载层
指标只保留边界有限、能聚合和能告警的属性,例如 service、environment、route、model_family、provider、outcome 与经过枚举的 error_class。租户可按套餐或隔离池分组,但不要直接使用租户 ID。指标回答“影响面有多大”,不承担单请求取证。
Trace 可以保存 request_id、Prompt 版本、工具名和供应商请求 ID,因为 Trace 本身有采样与保留边界。即便如此,也不应把原始 Prompt、用户邮箱或工具参数默认写入属性。日志用于少量结构化事件,索引字段仍采用白名单;高基数值放在非索引正文或隔离对象存储中。需要逐租户归因时,优先从账本或离线明细计算,AI 成本归因 的请求级账本比长期维护数百万条指标序列更可靠。
用乘法估算,而不是凭感觉审批
为每个 metric 建立标签域上限。假设请求直方图包含 3 个环境、20 个服务、4 条路由、6 个模型族、5 类结果和 12 个 bucket,理论上已经产生 3 × 20 × 4 × 6 × 5 × 12 = 86,400 条 bucket 序列;再加入 500 个租户会变成四千多万。预算表需要记录预计域、最坏组合、每小时新增序列、保留天数和负责人。
建议给每个服务设置两级门槛:单个新指标的 series 上限,以及整个服务的 active-series 总额。发布前用回放流量跑十五到三十分钟,观察实际组合而非只看标签各自的 distinct 数。验收可查询 prometheus_tsdb_head_series、远端写入失败率、Collector export queue 使用率,并用 /api/v1/status/tsdb 或后端 cardinality API 找出贡献最大的 label pair。
topk(10,
count by (__name__, service) ({job="ai-gateway"})
)
sum by (service) (
rate(otelcol_exporter_send_failed_metric_points_total[5m])
)
门禁不能只写“相比基线涨幅不大”。例如规定 canary 的活跃序列增量不得超过 8%,单指标不得超过 50,000 条,远端写入失败必须为零,p95 查询耗时不得恶化 20%。超过任一项就停止扩大流量。
在 SDK 和 Collector 两层限制属性
应用侧通过 OpenTelemetry View 为指标选择明确的 attribute keys,并把 model 映射为受控的 model_family。未知供应商型号进入 other,而不是自动成为新标签。Collector 再做第二道防线,删除任何意外透传的身份和请求属性:
processors:
transform/cardinality_guard:
error_mode: ignore
metric_statements:
- context: datapoint
statements:
- delete_key(attributes, "enduser.id")
- delete_key(attributes, "tenant.id")
- delete_key(attributes, "gen_ai.prompt.id")
- delete_key(attributes, "request.id")
service:
pipelines:
metrics:
processors: [memory_limiter, transform/cardinality_guard, batch]
不要依靠 Prometheus metric_relabel_configs 才开始清理,因为样本已经穿过 SDK、网络和 Collector,前置成本仍然存在。也不要用哈希后的用户 ID 作为指标标签;哈希隐藏了原值,却没有降低基数。AI 平台租户配额隔离 中的稳定租户身份适合记账和限额,不代表它适合时序索引。
建立可观测性自己的变更流程
每个指标变更随代码提交一份 telemetry diff:新增或删除哪些 metric,标签集合怎样变化,预计 series 数、采样数据和负责人是什么。Collector 配置先进入影子管线,只写短保留测试后端;确认看板和告警可以用低基数聚合表达后,再切主远端写入。对模型动态路由,必须测试供应商返回未知型号、长版本号和空值时的归一化结果。
持续告警至少包括 active series 增速、样本拒绝、WAL 或队列积压、Collector 内存、远端写入延迟和最重指标排名。日常看板显示“预算已用百分比”,而不是等存储账单异常才处理。每周扫描最近出现的新标签值,并把无法解释的增长追到具体部署。
超限时先保住告警基本盘
发生基数爆炸后,第一步冻结相关发布并确定首个异常时间;第二步按 metric 和 label 找出增长源;第三步启用预先准备的 Collector 紧急规则,删除高风险属性或临时丢弃单个新指标。不要关闭整条 metrics pipeline,也不要在事故中同时调整采样、保留期和存储集群。
回滚采用版本化配置:恢复上一份已签名的 View 与 Collector 配置,重启 canary 后确认新序列增长停止、发送失败归零、核心告警仍有数据,再逐步覆盖实例。已创建的旧序列不会立刻消失,因此还要等待 head block 和保留周期收敛;未经后端支持不要直接删除 TSDB 文件。
事故结束后,用同一段回放流量验证修复,并补一条“未知维度值”测试。高基数预算真正保护的不是监控费用,而是故障发生时仍能查询到延迟、错误和饱和度。只有把单请求细节放回 Trace,把指标限制在有限域,AI 平台的诊断能力才会随流量增长而不是一起崩溃。
延伸阅读
Related