第 12 章:智能体系统的 SLO¶
1. 从一个问题开始:怎样知道这个支持智能体到底健不健康¶
继续沿用同一个支持场景。
团队已经会用追踪还原事故,也已经知道重复工单可能来自糟糕的重试路径,记忆写入可能是多余的,工具适配器也可能返回含糊结果。
但在做完最初几次排障之后,接下来的问题会变成:
我们怎样不是在事故之后,而是在每天运行时,就知道系统到底健不健康?
这就是 SLO 出场的地方。
普通可用率只回答一个问题:“组件是否可用?”
对支持智能体来说,这远远不够。即使所有服务都形式上在线,系统也可能已经不健康:
- 用户等待过久;
- 智能体创建了过多不必要的工单;
- 升级率悄悄上升;
- 典型请求的成本变高;
- 安全路径开始过度打断正常场景;
- 策略门禁要么拦错动作,要么放过多余动作;
- 验证器或评分层发生漂移,开始把不安全或低质量运行误判为健康。
SLO 的价值就在于把“系统健康”从感觉变成可度量目标。
在本章里,这首先意味着一种预算语言。SLO 还不是响应流程。它定义的是,在另一个层次必须介入之前,系统还能容忍多少退化、不安全行为、操作员负担或验证器质量侵蚀。
在本书里,SLO 的角色也很具体。追踪捕获原始历史;评估产出判断;可观测性在系统尺度上保存证据;保证响应发现;而 SLO 定义的是平台在运行中允许消耗的健康预算与风险预算。
需要配套的 schema 和工程工件?
如果你需要的不只是原理说明,可以直接打开 Trace Schema 与 Event Catalog、Incident Record Schema 和 Change 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 设计的实用规则¶
如果要把最有用的规则压缩成一小组,通常就是这些:
- 从运行级结果出发,而不是从单个组件指标出发。
- 成功应该描述任务被解决,而不只是没有异常。
- 安全、成本和升级都应该算进系统健康,而不是挂在可靠性旁边。
- 延迟最好按阶段拆开,否则很难诊断。
- 只有当 SLO 会影响 rollout 和变更决策时,它们才真正有意义。
- 如果发布控制依赖验证器输出,验证器质量也应该成为系统健康的一部分。
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. 读完这一章后先做什么¶
如果你想快速检查这个支持智能体的健康模型,可以先过一遍这个短清单:
- 是否有运行级的成功定义?
- 是否能看到按阶段拆开的延迟,而不只是总延迟?
- 是否有安全 SLO,而不只是可用率?
- 是否衡量每个有效结果的成本?
- 是否能看到有多少真实负担被转移到了人身上?
- SLO 是否真的会影响发布决策?
如果连续几个答案都是否,那说明可观测性也许已经存在,但系统健康仍然没有通过质量目标被真正管理。
15. 接下来读什么¶
沿着同一条故事线,SLO 之后的下一步就是评测闭环:离线评测、在线评测、追踪分级和回归门禁。也正是在那里,可观测性变成持续改进闭环。