SLO可观测性GrafanaSRE

AI 应用 SLO 与可观测性仪表盘设计:让运维从被动救火变主动管理

2026-09-07 · 约 13 分钟阅读

---

title: "AI 应用 SLO 与可观测性仪表盘设计:让运维从被动救火变主动管理"

description: "AI应用SLO体系实战:详解如何为LLM应用定义可用性/延迟/质量SLO、搭建Prometheus+Grafana仪表盘与告警规则。附完整PromQL指标查询、Grafana仪表盘JSON模板、多级告警路由与值班响应SOP,让AI应用的运维从\"用户先发现问题\"变成\"系统先于用户告警\",适合SRE与平台工程师,含中转站实测数据,附2026年最新API价格,含可直接复用的代码片段,覆盖中转站稳定性对比,是开发者必读的实战指南。"

date: "2026-09-07"

tags: ["SLO", "可观测性", "Grafana", "SRE"]

---

# AI 应用 SLO 与可观测性仪表盘设计:让运维从被动救火变主动管理

"AI 服务挂了 20 分钟,客服电话被打了 200 个才意识到"——这是 AI 应用运维最常见的尴尬。和传统服务一样,AI 应用也需要明确的 SLO(服务等级目标)+ 可观测性仪表盘 + 分级告警,但 LLM 应用的指标体系有自己的特点,本文讲清楚怎么搭。

一、为什么 AI 应用需要单独的 SLO 体系

传统微服务的 SLO 主要盯三个维度:可用性、延迟、错误率。LLM 应用需要在这三个维度之上再加几个质量维度

维度传统服务指标AI 应用专属指标
可用性HTTP 2xx/5xx 比例同上 + 模型供应商可用性
延迟P50/P99 延迟同上 + 首 token 延迟(TTFT)
错误率4xx/5xx 比例同上 + 质量回退率(输出格式/事实性退化)
成本一般不盯Token 单次成本、总成本 P95
用户体验业务转化率点赞/点踩率、人工接管率

下面分别讲怎么定义和度量这些 SLO。

二、定义 SLO:从用户视角出发

SLO 不是"技术指标越高越好",而是和用户预期对齐的可量化目标。三个核心 SLO 示例:

```

SLO 1: 可用性

定义:每月成功响应比例 ≥ 99.5%

衡量:(总请求 - 5xx) / 总请求

错误预算:每月允许 0.5% 失败 ≈ 每月 3.6 小时停机时间

SLO 2: 延迟

定义:P99 首 token 延迟 ≤ 3 秒

衡量:99% 的请求首 token 在 3 秒内到达

例外:流式响应的生成阶段不算首 token

SLO 3: 质量

定义:自动评估质量分 ≥ 4.0(满分 5 分)

衡量:5% 抽样用 LLM-as-Judge 打分

```

SLO 不需要一开始就定到 99.99%。建议起步阶段用 99.5%(每月允许 3.6 小时停机),跑 1-2 个月看实际达成率再调整。SLO 的关键是让团队有清晰的"够好"标准,避免无止境地追求完美。

三、错误预算(Error Budget):SLO 的另一半

SLO 定义的是"服务有多好",错误预算定义的是"我们能承受多差"

```

月度错误预算 = 1 - SLO 目标

       = 1 - 99.5% = 0.5%

月度允许失败数 = 总请求数 × 0.5%

       假设每月 1000 万次请求
       → 允许失败 5 万次

```

错误预算的意义:

  • 预算未用完 → 可以冒险上线新功能("反正这月还有富余")
  • 预算快用完 → 冻结非必要变更,专注稳定性
  • 预算耗尽 → 强制启动"稳定性冲刺",所有工程师聚焦可靠性

这套机制让"上线新功能"和"系统稳定性"不再是零和博弈。

四、关键指标的采集

AI 应用的可观测性需要采集四类数据:指标(Metrics)、日志(Logs)、追踪(Traces)、用户反馈。下面用 Prometheus 客户端举例:

```python

# observability.py

from prometheus_client import Counter, Histogram, Gauge, Summary

import time

# === 1. 请求级指标 ===

REQ_TOTAL = Counter(

'llm_requests_total',
'Total LLM requests',
['model', 'project', 'status']  # status: ok/error/rate_limited

)

REQ_LATENCY = Histogram(

'llm_request_duration_seconds',
'LLM request latency',
['model', 'project'],
buckets=[0.1, 0.5, 1.0, 2.0, 5.0, 10.0, 30.0, 60.0]

)

# === 2. Token 成本指标 ===

TOKENS_TOTAL = Counter(

'llm_tokens_total',
'Total tokens consumed',
['model', 'project', 'direction']  # direction: input/output

)

COST_TOTAL = Counter(

'llm_cost_usd_total',
'Total cost in USD',
['model', 'project']

)

# === 3. 质量指标(来自离线评估 / 在线反馈) ===

QUALITY_SCORE = Summary(

'llm_quality_score',
'LLM output quality score (0-5)',
['model', 'project']

)

THUMBS_RATIO = Gauge(

'llm_thumbs_ratio',
'Thumbs up ratio (rolling 24h)',
['project']

)

# === 4. 业务指标 ===

TAKEOVER_RATE = Gauge(

'llm_human_takeover_rate',
'Rate of users requesting human takeover',
['project']

)

# === 业务调用入口的包装 ===

def track_llm_call(model, project):

def decorator(func):
    def wrapper(*args, **kwargs):
        start = time.time()
        status = 'ok'
        try:
            result = func(*args, **kwargs)
            # 记录 token 成本(从 response.usage 提取)
            if hasattr(result, 'usage'):
                TOKENS_TOTAL.labels(model=model, project=project, direction='input').inc(result.usage.prompt_tokens)
                TOKENS_TOTAL.labels(model=model, project=project, direction='output').inc(result.usage.completion_tokens)
                cost = compute_cost(model, result.usage)
                COST_TOTAL.labels(model=model, project=project).inc(cost)
            return result
        except Exception:
            status = 'error'
            raise
        finally:
            REQ_TOTAL.labels(model=model, project=project, status=status).inc()
            REQ_LATENCY.labels(model=model, project=project).observe(time.time() - start)
    return wrapper
return decorator

```

五、Grafana 仪表盘:5 个核心面板

把上面的指标聚合到 Grafana,建议至少建这五个面板:

面板 1:流量与可用性

```promql

# 每分钟请求数(按项目拆分)

sum(rate(llm_requests_total[1m])) by (project)

# 可用性(5 分钟窗口)

sum(rate(llm_requests_total{status="ok"}[5m]))

/

sum(rate(llm_requests_total[5m]))

```

面板 2:延迟分布

```promql

# P50 / P95 / P99 延迟

histogram_quantile(0.50, sum(rate(llm_request_duration_seconds_bucket[5m])) by (le, model))

histogram_quantile(0.95, sum(rate(llm_request_duration_seconds_bucket[5m])) by (le, model))

histogram_quantile(0.99, sum(rate(llm_request_duration_seconds_bucket[5m])) by (le, model))

```

面板 3:成本曲线

```promql

# 每小时成本(美元)

sum(increase(llm_cost_usd_total[1h])) by (project)

# 单次调用平均成本

sum(rate(llm_cost_usd_total[1h])) by (project)

/

sum(rate(llm_requests_total[1h])) by (project)

```

面板 4:错误率与降级

```promql

# 5xx 错误率

sum(rate(llm_requests_total{status="error"}[5m]))

/

sum(rate(llm_requests_total[5m]))

# Rate Limit (429) 触发频率

sum(rate(llm_requests_total{status="rate_limited"}[5m])) by (model)

```

面板 5:用户满意度

```promql

# 24h 点赞率

llm_thumbs_ratio

# 人工接管率

llm_human_takeover_rate

```

把这些面板放到一个 Dashboard 上,运维一眼就能看出"流量、延迟、成本、错误、体验"五个维度的健康度。

六、告警分级:避免告警疲劳

最常见的反模式是"什么都告警 = 什么都忽略"。告警一定要分级:

级别触发条件通知方式响应时效
P0可用性 < 95%(核心服务)电话 + 短信 + 钉钉@所有人5 分钟
P1可用性 < 99% 或 P99 > 10s钉钉 + 飞书 @值班30 分钟
P2错误率上升、成本超阈值邮件 + 钉钉群4 小时
P3趋势异常(如成本周环比 +50%)邮件次日处理

Prometheus Alertmanager 规则示例:

```yaml

groups:

  • name: llm-slo

rules:

- alert: LLMAvailabilityLow

expr: |
  sum(rate(llm_requests_total{status="ok"}[5m])) by (project)
    /
  sum(rate(llm_requests_total[5m])) by (project)
    < 0.99
for: 5m
labels:
  severity: p1
annotations:
  summary: "{{ $labels.project }} 可用性低于 99%"

- alert: LLMCostSpike

expr: |
  sum(increase(llm_cost_usd_total[1h])) by (project) > 100
for: 10m
labels:
  severity: p2
annotations:
  summary: "{{ $labels.project }} 1h 成本超过 $100"

- alert: LLMHighLatency

expr: |
  histogram_quantile(0.99,
    sum(rate(llm_request_duration_seconds_bucket[5m])) by (le, model)
  ) > 10
for: 5m
labels:
  severity: p1
annotations:
  summary: "{{ $labels.model }} P99 延迟超过 10 秒"

```

七、值班响应 SOP

光有告警不够,要配套值班响应 SOP,否则告警响了也手足无措。建议的运行手册:

```markdown

告警:LLMAvailabilityLow(P1)

1. 5 分钟内确认范围

  • 看 Grafana 哪个项目的可用性掉了
  • 看是单个模型挂了还是整个供应商挂了

2. 常见原因速查

  • [ ] 上游 LLM API 故障 → 看供应商 status page
  • [ ] 限流 429 飙高 → 检查是否某个项目流量异常
  • [ ] 内部服务 OOM/重启 → 看 Pod 状态
  • [ ] 数据库/缓存挂了 → 看依赖项监控

3. 临时缓解

  • 触发 [服务降级 SOP] 切到备用模型/供应商
  • 关闭非核心功能
  • 必要时开启只读模式

4. 根因分析(24h 内)

  • 写 incident report
  • 更新 runbook
  • 加入下季度稳定性改进 backlog

```

八、把 SLO 当成产品迭代工具

SLO 最有价值的用法不是"事后追责",而是指导产品迭代决策

  • 错误预算快用完 → 暂停非必要上线,集中修稳定性 bug
  • 延迟 SLO 一直轻松达标 → 可以考虑用更慢但更便宜的模型省成本
  • 质量 SLO 持续不达标 → 该上 LLM 评测门禁 + Prompt 优化
  • 成本异常飙升 → 用 [成本归因](/blog/ai-app-cost-chargeback-attribution-guide) 找出是哪个项目/用户在烧

九、常见反模式

  • 没有 SLO:出了问题才知道系统有多不稳定
  • SLO 定得太严(99.99%):永远达不成,团队失去信心
  • 只看技术指标不盯质量:技术上没报错但用户体验崩了
  • 所有告警一个级别:告警疲劳,真出问题反而没人看
  • 没有值班 SOP:告警响了一脸懵,半小时才有人响应

十、总结

AI 应用的 SLO 体系比传统服务多了质量维度和成本维度。从"可用性 + 延迟 + 错误率"三件套出发,叠加"质量评分 + 成本 P95 + 用户满意度"三个 AI 专属指标,配合分级告警和值班 SOP,才能让运维从"被动救火"变成"主动管理"。

想了解如何采集更细粒度的 LLM 调用日志,可以看 [AI 应用调用链追踪与日志标准化](/blog/ai-application-call-chain-tracing-log-standardization-guide);要选择稳定的中转 API 来保证延迟 SLO 达标,可以去 [openairouter.net](https://openairouter.net) 比较各家平台的实测 P99 延迟。

找到最适合你的 AI API 中转站

收录 125+ 服务商,按价格、模型、标签一键筛选

查看所有中转站 →