跳到主要内容

可观测性

可观测性是让大模型系统“出问题时能解释清楚”的工程能力。

普通 Web 服务的可观测性通常关注 QPS、错误率和接口延迟。LLM 应用还要额外关注 prompt、token、上下文长度、流式输出、RAG、工具调用、模型版本、推理参数、GPU 和 KV Cache。

一句话概括:

LLM 可观测性 = 请求链路 + token 用量 + 模型行为 + 资源状态 + 业务结果

如果没有可观测性,线上问题会很难定位。用户说“模型变慢了”时,原因可能是输入变长、RAG 召回变慢、prefill 排队、GPU 显存紧张、工具接口超时、网关缓冲、prompt 版本变化,或者只是客户端渲染卡顿。

1. 观测对象

LLM 系统至少要观测五类对象。

对象关注点
请求链路request id、trace id、网关、业务服务、推理服务、工具和 RAG
模型输入输出prompt 版本、input tokens、output tokens、finish reason、采样参数
推理性能TTFT、ITL、E2E latency、queue time、prefill time、decode time
资源状态GPU 利用率、显存、KV Cache、batch、waiting / running requests
业务质量命中率、人工反馈、安全拦截、引用正确性、工具成功率

这些信息要能串起来。只看单点指标,很容易误判。

例如 TTFT 变高,可能来自:

  • 网关排队。
  • RAG 检索变慢。
  • prompt 变长。
  • tokenizer 慢。
  • scheduler waiting queue 变长。
  • prefill 计算变慢。
  • worker 冷启动。

只有把链路拆开,才能知道真正瓶颈在哪里。

2. 请求日志

请求日志是排障的基础。

建议每个请求至少记录:

字段说明
request_id单请求唯一标识
trace_id跨服务链路标识
tenant_id / user_id租户和用户,必要时哈希化
model外部模型名或别名
model_version实际命中的模型版本
prompt_versionprompt 或 system prompt 版本
template_versionchat template 版本
input_tokens输入 token 数
output_tokens输出 token 数
max_tokens用户或系统设置的最大输出
stream是否流式输出
finish_reasonstop、length、tool_calls、error 等
error_code失败时的稳定错误码
latency_ms端到端耗时

日志不要只记录“请求成功 / 失败”。LLM 请求的成本和风险差异太大,必须记录 token 和版本信息。

一个最小化的结构化日志可以长这样:

{
"request_id": "req_123",
"trace_id": "trace_abc",
"tenant_id": "tenant_hash",
"model": "qwen3-32b",
"model_version": "2026-04-18",
"prompt_version": "support-v12",
"input_tokens": 1840,
"output_tokens": 512,
"stream": true,
"finish_reason": "stop",
"latency_ms": 8420,
"ttft_ms": 920,
"error_code": null
}

日志字段要稳定,方便后续查询、聚合和告警。

3. Prompt 和 Output 采样

prompt 和 output 对排障很有价值,但也最容易触碰隐私和安全边界。

建议分层处理:

内容记录策略
prompt 原文默认不全量记录,只在受控环境或采样场景记录
output 原文默认采样记录,敏感业务需要脱敏或摘要
prompt 版本必须记录
system prompt 版本必须记录
RAG chunk id建议记录
tool schema 版本建议记录
推理参数必须记录

不要把“完整 prompt 进日志”当成默认方案。更稳妥的方式是:

  • 记录 prompt 模板版本和变量摘要。
  • 记录 token 数和上下文组成。
  • 对原文做采样。
  • 对敏感字段脱敏。
  • 给原文日志设置更严格的访问权限和保留周期。

排障时经常需要重放请求。为了重放,至少要保留:

  • 模型版本。
  • tokenizer 版本。
  • chat template 版本。
  • prompt 模板版本。
  • RAG 检索配置。
  • tool schema 版本。
  • 推理参数。
  • 输入数据的可追溯引用。

如果只保留最终文本,很多问题无法复现。

4. Token Usage

token 是 LLM 服务的核心计量单位。

必须记录:

  • input tokens。
  • output tokens。
  • total tokens。
  • cached tokens。
  • reasoning tokens,若模型或服务暴露。
  • 每个 RAG chunk 的 token 数。
  • tool schema 占用的 token 数。
  • 历史对话占用的 token 数。

token usage 用于:

  • 计费。
  • 限流。
  • 成本分析。
  • 容量规划。
  • 上下文裁剪。
  • 排查 TTFT。
  • 识别异常长请求。

常见问题是只看 QPS,不看 token。一个 QPS 很低的长文档总结服务,可能比高 QPS 的短问答服务更吃 GPU。

建议按这些维度聚合 token:

维度用途
model对比不同模型成本
tenant / user配额、账单和异常使用
endpoint区分 chat、embedding、rerank、tool
prompt version判断版本变更是否导致 token 膨胀
input length bucket观察长上下文占比
output length bucket观察长输出占比

如果 prompt 版本升级后 input tokens 均值突然上升,要及时告警。这类变化会直接影响 TTFT、显存和成本。

5. 延迟指标

LLM 延迟不能只看 E2E latency。

建议拆成:

指标含义
E2E latency从客户端发起到完整响应结束
TTFTTime To First Token,首 token 延迟
ITLInter Token Latency,token 间隔
queue time进入推理服务后的排队时间
prefill time处理输入 prompt 的耗时
decode time生成输出 token 的耗时
RAG latency检索、rerank、上下文组装耗时
tool latency工具调用耗时

不同指标对应不同问题:

  • TTFT 高:用户觉得系统迟迟不开始回答。
  • ITL 高:用户觉得输出一顿一顿。
  • E2E 高:完整任务耗时长。
  • queue time 高:容量或调度不足。
  • prefill time 高:输入太长或长上下文压力大。
  • decode time 高:输出太长、模型慢或并发高。

线上仪表盘至少要看 p50、p90、p99,而不是只看平均值。

平均延迟容易掩盖少量长上下文、长输出或工具超时造成的长尾问题。

6. 流式输出观测

流式输出要额外观测:

  • active streams。
  • first chunk time。
  • chunk 间隔。
  • stream error rate。
  • client disconnect rate。
  • cancel rate。
  • cancel 后 worker 是否释放资源。
  • [DONE] 或结束事件是否正常发送。
  • usage 是否在最后返回。

流式接口常见的线上问题包括:

  • 本地流式,线上被网关缓冲。
  • 客户端断开后,GPU 仍继续生成。
  • 中途错误只表现为连接断开,没有稳定错误码。
  • finish_reason = length 被当作正常完成。
  • 前端每个 chunk 全量渲染,导致 UI 卡顿。

因此流式日志里要记录:

  • 开始时间。
  • 首 token 时间。
  • 结束时间。
  • 是否用户取消。
  • 是否客户端断开。
  • 是否上游异常。
  • finish reason。

对应阅读:流式输出

7. GPU 和 KV Cache 指标

推理服务必须观测 GPU 和 KV Cache。

建议监控:

指标说明
GPU utilizationGPU 计算利用率
GPU memory used / reserved显存使用和预留
GPU memory free剩余显存
KV Cache usageKV Cache 使用率
KV Cache blocks free可用 cache block
preemption / eviction抢占或缓存淘汰
running requests正在运行的请求
waiting requests等待调度的请求
batch size当前 batch 中 sequence 或 token 数
input tokens/sprefill 吞吐
output tokens/sdecode 吞吐

不要只看 GPU 利用率。

GPU 利用率高可能说明吞吐好,也可能说明长 prompt 或长输出把服务打满。GPU 利用率低也不一定说明系统空闲,可能是 tokenizer、RAG、队列、网络或客户端消费速度拖住了链路。

KV Cache 对长上下文和高并发更敏感。很多服务不是权重显存不够,而是运行时 KV Cache 被长请求占满。

对应阅读:KV Cache并发与批处理

8. 错误码和异常分类

LLM 服务需要稳定的错误分类,不能只返回 500

常见分类:

类型示例
请求错误参数非法、上下文超长、模型不存在
鉴权配额API key 无效、配额不足、限流
调度错误队列满、worker 不可用、KV Cache 不足
推理错误OOM、CUDA error、模型执行失败
上游依赖RAG 检索失败、工具超时、数据库错误
安全策略输入拦截、输出拦截、权限不足
客户端行为客户端取消、连接断开、超时

建议错误日志包含:

  • 稳定 error_code
  • error_type
  • 是否可重试。
  • 发生阶段。
  • request id / trace id。
  • worker id。
  • 上游依赖名称。

发生阶段很关键。timeout 可能发生在网关、RAG、排队、prefill、decode、工具调用或客户端消费阶段,处理方式完全不同。

9. 链路追踪

一次 LLM 请求可能经过多个服务:

Client
-> API Gateway
-> Business API
-> RAG Service
-> Reranker
-> LLM Gateway
-> Inference Worker
-> Tool Service
-> Database / External API

需要用 trace id 把这些步骤串起来。

建议每个 span 记录:

  • span name。
  • start / end time。
  • request id / trace id。
  • model / version。
  • input / output token。
  • error code。
  • dependency name。
  • retry count。

典型 span 可以包括:

  • auth。
  • rate limit。
  • prompt build。
  • retrieval。
  • rerank。
  • tokenizer。
  • scheduler queue。
  • prefill。
  • decode。
  • tool call。
  • output postprocess。

链路追踪的价值是定位“慢在哪里”,而不是只知道“这次请求慢”。

10. RAG 召回日志

RAG 问题经常表现为“模型答错”,但根因可能是没有召回正确内容。

建议记录:

  • query。
  • query rewrite 结果。
  • embedding model。
  • index version。
  • top k。
  • rerank model 和版本。
  • 命中的 document id / chunk id。
  • chunk score。
  • rerank score。
  • 最终进入 prompt 的 chunk id。
  • 引用是否出现在答案中。

原文内容是否记录,要根据隐私和权限决定。即使不记录原文,也要记录可追溯的 chunk id 和 index version。

排查 RAG 时要能回答:

  • 有没有召回正确文档?
  • 召回了但 rerank 是否排低了?
  • 进入 prompt 的内容是否被上下文裁剪掉?
  • 模型是否忽略了引用内容?
  • 答案引用是否和实际 chunk 对齐?

对应阅读:RAG 工程化

11. 工具调用日志

Agent 和 tool calling 场景必须记录工具轨迹。

建议记录:

  • tool schema version。
  • tool name。
  • tool call id。
  • 参数摘要或脱敏参数。
  • 参数校验结果。
  • 开始时间和结束时间。
  • 工具返回状态。
  • 工具错误码。
  • retry 次数。
  • 是否命中权限拦截。
  • 工具结果是否进入下一轮模型输入。

工具日志用于判断:

  • 模型是否选错工具。
  • 参数是否生成错误。
  • 工具本身是否超时。
  • 权限是否配置错误。
  • 重试是否造成重复副作用。
  • 工具结果是否被模型正确使用。

高风险工具还要记录审批、确认和审计信息。

对应阅读:工具调用

12. 安全与隐私

可观测性不能以牺牲隐私为代价。

常见敏感内容包括:

  • 用户输入。
  • 文档原文。
  • 检索结果。
  • 工具参数。
  • API key。
  • 邮箱、手机号、身份证、地址等个人信息。
  • 内部系统 ID。
  • 业务交易数据。

建议策略:

  • 默认结构化记录元数据,不默认全量记录原文。
  • 对 prompt / output 做采样。
  • 对敏感字段脱敏。
  • 原文日志单独存储,单独授权。
  • 设置日志保留周期。
  • 记录访问审计。
  • 高风险业务支持关闭原文采样。

脱敏要在进入日志系统前完成,不能依赖后续查询时再处理。

13. 告警

告警要覆盖用户体验、服务健康和成本风险。

常见告警项:

告警项说明
error rate 上升服务失败增多
p99 TTFT 上升首 token 体验变差
p99 ITL 上升流式输出卡顿
queue time 上升容量或调度不足
KV Cache usage 过高接近显存或缓存瓶颈
OOM / CUDA error推理 worker 异常
timeout rate 上升链路或上游依赖异常
token usage 异常增长成本或 prompt 膨胀风险
safety block rate 异常安全策略或流量变化
tool error rate 上升外部依赖异常

告警阈值要按模型、业务和租户区分。长文档总结服务和短问答服务的正常延迟范围不同,不能使用同一套阈值。

14. 仪表盘

建议至少建立几类仪表盘。

仪表盘内容
入口流量QPS、请求成功率、错误率、限流率
延迟体验TTFT、ITL、E2E、p50 / p90 / p99
Token 用量input / output tokens、tokens/s、长请求分布
推理资源GPU、显存、KV Cache、batch、队列
RAG 质量召回量、rerank 分数、引用命中、检索耗时
工具调用调用次数、成功率、耗时、错误码
成本按模型、租户、业务线拆分的 token 和 GPU 成本

仪表盘要支持下钻到:

  • model。
  • model version。
  • tenant。
  • endpoint。
  • prompt version。
  • worker。
  • region。

否则整体平均值会掩盖局部故障。

15. 常见问题

15.1 用户说变慢了,但 QPS 没变

可能原因:

  • input tokens 变长。
  • output tokens 变长。
  • prompt 版本变更导致 token 膨胀。
  • RAG 检索或 rerank 变慢。
  • scheduler queue time 上升。
  • KV Cache 接近上限。

排查顺序:

  1. 看 TTFT、ITL、E2E 哪个变差。
  2. 看 input / output token 分布是否变化。
  3. 看 queue time 和 KV Cache。
  4. 看 RAG / tool span 是否变慢。
  5. 看最近模型、prompt、模板和路由是否发布过。

15.2 答案质量变差,但模型没换

可能原因:

  • prompt 版本变了。
  • RAG index 更新了。
  • 检索 top k 或 rerank 配置变了。
  • 工具 schema 变了。
  • 推理参数变了。
  • 上游业务数据变了。

需要对比:

  • model version。
  • prompt version。
  • retrieval config。
  • tool schema version。
  • sampling params。
  • 命中的 chunk id。

15.3 GPU 利用率高,但吞吐没提升

可能原因:

  • 长 prompt prefill 占用算力。
  • batch 调度不合理。
  • KV Cache 频繁抢占。
  • worker 间负载不均。
  • 输出很长导致 decode slot 被占住。

要看 tokens/s、queue time、running / waiting requests、KV Cache usage,而不是只看 GPU utilization。

15.4 线上问题无法复现

常见原因:

  • 没记录模型真实版本。
  • 没记录 chat template 版本。
  • 没记录 prompt 变量。
  • 没记录 RAG chunk id。
  • 没记录推理参数。
  • 线上使用随机采样,未记录 seed 或无法复现。
  • 工具调用结果已变化。

复现能力要在设计日志时就考虑,不能等事故后再补。

16. 实践检查清单

上线前至少确认:

  1. 每个请求都有 request id 和 trace id。
  2. 日志记录 model、model version、prompt version 和 template version。
  3. 日志记录 input tokens、output tokens 和 finish reason。
  4. 延迟拆分到 TTFT、ITL、E2E、queue、prefill、decode。
  5. 流式输出记录取消、断开和中途错误。
  6. GPU、显存、KV Cache、running / waiting requests 有指标。
  7. 错误码稳定,并能区分发生阶段。
  8. RAG 记录 index version、chunk id、score 和进入 prompt 的内容引用。
  9. 工具调用记录 tool name、schema version、参数校验和错误码。
  10. prompt 和 output 原文日志有采样、脱敏、权限和保留周期。
  11. 告警覆盖错误率、TTFT、ITL、queue、KV Cache、OOM 和 token 异常增长。
  12. 仪表盘能按模型、租户、版本和 worker 下钻。

17. 和其他概念的关系

  • 推理服务架构:可观测性要贯穿 API、调度、worker 和资源层。
  • 流式输出:TTFT、ITL、取消率和中途错误是流式体验的核心指标。
  • 并发与批处理:queue time、batch、running / waiting requests 决定高并发下的延迟。
  • 容量与成本规划:token usage、GPU 利用率和稳定吞吐是成本估算的输入。
  • RAG 工程化:召回日志和引用链路决定 RAG 问题能否定位。
  • 工具调用:工具轨迹决定 Agent 行为能否审计和复现。

18. 总结

LLM 可观测性的核心不是多记日志,而是把“用户请求如何变成模型输出”这条链路拆清楚。

最关键的几类信息是:

  • 请求和链路标识。
  • 模型、prompt、template、RAG 和工具版本。
  • token 用量。
  • TTFT、ITL、E2E 和阶段耗时。
  • GPU、显存、KV Cache 和队列状态。
  • 错误码、finish reason 和安全策略命中。

只有这些信息能串起来,线上问题才能从“模型好像不对”变成可验证、可定位、可回滚的工程问题。