Skip to content

生产故障模式与排查顺序 ​

学习目标 ​

  • 能把 Agent 生产故障按模型、循环、工具、数据、基础设施和安全边界分类。
  • 能使用 Trace、指标、事件和版本信息按证据顺序排查,而不是先改提示词。
  • 能在事故中执行止损、禁用能力、回滚和人工接管。
  • 能把修复样本加入回归门禁,避免同一问题反复出现。

前置知识 ​

需要理解本章前六篇以及第 05 章的 Recovery、Checkpoint 和数据隔离。本文以“先保护用户和数据,再恢复服务,再解释根因”为生产排查主线。

核心知识点 ​

Agent 的故障面 ​

Agent 的最终失败经常是多层故障叠加,不要只把它归因于“模型变笨”。常见类别如下:

  • 模型/供应商:限流、超时、上下文截断、模型版本变化、结构化输出不符合契约。
  • 循环/运行时:停止条件缺失、重复工具、并行竞态、取消丢失、状态版本冲突。
  • 工具/依赖:Schema 不兼容、外部 API 失败、权限拒绝、非幂等重试。
  • 数据/记忆:检索为空、索引过期、租户串数据、上下文摘要丢失关键信息。
  • 基础设施:进程崩溃、队列堆积、磁盘满、网络/DNS、缓存或数据库异常。
  • 安全/策略:Prompt Injection、秘密外泄、沙箱逃逸迹象、审计断裂或审批绕过。

分类不是为了贴标签,而是为了决定证据和止损动作。安全类故障优先隔离,模型类故障可能先降级,数据类故障可能先冻结写入。

用户影响与严重度 ​

先问“谁受到什么影响”,再问“根因是什么”。至少记录:

  • 影响租户、用户、运行和功能范围。
  • 是错误答案、延迟、重复副作用、数据泄露还是服务不可用。
  • 是否仍在扩大,是否需要停止队列或撤销能力。
  • 是否有可接受的降级路径,例如只读、人工处理或旧模型。

一个低比例的密钥泄露可能比大比例的普通超时更严重;严重度不应只由错误百分比决定。

证据排查顺序 ​

推荐顺序:

  1. 事件时间线和告警:确定开始时间、范围和仍否持续。
  2. trace_id/run_id:打开一条成功和一条失败轨迹对比。
  3. Span/Event:查模型、工具、权限、重试、回填和停止边界。
  4. 版本与配置:模型、提示、工具 Schema、策略、数据集、部署和依赖。
  5. 依赖指标:P95、错误率、队列、资源、供应商状态。
  6. 原始请求和输出:仅在有权限且脱敏后查看。

不要一开始就让模型再次运行同一危险任务,也不要把一次日志猜测当作根因。每个假设都要有可以证伪的证据。

止损、回滚和降级 ​

止损动作按影响排序:

  • 暂停高风险工具或外发能力。
  • 停止继续消费危险队列,保留任务和检查点。
  • 切换到旧模型、只读工具或人工流程。
  • 回滚代码、配置、提示、模型路由或数据索引。
  • 轮换可能暴露的凭据,隔离受影响租户。

回滚前要确认兼容性和未完成任务的状态;直接回滚可能让新旧 Schema、数据库和检查点不兼容。每个止损动作也要有审计记录和负责人。

修复后的回归门禁 ​

事故样本必须进入 Dataset,包含原始输入、工具环境、关键轨迹、期望安全行为和脱敏后的证据。修复后至少检查:

  • 原始事故是否复现并通过。
  • 相邻风险样本是否未被破坏。
  • 工程指标是否在预算内。
  • 安全和权限硬门禁是否仍然通过。
  • 灰度和观测窗口是否足够长。

“线上不报错”不是修复完成;要有可重复的测试和发布记录。

生产排查流程 ​

图中安全分支优先于普通分类;排查和修复完成后必须经过回放与门禁,不能因为告警消失就直接关闭事故。

一个最小的故障分流器 ​

用途:下面的例子把首条证据映射到排查方向,并为安全故障给出立即隔离动作。它不是自动化事故处理器,真实系统仍需要人工确认和权限控制。

python
from dataclasses import dataclass


@dataclass(frozen=True)
class Incident:
    symptom: str
    error_rate: float
    security_signal: bool = False


def triage(incident):
    if incident.security_signal:
        return {
            "severity": "critical",
            "first_action": "disable_high_risk_capabilities",
            "evidence": ["audit_events", "trace", "egress_logs"],
        }
    if "timeout" in incident.symptom or "rate_limit" in incident.symptom:
        return {
            "severity": "high" if incident.error_rate > 0.2 else "medium",
            "first_action": "check_provider_and_queue",
            "evidence": ["model_spans", "dependency_metrics", "queue_depth"],
        }
    if "wrong_tool" in incident.symptom:
        return {
            "severity": "high",
            "first_action": "freeze_tool_and_replay",
            "evidence": ["tool_calls", "policy_events", "dataset_case"],
        }
    return {
        "severity": "medium",
        "first_action": "compare_success_and_failure_traces",
        "evidence": ["trace", "versions", "config"],
    }


incident = Incident("wrong_tool", error_rate=0.01)
print(triage(incident))
# 输出:{'severity': 'high', 'first_action': 'freeze_tool_and_replay', 'evidence': ['tool_calls', 'policy_events', 'dataset_case']}

安全信号为 True 时,即使 error_rate 很低,也应先隔离高风险能力。分流器给出排查入口,不应绕过人工批准去自动轮换所有凭据或删除任务。

常见故障模式与第一问 ​

无限循环或重复工具 ​

先查停止条件、step budget、相同 tool_call_id、状态版本和重试策略。处理方式通常是停止当前 Run、保留轨迹、去重或恢复检查点,而不是继续增加模型温度。

延迟突然升高 ​

比较模型 Span、工具 Span、队列等待和回填时间。若只有模型耗时增加,查看供应商、上下文 token 和限流;若工具耗时增加,查看依赖和并发。不要只看端到端平均值,应看分位数和尾延迟。

答案看似正确但数据不对 ​

检查检索版本、租户过滤、工具返回和上下文摘要,再看模型是否超出证据。把错误样本加入事实断言和来源检查,避免只调措辞。

发生秘密外泄 ​

先暂停外发和高风险工具,隔离受影响租户,轮换凭据并保留审计;随后查来源、上下文、缓存、Trace 和第三方请求。不要先删除日志,删除会破坏取证。

发布后成功率下降 ​

对比 candidate/baseline 的模型、提示、工具 Schema、策略、依赖和数据版本,按标签分桶看变化。若硬门禁失败,回滚或降级;若只是质量波动,先扩充样本和人工复核。

源码阅读锚点 ​

  • OpenTelemetry:查看异常、状态、事件和上下文如何被导出,确认观测失败是否会影响业务执行。
  • OpenAI Agents SDK:对照 Runner 的错误、取消、工具和 tracing 事件,寻找恢复边界。
  • LangGraph:重点看 checkpoint、interrupt、retry 和 durable execution 的故障恢复语义。
  • DeepSeek Harness:从 Driver、Session、Plugin、Hook 和事件流追一条失败任务,找出止损和人工接管入口。

易混点 ​

  • 告警恢复不等于事故结束:还要完成影响确认、回归和复盘。
  • 错误率低不等于风险低:一次越权或泄露可能是严重事故。
  • 回滚代码不等于回滚副作用:外部写入需要补偿、撤销或人工处理。
  • 重放不等于复现:如果模型、工具、数据和时间没固定,重放结果不能直接比较。
  • 修改提示词不等于修复权限:权限应在运行时和执行器边界控制。

课后小问(含解析) ​

问题 1:生产出现一次数据泄露,第一步是什么? ​

答案:先止损和隔离外发能力,再保留审计和轨迹证据。

解析:继续运行可能扩大泄露。应暂停高风险能力、撤销租约、隔离范围、轮换凭据,并由人工确认后续取证和通知策略。

问题 2:为什么排查要同时看成功 Trace? ​

答案:成功 Trace 提供对照组,能识别差异发生在哪一层。

解析:单条失败日志可能缺字段或包含噪声。对比同类成功和失败的模型、工具、状态、版本和时间,能缩小假设范围。

问题 3:事故样本修复后为什么还要加到回归 Dataset? ​

答案:否则修复无法持续验证,下一次发布可能再次引入同一故障。

解析:事故样本是最有价值的真实边界案例。脱敏后固定输入、环境和期望安全行为,才能形成长期门禁。

本节小结 ​

生产排查先确认影响和安全风险,再用 Trace、Span、Event、版本和依赖指标建立证据链。止损、降级、回滚和人工接管优先保护数据和用户;修复后要回放事故样本、运行分层门禁并灰度观察。根因分析不是猜模型,而是定位状态、工具、数据、基础设施和策略的具体边界。

快速回顾 ​

  • 能按故障类别选择第一批证据。
  • 能解释为什么安全事故先隔离,普通超时先看依赖和队列。
  • 能把事故样本沉淀为回归门禁。
  • 第 10 章至此把评测、观测、Guardrail、安全和生产排查串成一个闭环。

官方依据 ​