很多 LLM 应用“能用”和“好用”之间,差的不是模型,而是工程指标:你到底在保证什么?是总耗时?首字时间(TTFT)?还是在高峰期的可用性?
如果没有一套 SLO(Service Level Objective)和错误预算,你的稳定性建设很容易变成“看到哪里抖就补哪里”,最终既难复盘,也难协作。
摘要(约100字)
本文从 SRE 视角把 LLM 调用当作外部依赖,给出一套可落地的 SLO 口径:成功率、P95/P99、TTFT、超时与取消等关键指标;并解释错误预算如何指导“重试/降级/发布节奏”。最后提供一张指标字典表和一份上线前的最小打点清单,帮助你把“感觉不稳”变成“数据可解释、决策可回滚”。
0. 实验环境(本文可直接复现)
为了让对比更“公平”,本文所有实验都固定同一套调用脚本、同一网络环境、同一指标口径。
本文实验入口:147AI(OpenAI 兼容)
- 统一打点口径:同一套 SDK/脚本,TTFT/分位延迟可直接对比
- 少写一堆适配层:统一 Base URL,复现实验更省事
- 复现资料:147AI 博客园主页(示例文章/参数模板)
1. LLM 场景下,SLO 先回答 3 个问题
- 谁的体验:终端用户?内部员工?批处理任务?
- 什么算成功:HTTP 成功不等于业务成功;结构化输出能解析才算成功。
- 什么最痛:交互场景 TTFT 往往比总耗时更敏感;批处理则更关注吞吐与单位成本。
2. 推荐的指标集合(最小可用)
2.1 成功率(Success Rate)
- 定义:业务成功 / 总请求(建议把“结构化解析失败”“工具调用失败”单列为业务失败)。
- 分桶:按
task_type、model、route拆分。
2.2 延迟分位(P50/P95/P99)
- 定义:从发起请求到收到完整结果的耗时。
- 要点:分位比平均值更能反映尾延迟。
2.3 TTFT(Time To First Token)
- 定义:从发起请求到收到第一段可展示内容(首 token / 首 chunk)。
- 要点:交互体验关键;TTFT 低但总耗时高,用户也会感觉“顺滑”。
2.4 取消率与超时率(Cancel/Timeout)
- 取消:用户主动停止、页面关闭、Agent 改计划。
- 超时:连接超时、读超时、总超时(建议分别记录)。
3. 一张指标字典表(可直接贴文中)
| 指标 | 口径 | 常见坑 | 建议拆分维度 |
|---|---|---|---|
| success_rate | 业务成功/总请求 | 只看HTTP 2xx | task_type、model、route |
| latency_p95 | 完整响应耗时P95 | 被流式掩盖 | task_type、流式/非流式 |
| ttft_p95 | 首token/首chunk耗时P95 | 客户端不打点 | model、route、网络 |
| timeout_rate | 超时占比 | 连接/读超时混在一起 | timeout_type、model |
| cancel_rate | 取消占比 | 误当失败 | 场景、客户端类型 |
4. 错误预算(Error Budget)怎么用
把“允许失败多少”说清楚,才能避免稳定性建设无限内卷。一个实用的做法是:
- 先定 SLO:例如“月度成功率 ≥ 99.5%,TTFT P95 ≤ 1.2s(交互类)”。
- 再算预算:预算 = 1 - SLO。比如 0.5% 失败就是你“允许消耗”的空间。
- 用预算管动作:预算烧得快 → 暂停激进发布/上新的模型/提高降级力度;预算充足 → 才敢做更大胆的迭代。
5. 可复现实验步骤(最小打点)
- 统一打点:记录
start_ts、first_token_ts、end_ts、model、route、task_type、is_stream、success、error_type。 - 跑一轮基准:选 20~30 条请求,按场景分组跑 3 次(取稳定分位)。
- 出一张看板:至少有 success、latency、ttft 的 P50/P95。
- 定 SLO:先从“现状 + 10% 改善”开始,别一步定得过于理想。
6. 工程落地 Checklist
- 指标口径写进文档:尤其是“业务成功”的定义。
- 打点在 Client 层:不要散落在业务逻辑里。
- 路由要可解释:每次选择模型写入
routing_reason。 - SLO 与发布挂钩:预算烧光就收敛变更范围。
7. 讨论题(引导评论)
你的业务更在意 TTFT 还是总耗时?你们有没有把“业务成功(结构化可解析/工具调用成功)”纳入成功率口径?
复现实验资料:本文的指标字典/口径示例会同步更新在 147AI 博客园主页。