跳转至

第 12 章:智能体系统的 SLO

1. 从一个问题开始:怎样知道这个支持智能体到底健不健康

继续沿用同一个支持场景。

团队已经会用追踪还原事故,也已经知道重复工单可能来自糟糕的重试路径,记忆写入可能是多余的,工具适配器也可能返回含糊结果。

但在做完最初几次排障之后,接下来的问题会变成:

我们怎样不是在事故之后,而是在每天运行时,就知道系统到底健不健康?

这就是 SLO 出场的地方。

普通可用率只回答一个问题:“组件是否可用?”

对支持智能体来说,这远远不够。即使所有服务都形式上在线,系统也可能已经不健康:

  • 用户等待过久;
  • 智能体创建了过多不必要的工单;
  • 升级率悄悄上升;
  • 典型请求的成本变高;
  • 安全路径开始过度打断正常场景;
  • 策略门禁要么拦错动作,要么放过多余动作;
  • 验证器或评分层发生漂移,开始把不安全或低质量运行误判为健康。

SLO 的价值就在于把“系统健康”从感觉变成可度量目标。

在本章里,这首先意味着一种预算语言。SLO 还不是响应流程。它定义的是,在另一个层次必须介入之前,系统还能容忍多少退化、不安全行为、操作员负担或验证器质量侵蚀。

在本书里,SLO 的角色也很具体。追踪捕获原始历史;评估产出判断;可观测性在系统尺度上保存证据;保证响应发现;而 SLO 定义的是平台在运行中允许消耗的健康预算与风险预算。

需要配套的 schema 和工程工件?

如果你需要的不只是原理说明,可以直接打开 Trace Schema 与 Event CatalogIncident Record SchemaChange Review 与 Rollout Gate Schema

2. SLO 应该描述一次运行的行为,而不是单个部件的健康度

一个很常见的错误是这样:

  • 模型响应很快;
  • vector store 可用;
  • 工单 API 在线;
  • 适配器很少报错。

这些都很有用,但没有一个回答了真正的问题:

用户是否拿到了正确、安全而且及时的结果?

对这个支持智能体来说,重要的不是某个库的可用率,而是整次运行的结果:

  • 状态是否被正确找回;
  • 工单是否只在真正需要时才创建;
  • 审批路径是否在该触发时触发;
  • 副作用是否没有重复、没有落入不明状态;
  • 用户是否没有被无意义地丢给人工。

因此,智能体系统的 SLO 更适合围绕运行级行为来构建。

这也是本章最清晰的边界:SLO 并不试图解释每一个失败,也不试图证明每一个控制。它们定义的是,在变更、rollout 或响应必须收紧之前,平台到底还能容忍多少退化、延迟、不安全行为、成本增长或人工负担。

3. 对这个支持智能体来说,真正重要的是五组 SLO

在实践里,生产级的智能体系统通常只需要从一个紧凑集合开始:

  • 成功 SLO;
  • 延迟 SLO;
  • 安全 SLO;
  • 成本 SLO;
  • 升级 SLO。

这已经足够让团队看见系统不只是“活着”,还是否:

  • 真正有用;
  • 正在变慢;
  • 正在磨薄安全边界;
  • 正在变贵;
  • 正在把负担转移给人。

不要试图一开始测量一切。先抓住那些真正影响用户结果和运行稳定性的指标。

4. 成功 SLO 应该贴近任务,而不是贴近 HTTP 200

这里最危险的陷阱很简单:只要一次运行没崩,就把它当成功。

但对支持智能体来说,一次运行完全可能形式上“成功”,实际上却很差:

  • 答复返回了,但并没有帮到用户;
  • 状态在缺乏足够依据时就被返回;
  • 本该安全追问时,系统却直接创建了工单;
  • 工单被创建了两次;
  • 系统只返回了一段文本,而没有完成应该完成的动作。

因此,成功 SLO 更应该绑定在这些东西上:

  • 状态被正确找到并传达;
  • 工单只被创建一次,而且上下文正确;
  • 请求在该停止或转人工时被安全停止或转交;
  • 用户在没有不必要升级的前提下拿到了有用结果。

对支持智能体来说,成功不应该等于“没有异常”,而应该等于“任务真的解决了”。

贯穿案例:重复工单的 SLO

在支持分诊案例里,成功 SLO 应该把重复工单算作结果失败,而不是“创建成功”。更好的目标应该贴近任务:卡住的请求只产生一张上下文正确的工单,而 side_effect_unknown 不会以盲目重复结束。这样,SLO 保护的是用户和操作员,而不只是一个绿色 HTTP 状态。

5. 延迟 SLO 应该按阶段拆开看

如果你只看整体运行 p95,你知道系统变慢了,但不知道为什么。

对同一个支持智能体来说,延迟可能出现在完全不同的地方:

  • 检索取回请求历史变慢;
  • 提示变胖以后,模型思考更久;
  • 工具适配器在外部工单系统上等待太久;
  • 审批路径卡在人工环节;
  • background queue 开始压住新的运行。

所以,除了端到端延迟,更有用的是分阶段看:

  • run p95/p99;
  • 检索延迟;
  • 模型 span 延迟;
  • 工具执行延迟;
  • 审批等待;
  • queue wait time。

这样延迟 SLO 才不只是漂亮数字,而会变成诊断工具。

但它仍然是预算工具,而不是响应循环。延迟 SLO 告诉团队,在必须采取行动之前,还能容忍多少变慢。后面的保证章节才负责在这个容忍度被突破之后处理遏制、负责人归属与响应。

5.1. 延迟预算应该从用户耐心开始算,而不是从模型速度开始算

这里还有一个很值得保留的产品问题:延迟预算不应该从模型基准出发,而应该从用户究竟愿意等多久出发。

如果用户在 8 到 10 秒左右就开始流失,那么一个平均响应要 25 秒的智能体,即使质量指标看上去不错,也依然是糟糕设计。

这也是为什么,除了想着"把所有东西都加速",更有用的思路往往是路由流水线:

  • 给常见、简单场景一条快速路径;
  • 只有模糊、高风险或异常复杂的运行才走更慢的推理路径。

落到工程上,这通常意味着:

  • 常规场景用更少上下文和更便宜的模型路径;
  • 更昂贵的模型路由只留给真正值得的场景;
  • 简单场景里减少不必要的工具跳转;
  • 明确规定到底哪些任务类别值得长时间深思路径。

这样延迟 SLO 就不再只是平台指标,而会开始成为产品匹配度的一部分。

6. 安全 SLO 必须和可靠性放在一起

在智能体系统里,安全不能被放成一个独立的安全附录。对生产系统来说,它本身就是系统健康的一部分。

对这个支持智能体来说,至少值得跟踪:

  • 没有策略违规的运行比例;
  • 没有跨租户检索的运行比例;
  • 没有未知副作用的写入动作比例;
  • 高风险动作的审批覆盖率;
  • 没有隐私敏感外发事故的运行比例。

这在重复工单或不安全记忆写入之后尤其重要:如果安全从不进入 SLO,团队很快又会只按速度和便利性优化系统。

随着评估与验证器层成为发布纪律的一部分,把它们的质量也纳入健康模型会越来越有价值。如果运行时行为看起来“没问题”只是因为验证器变得更嘈杂或更轻信,那系统其实并不健康。

智能体系统的健康几乎总是多维的

flowchart LR
    A["支持智能体健康度"] --> B["成功"]
    A --> C["延迟"]
    A --> D["安全"]
    A --> E["成本"]
    A --> F["升级"]

7. 成本 SLO 能在事故前抓住静默退化

智能体系统有个很不舒服的特点:它可能在“还能工作”的同时,经济性已经悄悄塌掉。

在这个支持场景里,这通常会表现成:

  • 检索往提示里塞进太多上下文;
  • 模型更频繁地调用工具却没有带来收益;
  • 规划器多走了几步;
  • 重试把一次运行越滚越大;
  • 记忆摘要吞掉了过多预算。

因此,成本 SLO 至少值得看:

  • 每次成功运行的成本;
  • 每次运行的 tokens;
  • 每次运行的工具调用数;
  • 高成本模型的使用比例。

否则团队会很晚才发现退化:那时智能体也许还“在帮忙”,但成本已经显著变高。

8. 升级 SLO 保护的是系统周围的人

人在环路不是一个免费的安全网。

如果支持智能体:

  • 过于频繁地请求审批;
  • 过于频繁地落入人工补救;
  • 过于频繁地把决定扔给人;

它也许看上去安全,但实际上只是把混乱转移给操作员。

因此,值得跟踪:

  • 升级率;
  • 高风险流程的审批率;
  • 人类决策的中位耗时;
  • 无需人工干预即可完成的运行比例。

对支持智能体来说,这一点很关键:如果升级率太高,自动化很快就会沦为摆设。

9. SLO 设计的实用规则

如果要把最有用的规则压缩成一小组,通常就是这些:

  1. 从运行级结果出发,而不是从单个组件指标出发。
  2. 成功应该描述任务被解决,而不只是没有异常。
  3. 安全、成本和升级都应该算进系统健康,而不是挂在可靠性旁边。
  4. 延迟最好按阶段拆开,否则很难诊断。
  5. 只有当 SLO 会影响 rollout 和变更决策时,它们才真正有意义。
  6. 如果发布控制依赖验证器输出,验证器质量也应该成为系统健康的一部分。

10. 一个支持智能体的 SLO 策略示例

这里重要的不是“标准答案”,而是明确的纪律:

slo:
  success:
    successful_run_rate: ">= 97%"
  latency:
    run_p95_ms: "<= 12000"
    tool_span_p95_ms: "<= 2500"
  safety:
    policy_violation_rate: "< 0.2%"
    unknown_side_effect_rate: "< 0.05%"
  cost:
    avg_tokens_per_run: "<= 18000"
    avg_cost_per_successful_run_usd: "<= 0.12"
  escalation:
    manual_intervention_rate: "< 8%"
  verifier:
    false_positive_rate_high_risk: "< 1%"
    failure_attribution_agreement_rate: ">= 95%"

重点不在具体阈值,而在于团队提前说清楚:什么才算系统的正常状态。

正是这种约定,才把指标变成运营约束。没有这一步,系统也许仍然在被测量,但还没有通过明确的健康预算与风险预算被治理。

这也正是它与保证的清晰边界。SLO 说明平台还能容忍多少痛点、漂移、成本、不安全行为或人工负担;保证决定的是,当这些预算不再被尊重时,接下来该怎么做。

现在,这种约定也可以把验证器层纳入其中,尤其是在 rollout、保证或事故后分类依赖它判断结果的时候。

11. 一个简单的健康分类示例

下面这个小骨架展示的是一个核心思路:一次运行应该同时在多个维度上被判断,而不是只看单一指标。

from dataclasses import dataclass


@dataclass
class RunHealth:
    successful: bool
    latency_ms: int
    policy_violated: bool
    cost_usd: float


def classify_run_health(run: RunHealth) -> str:
    if run.policy_violated:
        return "safety_failure"
    if not run.successful:
        return "task_failure"
    if run.latency_ms > 12_000:
        return "slow_success"
    if run.cost_usd > 0.12:
        return "expensive_success"
    return "healthy"

这个模型很简单,但它有价值,恰恰因为它不会把运行质量藏在形式上的“成功”后面。

12. SLO 文化最常见的崩坏点

这里的问题非常重复:

  • 成功用 HTTP status 来算;
  • 延迟只在模型调用层可见;
  • 安全和可靠性分家;
  • 成本从不进入健康模型;
  • 人工升级不被当成系统健康的一部分;
  • 验证器质量被默认假定,而不是被测量;
  • SLO 只挂在仪表盘上,却不影响 rollout。

一旦如此,SLO 就会变成装饰。团队看到了数字,但并没有通过这些数字来控制平台。

这时平台也许已经有仪表盘,但还没有真正的健康与预算层。

13. 给 SLO 纪律做一次快速成熟度测试

团队不应该只因为在看 uptime、p95 延迟和几个仪表盘告警,就觉得自己已经有了健康的服务管理。

更高的标准应该是:

  • 健康是在运行级上定义的,而不只是组件级;
  • 安全、成本和升级被当成一等健康维度;
  • 成功意味着任务真的被解决,而不只是没有异常;
  • SLO 会影响 rollout、rollback 和变更决策;
  • 人不会被系统悄悄转移过来的负担压垮。

如果这些条件大多不成立,那团队也许已经有指标,但还没有真正适用于智能体系统的 SLO 纪律。

14. 读完这一章后先做什么

如果你想快速检查这个支持智能体的健康模型,可以先过一遍这个短清单:

  1. 是否有运行级的成功定义?
  2. 是否能看到按阶段拆开的延迟,而不只是总延迟?
  3. 是否有安全 SLO,而不只是可用率?
  4. 是否衡量每个有效结果的成本?
  5. 是否能看到有多少真实负担被转移到了人身上?
  6. SLO 是否真的会影响发布决策?

如果连续几个答案都是否,那说明可观测性也许已经存在,但系统健康仍然没有通过质量目标被真正管理。

15. 接下来读什么

沿着同一条故事线,SLO 之后的下一步就是评测闭环:离线评测、在线评测、追踪分级和回归门禁。也正是在那里,可观测性变成持续改进闭环。

16. 值得配套阅读的参考页