可观测性是从系统外部输出(指标、日志、链路追踪)反推内部状态的能力,AI 项目需要它,是因为大模型应用的”错误”不再是进程崩溃,而是语义偏差、幻觉、Token 浪费和不可复现的回答。我们给”AI 爆款文章创作器”接入可观测性体系后,线上问题定位从平均 2 小时缩到 15 分钟,核心做法是:在 Spring Boot 后端埋入结构化日志、用 OpenTelemetry 串起”选题→大纲→初稿→润色”的多阶段生成链路、把 Token 消耗与首字延迟做成指标送进 Prometheus。下文给出这套体系的选型依据与可直接复用的实现片段。
一、可观测性与监控不是一回事
监控回答”系统挂没挂”,可观测性回答”系统为什么变成这样”。前者围绕预定义指标做阈值告警,后者依赖丰富的上下文让你在未知故障里逆向推导。判断标准很朴素:一个从未想过的故障发生时,手里有没有足够数据找出根因。
| 维度 | 监控 | 可观测性 |
|---|---|---|
| 数据来源 | 预定义指标 | 指标 + 日志 + 链路追踪 |
| 应对故障 | 已知问题的阈值告警 | 未知问题的根因推导 |
| 数据关联 | 各指标独立 | 按 trace_id 全局串联 |
| 对 LLM 场景 | 只能看到”没崩” | 能看到”答错了、为什么错” |
传统 APM 对确定性代码有效,因为每行代码的输入输出可预判。LLM 应用有三大不确定性:用户输入长尾不可穷举、检索与 Prompt 拼装过程是黑盒、输出语法正确但事实错误。这些不确定性正是传统手段失效、必须构建专属观测体系的原因。
二、AI 项目观测与传统微服务的差异
落地前先明确差异,否则会照搬 HTTP 监控模板,抓不到 AI 场景的关键信号。
| 观测维度 | 传统微服务 | AI 项目 |
|---|---|---|
| 核心指标 | QPS、错误率、P99 延迟 | Token 用量、首 Token 时间(TTFT)、语义质量分 |
| 故障形态 | 异常、超时、依赖不可用 | 幻觉、检索遗漏、Prompt 截断 |
| 追踪粒度 | HTTP 请求链路 | 多阶段生成链路(检索→重排→生成→校验) |
| 成本关注 | 资源占用 | Token 直接等于费用 |
我们的文章创作器把生成拆成选题打分、大纲规划、正文初稿、风格润色四个阶段,每阶段独立调一次模型。如果不做链路追踪,用户反馈”文章偏题”时,你分不清是选题阶段就选偏了,还是初稿阶段 Prompt 丢上下文。链路上每个 Span 携带输入摘要与 Token 数,就能精确定位。
三、三大支柱的落地方式
3.1 指标(Metrics):回答”整体表现如何”
采集四类即可覆盖大部分场景:请求量与错误率、Token 用量(输入/输出分开)、延迟分布(TTFT 与总耗时)、成本(按模型和用户聚合)。Micrometer 注册 Counter 与 Timer,Prometheus 拉取,Grafana 出图,下面是创作器里统计一次生成阶段耗时的代码:
Timer.Sample sample = Timer.start(registry);
try {
String content = chatClient.call(prompt);
return content;
} finally {
sample.stop(Timer.builder("article.gen.duration")
.tag("stage", "draft") // 初稿阶段
.tag("model", modelName)
.publishPercentiles(0.5, 0.95, 0.99)
.register(registry));
}
TTFT 用 Timer 单独记:从 SSE 连接建立到首个数据块到达的毫秒数,它直接反映用户感知的”打字感”。低于 200ms 属于正常,超过 800ms 就该查上游并发配额。
3.2 日志(Logs):回答”这次请求到底发生了什么”
日志必须结构化,每个字段有明确语义,禁止散装字符串拼接。我们统一在 JSON 日志里携带 traceid、stage、tokenusage、latencyms、promptpreview(截断到 200 字符),用户会话 ID 兜底关联。PII 字段在写入前脱敏,避免敏感信息进日志系统。
采样策略控制成本:全量记录元数据,正文内容按 10%~25% 采样,命中失败、超时、触发安全拦截的请求无论采样率一律全量落盘。
3.3 链路追踪(Traces):回答”请求在系统里怎么流转”
基于 OpenTelemetry 埋点,一次对话生成一条 Trace,四个生成阶段各是一个 Span,挂上模型名、Token、阶段结果。OpenTelemetry 的 GenAI 语义约定把 gen_ai.operation.name、gen_ai.usage.input_tokens 这些属性标准化,后面换观测后端不用重埋。
四、AI 项目特有的三类质量指标
机器指标再齐全,也回答不了”回答对不对”。三类质量指标补上这块:
- 成本健康度:每请求 Token、每用户日消耗,异常暴涨通常意味着 Prompt 注入或死循环调用。
- 语义质量分:对采样请求用规则或轻量模型评估忠实度、相关性,低于阈值触发告警。
- 流程健康度:多阶段生成的平均迭代次数、工具/阶段调用失败率、上下文是否频繁触顶。
五、为文章创作器构建体系的五个步骤
- 后端引入 spring-boot-starter-actuator 与 micrometer-registry-prometheus,暴露
/actuator/prometheus端点; - 定义日志字段规范并接入全局 trace_id 生成器,每个请求入口生成一次;
- 在四个生成阶段各创建一个 Span,记录模型、阶段耗时与 Token 用量;
- 用 Prometheus 抓取指标,Grafana 建”生成耗时分布、Token 消耗趋势、按模型成本排行”三个面板;
- 先跑满一周建立基线,再给 TTFT、失败率、Token 异常增长配告警阈值。
六、常见踩坑
冷启动时 TTFT 基线未建立就配死阈值,会在发布瞬间误报。日志字段不统一,trace_id 缺失让排查断链,解决方法是请求入口强制注入,取不到就标记 unknown 并单独计数。标签基数失控最隐蔽:把用户 ID 直接做成 Prometheus 标签,几个热门用户就能撑爆时序库,用户维度应该走日志查询而非指标标签。
常见问题(FAQ)
Q1:可观测性和监控到底怎么区分?
监控查已知问题,可观测性查未知问题,后者需要指标、日志、链路三样数据联动。
Q2:AI 项目必须建全套体系吗?
不用一次做全,从结构化日志加 trace_id 起步,两周内就能见效,再逐步补指标与追踪。
Q3:Token 消耗该用指标还是日志记录?
总量与趋势用指标,单次明细用日志,二者通过请求 ID 关联即可。