传统错误率、延迟和 HTTP 状态无法发现上下文截断、提示词变更或输出质量漂移等静默故障。文章主张为 LLM 功能补充输入、配置与质量层面的专用监测。
生产环境中的三种静默故障模式,标准 APM 无法发现;而这套插桩层能赶在用户察觉之前捕获它们。
你的 AI 功能通过了负载测试。延迟低于两秒,错误率低于百分之一,产品演示运行顺畅。于是你将它发布上线。三周后,一位客户反馈,AI 生成的内容“开始让人看不懂了”。但仪表盘显示一切正常。端点仍在返回 200,日志也风平浪静。
这就是生产环境 AI 后端存在的可观测性缺口。它与传统监控工具所针对的任何问题都不一样。
HTTP 响应码、p95 延迟和错误率描述的是传输层。对于提供缓存数据或查询关系型数据库的 REST 端点,这些指标已经足够。但对于 LLM 后端功能,200 响应几乎无法说明系统是否正常工作。
OpenAI 或 Anthropic 返回 200,可能意味着模型给出了有效响应。但也可能意味着:由于输入超出了上下文窗口,模型悄悄截断了输入,然后返回一个看似连贯、实则信息不完整的答案。又或者:响应在语法上完全正确,但因为有人在两周前修改了 system prompt,却没有运行评估,导致输出质量发生了变化。
生产环境中的 AI 原生后端所遇到的故障,不会以错误率陡增的形式出现在 Grafana 仪表盘上。它们表现为输出质量在数天内缓慢下降,持续积累,直到某位用户提出投诉。
大多数 LLM 客户端在触及模型的上下文上限时,会静默截断输入;或者抛出一个异常,随后被通用的 catch 代码块吞掉。你的功能仍在持续返回 200,但模型看到的只是一部分数据。根据被截掉的内容不同,输出质量会以一种微妙的方式下降——足以通过自动化验证,却又错误到会被细心的用户察觉。这种截断具有系统性、可预测性,却完全无法被标准监控发现。
每分钟 Token 数量限制是按 API key 执行的。在流量较低时,你永远不会触及这个限制。但当有 200 名并发用户时,某个流量高峰时段就可能让你遭遇 429,而你的重试逻辑又会将其转化为阻塞线程的级联故障。如果没有按模型、按分钟追踪累计 Token 消耗,那么在真正撞上限制之前,你不会收到任何信号。等 429 出现在错误日志里时,系统性能早已开始劣化。
输出质量取决于三件事:prompt、模型版本和输入数据分布。这三者都会随时间变化。模型提供商会在小版本中更新默认行为;工程师会在没有运行评估的情况下修改 prompt;真实用户流量还会暴露预发布环境从未遇到过的边界情况。如果没有结构化的评估流水线,prompt 回归就不会以 CI 失败的形式暴露,而会变成客户投诉。
某个客户运行着一项由 AI 驱动的文档处理功能,其后端每天需要通过两个提供商处理数百次 LLM 调用。标准监控没有显示任何异常。后来,一次代码审查发现了上下文溢出问题:输入已经被静默截断了十一天。虽然还没有用户看到足够多的劣化输出并提交工单,但对于超过特定长度的文档,这种截断一直在系统性地发生。
修复只花了两个小时:在每次 API 调用前增加 tokenizer 检查,并直接拒绝会溢出上下文窗口的请求。修复之前真正缺少的,是一个展示各端点输入 Token 数量分布的仪表盘。有了它,问题在第一天就会暴露。
第二种常见情况是提供商侧升级模型版本。某个团队通过别名锁定了 gpt-4-turbo,而不是使用精确标识符。提供商新的默认版本改变了格式化行为,而该功能依赖一种结构化 JSON 输出 schema。于是,schema 验证失败开始出现在重试日志中。由于没有 span attribute 记录每次调用具体由哪个模型版本处理,团队花了四个小时才完成诊断。
标准 APM 覆盖的是基础设施可观测性。AI 原生后端还需要在它之上增加第二层。以下四个组件可以覆盖这部分需求。
每次调用 LLM 提供商时,都应该生成一个 OpenTelemetry span,记录精确的模型标识符、输入 Token 数量、输出 Token 数量、延迟,以及提供商返回的 HTTP 状态码。这些是实现其他一切能力所需的原始数据。
// NestJS — LLM call wrapped in an OpenTelemetry span
import { trace, SpanStatusCode } from '@opentelemetry/api';
const tracer = trace.getTracer('llm-service');
async function callLLM(prompt: string, model: string): Promise<string> {
return tracer.startActiveSpan('llm.completion', async (span) => {
span.setAttributes({
'llm.model': model,
'llm.prompt_tokens': estimateTokens(prompt),
});
try {
const res = await openai.chat.completions.create({
model,
messages: [{ role: 'user', content: prompt }],
});
span.setAttributes({
'llm.completion_tokens': res.usage?.completion_tokens ?? 0,
'llm.total_tokens': res.usage?.total_tokens ?? 0,
});
span.setStatus({ code: SpanStatusCode.OK });
return res.choices[0].message.content ?? '';
} catch (err) {
span.setStatus({ code: SpanStatusCode.ERROR, message: String(err) });
throw err;
} finally {
span.end();
}
});
}
每次调用的 Token 数量和精确模型版本会通过 OTEL collector 流入 Prometheus。在此基础上,你就具备了速率限制告警和模型版本归因所需的数据。
在达到每个 API key 的 TPM 限制的 70% 时,设置一条 Prometheus 告警。这样,在触发 429 之前,你会获得两分钟的时间窗口,可以将请求排队、卸载部分流量,或者呼叫值班人员。
# Prometheus alert rule
- alert: LLMTokenBudgetHigh
expr: |
sum(rate(llm_tokens_total[1m])) by (api_key, model)
> 0.70 * on(api_key) llm_tpm_limit
for: 2m
annotations:
summary: "Token budget at {{ $value | humanizePercentage }} for {{ $labels.model }}"
70% 这个阈值并非随意设定。在 70% 时,你还有余地在系统开始劣化前作出响应。到了 90%,你已经身处级联故障之中。
锁定精确的模型标识符,而不是别名。使用 gpt-4o-2024-08-06,而不是 gpt-4o。升级时,应通过 PR 完成,并在 CI 中运行结构化评估。要像对待依赖升级一样对待模型升级:有意识地进行、接受审查,并以测试结果作为准入条件。
这是大多数 AI 原生团队本周就能完成的最低成本、最高杠杆改进。只需在模型配置中增加一行,“为什么输出质量发生了变化”这种需要四小时诊断的问题,就会变成一分钟即可完成的日志查询。
对于所有重视输出质量的功能——也就是绝大多数 LLM 功能——都应该将针对留出测试集的结构化评估纳入部署流水线。Langfuse 可以直接集成到大多数 AI 后端中,并根据评分阈值控制部署。
// Langfuse trace for evaluation tracking (TypeScript)
const langfuse = new Langfuse({ publicKey, secretKey, baseUrl });
const trace = langfuse.trace({ name: 'document-summary' });
const generation = trace.generation({
name: 'summarize',
model: 'gpt-4o-2024-08-06',
input: prompt,
});
generation.end({ output: result });
评估脚本会查询 Langfuse,获取针对测试集的最新 generation trace;如果质量指标相比基线下降超过 5%,就让部署失败。这样,prompt 回归会变成 CI 失败,而不是支持工单。
评估测试集不需要很大。根据我们的经验,二十到三十个具有代表性的输入,加上标注好的预期输出,就能捕获绝大多数回归问题。构建它只需要一天,维护工作则是每个迭代二十分钟:当生产流量暴露出新的边界情况时,将其加入测试集即可。
假设工程师此前已经在生产环境发布过 LLM 功能,那么搭建这套技术栈需要一名后端工程师投入两到三天。OpenTelemetry 的配置耗时最长。等 span 开始正常流转后,Prometheus 告警和 Langfuse 集成分别只需要几个小时。
另一种选择,是让这些故障模式静默运行一周之后才被发现。其结果是:四个小时的诊断、一次向客户道歉,以及一场事故复盘。与我们合作过的所有团队中,那些在第一次生产事故前部署这套可观测性技术栈的团队,都很庆幸自己这么做了;而那些在第一次生产事故后才部署的团队,说的也是同一句话。
标准 APM 覆盖的是传输层健康状态。三种 AI 特有的故障模式——静默上下文截断、速率限制级联和 prompt 回归——都需要专门的插桩。
每次 LLM 调用产生的 OpenTelemetry span 是整套体系的基础。每次调用的 Token 数量、精确模型版本和延迟,为其他所有能力提供了原始数据。
锁定精确的模型标识符,不要使用别名。只需修改一项配置,就能消除一整类需要四小时才能完成的调试工作。
评估流水线应该在第一次生产事故发生前就进入 CI,而不是等事故发生后再补。它的成本是两到三个工程师日;缺少它的代价,则是一周的静默劣化,以及随后而来的客户投诉。
SifrVentures 为科技公司组建专属工程团队,总部位于柏林。了解我们的工作方式|阅读博客中的更多内容
如需采取进一步措施,你可以考虑屏蔽此人和/或举报滥用行为。