企业级 AI API 可观测性 2026:Token、延迟、错误率、SLO 看板从 0 搭建
(updated )

企业级 AI API 可观测性 2026:Token、延迟、错误率、SLO 看板从 0 搭建

TL;DR — AI API 调用的可观测性,比传统服务多三个新维度:token 用量(input / output / cached / reasoning 分开)、流式延迟(TTFT 和 TPOT 而非单一 latency)、以及按调用拆分的成本归因。本文给出 2026 年企业落地路径:先用 OpenTelemetry GenAI semantic conventions 打底,按”代理模式 + SDK 埋点”双层采集,照 7 项 SLI 画看板,加 burn-rate 告警。文末附 ofox 用户的最小可运行配置。

为什么传统 APM 看不到 LLM 真正的问题

把一个调 LLM 的服务挂到 Datadog 或 New Relic 上,你会看到一条 HTTP 请求:status 200,duration 3.4s。然后呢?没了。

但这一次调用里隐藏的真问题,APM 根本不知道:

  • 这次调用花了多少钱?输入 12000 token、输出 800 token、reasoning 4500 token,按 ofox 的 Claude Opus 4.7 计价大约 0.18 美元,但 APM 那条 span 只告诉你 “HTTP 200, 3.4s”
  • 用户感知到的等待时间是什么?流式接口的真实体验是 TTFT(首 token 时间),不是 E2EL(端到端时间)。p95 TTFT = 1.8s 是好的,p95 TTFT = 6s 用户已经在切别的应用了
  • 截断了没有finish_reason = "length" 在 HTTP 层是 200,但下游业务可能直接拿到半截 JSON 然后 parse 失败
  • 谁触发的?同一个服务承载 5 个产品功能,账单一个月暴涨 40%,APM 告诉不了你哪个功能是元凶

LLM 调用的”四个黄金信号”(latency、traffic、errors、saturation)每个含义都和传统服务不一样。下面把 7 个真正该采的指标列清楚。

第一性原理:要采哪 7 个 SLI

维度指标为什么这个指标,不是别的
延迟(首 token)TTFT p50 / p95流式接口下用户感知的”反应时间”
延迟(生成速度)TPOT p50 / p95(ms/token)长输出场景的体验决定因素;厂商侧降级时第一时间露馅
延迟(端到端)E2EL p99非流式 / 批量场景;超时熔断的依据
流量每分钟请求数 + 每分钟 output token 数LLM 限流是按 RPM 和 TPM 双轨制,只看 RPS 会漏
错误按错误类型拆的 error rate(429 / 529 / 5xx / length 截断 / content_filter)一个总 error rate 数字会把”我打太快了”和”模型挂了”混在一起
饱和度rate-limit headroom(剩余配额 / 总配额)比 CPU/内存饱和度更重要,LLM 服务的瓶颈几乎总是配额
成本每次调用的 USD + 按 user_id / feature_id / model 标签拆分单看月账单没法做归因

注意几个反直觉的点:

TPOT 比 TTFT 更早暴露厂商侧降级。当 ofox / OpenAI / Anthropic 的某个模型路由切到了过载实例,TTFT 可能还正常(队列调度优先),但 TPOT 会从 30ms/token 慢到 80ms/token。这是早期信号。

finish_reason 必须当成结构化指标采,不是日志里的字符串。把 length / stop / tool_calls / content_filter 做成 Prometheus label 或 OTel span attribute,否则你永远查不到”上周日多少个调用被截断了”。

rate-limit headroom 要在每次响应后采。各家厂商的响应 header 都会带剩余 RPM / TPM,但命名不一样:OpenAI / Azure OpenAI 用 x-ratelimit-remaining-requests / x-ratelimit-remaining-tokens,Anthropic 用 anthropic-ratelimit-requests-remaining / anthropic-ratelimit-tokens-remaining(还细分 input-tokens-remaining / output-tokens-remaining),Gemini 通过 quota metric 暴露。在 collector 层做厂商归一化映射成统一的 gauge metric,配额吃紧时提前几分钟告警。

三种部署架构,怎么选

架构 A:代理 / 网关模式(Helicone / LiteLLM / 自建)

应用端不改一行代码,把 base URL 从 https://api.openai.com/v1 换成 https://your-gateway.com/v1,所有调用经过你的代理。代理负责打 metric、写日志、限流、缓存。

[app] --> [helicone / litellm gateway] --> [openai / ofox / anthropic ...]
            |
            +--> [postgres / clickhouse / langfuse]

适合:已经有多个服务在调 LLM、不想推动每个团队接 SDK、希望统一限流和缓存策略的中大型组织。

不适合:单一服务、需要 LLM 调用和业务 trace 串在一条链上做根因分析的场景。代理模式天然丢失了应用上下文。

架构 B:SDK 埋点(OpenTelemetry auto-instrumentation)

直接给你的 Python / Node / Go 应用装一个 OTel auto-instrumentation 包,它会自动 hook openaianthropicgoogle-genai 这些客户端,生成符合 OTel GenAI semantic conventions 的 span。

Python 例子:

pip install opentelemetry-instrumentation-openai-v2
# 流式 content 需要显式启用
export OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT=true
opentelemetry-instrument python your_app.py

每个 LLM 调用会生成一个 span,属性遵循 OTel GenAI semconv(gen_ai.systemgen_ai.request.modelgen_ai.usage.input_tokensgen_ai.usage.output_tokens 等)。

注意 semconv 状态:截至 2026 年 5 月,OTel semconv 仓库已发到 v1.41,client spans 走出了 experimental,agent / framework spans 还在 development 状态。要打开最新版字段,需要 OTEL_SEMCONV_STABILITY_OPT_IN=gen_ai_latest_experimental。Datadog 从 v1.37 起原生认这套字段,Honeycomb、New Relic、Grafana Tempo 也都跟上了。

适合:希望 LLM trace 和数据库、HTTP、消息队列的 trace 串成完整调用链的团队。

:reasoning token(Claude extended thinking、GPT-5 reasoning)的字段在不同 SDK 里命名不一致,auto-instrumentation 还在补齐。涉及到时自己手动加 span attribute。

架构 C:旁路应用层(Langfuse / Arize Phoenix SDK)

应用代码里显式调 Langfuse / Phoenix 的装饰器,把每次 LLM 调用作为一个 generation 上报,附带 prompt 模板 ID、user_id、session_id 这些业务维度。

from langfuse import observe
from langfuse.openai import openai  # drop-in 替换

@observe()
def answer_user_question(user_id: str, question: str):
    return openai.chat.completions.create(
        model="anthropic/claude-opus-4.7",
        messages=[{"role": "user", "content": question}],
        metadata={"user_id": user_id, "feature": "support_qa"}
    )

适合:需要把 prompt 模板版本、evaluation 分数、A/B 实验组也一起记录下来的 AI 应用团队。Langfuse 是当前 OSS 阵营最完整的选项(MIT license、ClickHouse 后端、支持 self-host)。

和架构 B 不冲突:很多团队 Langfuse 抓 LLM 业务维度,OTel 抓基础设施 trace,两个数据源用 trace_id 关联。

怎么选

你的现状推荐路径
团队已经在用 ofox / LiteLLM,多个服务调 LLMA → B(先上代理拿基线,再补 SDK 埋点串调用链)
单一 AI 应用、Python / Node 后端C 为主,B 做基础设施层兜底
强合规要求(金融 / 医疗),不能让 prompt content 出应用域B + 自建 OTel collector,禁用 OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT
一句话先看到东西在 ofox API base URL 前挂 Helicone proxy,10 分钟出第一张图

SLO 看板从 0 搭建

四块(latency / traffic / errors / cost)一张图,按这个 layout 起步够用:

块 1:延迟分布

  • 柱状图:TTFT p50 / p95 / p99,按模型拆分(Claude Opus 4.7、GPT-5.5、Gemini 3.1 Pro、Qwen3.7 Max 等)
  • 时序图:TPOT p95,过去 24h 折线,按模型上色
  • 红线:交互式产品的 TTFT SLO(建议 p95 < 2s);批量任务 p95 < 10s

p99 看 E2EL,p95 看 TTFT。把这两个放在一个 panel 里,能马上区分”模型变慢”还是”我们的工程链路变慢”。

块 2:流量 + 配额 headroom

  • 总 RPM / TPM:当前值 + 过去 7 天同比
  • 配额剩余比例 gauge:每个 provider × model 一根,低于 20% 黄、低于 10% 红
  • 请求按调用方拆分:堆叠图,user_id / feature 维度

配额告警比错误率告警更值得提前。429 一旦冒出来,损失已经发生。

块 3:错误率拆分

  • stacked area chart:按错误类型 stack(429 / 529 / 5xx / timeout / length / content_filter
  • error rate by model:哪个模型最不稳

length 截断单独看一块。截断率突然飙高,说明 prompt 模板让模型输出超长,或者你的 max_tokens 设小了。这个问题不报错,但下游 JSON parser 直接崩。

块 4:成本

  • 每小时 USD 时序图,按 model 堆叠
  • 当日累计 USD vs 月预算(条形图 + 进度条)
  • per-feature cost table:feature_id × USD × 调用次数 × 平均 token / 次

成本归因要从 SDK 层带 metadata={"feature": "...", "user_id": "..."},不然落到看板上你只有 model 维度。

把上面 4 块拼成一个 Grafana dashboard JSON 或一个 Langfuse 视图,团队 5 个人都对着同一张图看就够了。

告警规则:burn-rate 比固定阈值更可靠

最常见的反模式:把”error rate > 1%“做成告警,结果半夜 OpenAI 抖动 30 秒,5 条告警全炸;周末业务量小、绝对错误数低,但 burn rate 早超了却一条不响。

正确做法是 multi-window multi-burn-rate,照 Google SRE 那套:

SLO: 30 天内 99.5% 请求成功(错误预算 = 0.5%)

# fast burn(5 分钟告 PagerDuty)
1 小时窗口 burn rate > 14.4   AND   5 分钟窗口 burn rate > 14.4

# slow burn(1 小时告 Slack)
6 小时窗口 burn rate > 6     AND   30 分钟窗口 burn rate > 6

LLM 服务的错误预算分两类:

  • 可用性 SLO(成功调用) / (总调用),目标 99.5% / 30 天
  • 延迟 SLO(TTFT < 2s 的调用) / (总调用),目标 95% / 30 天

延迟 SLO 比可用性 SLO 更容易破线,因为厂商侧排队延迟随机性大。两个 SLO 各设各的 burn-rate alert,不要共用。

成本归因:标签是底层操作

每次调用必须打这 4 个标签,没有这些标签,月底账单和工程问题对不上:

metadata = {
    "user_id": "u_123",
    "feature": "support_qa",       # 业务功能
    "experiment": "prompt_v3",     # A/B 组
    "environment": "prod",
}

在架构 A(gateway)里,让应用通过 HTTP header(X-Helicone-User-IdX-Helicone-Property-Feature)把这些传过来。在架构 B(OTel SDK)里,作为 span attribute 打。在架构 C(Langfuse)里,作为 metadata 字段传。

落到看板上后,每周一份 cost 报告自动生成:

  • 哪个 feature 的 cost per request 突然上涨 → prompt 模板可能加长了
  • 哪个 user 异常高频 → 是 abuse 还是新上的批量任务忘记下采样
  • cached token 占比 → 决定是否值得开启 prompt caching

ofox 用户的最小可运行配置

如果你已经在用 ofox.ai 的统一 API,下面这个组合 30 分钟能跑起来:

1. 把 base URL 换成 ofox + 加 OTel 埋点

from openai import OpenAI
from opentelemetry import trace
from opentelemetry.instrumentation.openai_v2 import OpenAIInstrumentor

OpenAIInstrumentor().instrument()

client = OpenAI(
    base_url="https://api.ofox.ai/v1",
    api_key=os.environ["OFOX_API_KEY"],
)

OTel auto-instrumentation 会自动产出符合 GenAI semconv 的 span,里面有 input / output token、model、TTFT。

2. 用一个本地 Langfuse 接收业务维度

git clone https://github.com/langfuse/langfuse.git
cd langfuse
docker compose up -d

然后用 Langfuse 的 @observe 装饰器把 user_id、feature 打上。Langfuse 默认会按 ofox 实际计价算 cost,前提是 model 字段写对,按 ofox 实际格式带 provider 前缀,比如 anthropic/claude-opus-4.7openai/gpt-5.5google/gemini-3.1-pro-previewx-ai/grok-4.20

3. 在 ofox 控制台核对账单

ofox 控制台的 usage 视图是”账单事实源”,Langfuse / Datadog 的成本估算和这个核对一遍。两边差距 > 3% 就是模型计价表过期了,更新一下本地的 pricing config。

4. SLO 阈值起点

指标建议初始 SLO
TTFT p95< 2s(交互场景)
E2EL p99< 30s
可用性99.5% / 30 天
length 截断率< 0.5%
月预算超额当月 ≤ 110% 即告警

跑 2 周拿到自己的真实分布后再调,不要一开始就拍 99.9%。

常见踩坑

坑 1:把流式接口的 latency 当成端到端时间报time.time() - start 在流式里只测到第一个 chunk 之前的时间,这是 TTFT,不是 E2EL。要分别测 first_chunk_time - startlast_chunk_time - start

坑 2:reasoning token 不在 output_tokens。Claude extended thinking、GPT-5 reasoning 都有独立的 reasoning_tokens 字段。如果只采 input + output,月底账单会比 dashboard 高 30-50%。

坑 3:prompt caching 节省没记账。cached input token 价格是普通 input 的 10%-25%(厂商不同),如果你的看板把 cached 和未 cached 合并算,cost 会偏高,会让你误以为优化空间没那么大。

坑 4:tool calling 的中间步骤当成单次调用。一次用户请求触发 model → tool → model → tool → model,这是 4 次 LLM 调用,账单按 4 次出。看板按”agent run”做聚合视图,不要按”LLM call”看就以为是单次。

坑 5:告警通道太多。所有 LLM 服务的告警先 fan-out 到一个 collector channel,按 severity 二次路由。SRE 团队最讨厌的就是 5 个 LLM 服务每个都直接 PagerDuty。

相关阅读

可观测性不是上线后的”加个监控”环节,是从选型那一刻就该想的事情。你想达到的 SLO、能采集的指标、计价的透明度,决定了这套 LLM 系统能不能跑到企业级。