AI 学习笔记(二十五):LLM 紧急变更例外与风险接受治理最小实践

上一篇我们把 change freeze 和 risk window 规则落到了发布入口。
但团队在真实值班里很快会遇到一个更现实的问题:

系统已经进入 fix-only 甚至 freeze,却仍然出现“必须改”的紧急需求。

典型场景包括:

  1. 外部 provider 行为突变,当前 fallback 也开始抖动
  2. 高风险工具虽然已关闭,但有关键客户请求卡住需要临时放开
  3. 安全策略收紧后造成大面积误拦截,需要快速修补
  4. 事故止血后发现恢复策略本身有缺陷,不改会再次触发事故

很多团队的问题不在“有没有谨慎”,而在没有统一的例外机制

  1. 群里一句“先放行吧”,没有明确风险边界
  2. 批准了紧急变更,但没人记录风险接受时效
  3. 变更上线后缺乏回滚验证,结果把 freeze 变成高压期冒险发布

这篇继续生产运维主线,聚焦一个必须补齐的能力:

把紧急变更例外(emergency exception)和风险接受(risk acceptance)做成可执行、可审计、可到期回收的治理流程。

先说结论:

  1. 紧急例外不是“绕过规则”,而是规则内的受控通道
  2. 风险接受必须有时效和退出条件,不能无限期有效
  3. 所有例外都应绑定证据、审批人、回滚路径和恢复验证

1. 为什么 freeze 之后还需要“例外机制”

如果没有紧急例外机制,团队通常会走向两个极端:

  1. 绝对冻结:任何改动都不允许,导致故障扩散时无法快速止损
  2. 口头放行:每次都“特殊处理”,冻结规则名存实亡

更稳的治理方式是把 freeze 看成“默认更保守”,并保留一条严格受限的例外通道,用来处理不改更危险的情况。

判断是否可进入例外通道,可以先问三个问题:

  1. 当前问题是否正在扩大用户影响或安全风险
  2. 如果不在当前窗口执行,是否会造成更高代价
  3. 是否存在可验证的低风险替代方案

只有当答案满足“改动风险小于不改风险”,才有资格进入紧急例外审批。

2. 紧急变更例外的最小分级

建议先做 3 级分层,避免所有紧急变更都走同一套流程。

1) E1 - Stability Hotfix

适用:稳定性止血、降级、回退、只读化收敛。
风险:低到中。
要求:值班负责人 + 平台负责人双人确认。

2) E2 - Controlled Capability Restore

适用:为恢复关键业务而短时恢复部分能力(如受限工具白名单)。
风险:中到高。
要求:业务 owner、值班负责人、安全/平台三方确认,必须限时。

3) E3 - Critical Security / Compliance Override

适用:涉及安全、合规或重大客户承诺的紧急修复。
风险:高。
要求:更高层级审批 + 全量审计记录 + 明确到期时间。

这套分级重点不是“复杂”,而是让每次例外都能对应审批强度和回滚深度。

3. 风险接受记录必须包含的 8 个字段

风险接受(risk acceptance)如果只写一句“同意上线”,后续几乎无法追责和复盘。
最小可执行记录建议固定为 8 个字段:

  1. exception_id
  2. severity(E1/E2/E3)
  3. change_scope(模型、prompt、tool、route、policy)
  4. accepted_risk(明确接受的风险是什么)
  5. rollback_plan(失败后如何在 N 分钟内回退)
  6. verification_gate(上线后通过什么指标判定成功)
  7. expires_at(到期时间)
  8. approvers(审批人及时间)

其中 expires_at 最关键。
没有到期机制的风险接受,最终会变成永久例外,侵蚀整个治理体系。

4. 一个可直接落地的审批与执行流程

下面这条流程足够小,但能覆盖多数 LLM 生产场景。

Step 1: 提交例外申请

申请单必须回答:

  1. 现在不改会发生什么
  2. 这次改动范围和副作用边界是什么
  3. 回滚动作是谁执行、多久完成

Step 2: 预检自动校验

在人工审批前,先跑机器预检:

  1. 当前是否处于 freeze/fix-only
  2. 变更类型是否允许进入例外通道
  3. 是否附带 rollback 与验证门槛

预检未通过直接拒绝,避免人工审批被无效请求打扰。

Step 3: 人工审批

按 E1/E2/E3 分级路由审批人。
审批必须显式写出“接受了哪类风险”,不是仅点通过。

Step 4: 限流上线 + 观察窗口

即使是紧急例外,也要遵守:

  1. 先小流量
  2. 观察窗口内禁并发高风险发布
  3. 指标触发阈值立即自动回滚

Step 5: 到期回收

到达 expires_at 后,系统自动要求:

  1. 关闭例外
  2. 恢复默认策略
  3. 补齐 postmortem action 或正式变更方案

5. 最小策略示例:例外不是自由通行证

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
emergency_exception_policy:
modes:
fix_only:
allow_exception_levels:
- E1
- E2
freeze:
allow_exception_levels:
- E1
- E3
required_fields:
- exception_id
- severity
- change_scope
- accepted_risk
- rollback_plan
- verification_gate
- expires_at
- approvers
rollout_constraints:
max_initial_traffic_ratio: 0.05
observe_minutes: 30
block_parallel_high_risk_changes: true
auto_rollback_if:
error_rate_increase_gt: 0.03
p95_latency_increase_gt: 0.25
risky_write_event_gt: 0
lifecycle:
enforce_expiration: true
require_postmortem_link_on_close: true

重点是三件事:

  1. 例外级别受当前运行模式约束
  2. 上线后仍受流量和指标门槛约束
  3. 所有例外都必须在到期后回收

6. 服务层最小实现示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
function validateExceptionRequest(input) {
const required = [
"exceptionId",
"severity",
"changeScope",
"acceptedRisk",
"rollbackPlan",
"verificationGate",
"expiresAt",
"approvers",
];

const missing = required.filter((k) => !input[k]);
if (missing.length > 0) {
return { pass: false, reason: `missing-fields:${missing.join(",")}` };
}

if (new Date(input.expiresAt).getTime() <= Date.now()) {
return { pass: false, reason: "invalid-expiration" };
}

return { pass: true, reason: "request-valid" };
}

function canExecuteException({ mode, severity }) {
if (mode === "freeze") {
return severity === "E1" || severity === "E3";
}

if (mode === "fix-only") {
return severity === "E1" || severity === "E2";
}

return true;
}

function shouldAutoRollback(metrics, threshold) {
if (metrics.errorRateIncrease > threshold.errorRateIncreaseGt) return true;
if (metrics.p95LatencyIncrease > threshold.p95LatencyIncreaseGt) return true;
if (metrics.riskyWriteEvents > threshold.riskyWriteEventGt) return true;
return false;
}

这段逻辑只解决最关键的约束:

  1. 资料不全不能申请
  2. 运行模式不匹配不能执行
  3. 指标恶化触发自动回滚

7. 与前面治理链路怎么衔接

紧急例外机制不应孤立存在,建议接入前文的治理链路:

  1. change freeze / risk window 决定是否需要进入例外流程
  2. release gate / canary / rollback 负责上线期风控
  3. incident evidence / postmortem action 负责关闭例外后的追踪
  4. on-call runbook 负责谁提单、谁审批、谁执行回滚

这样例外就不会变成“临时拍板”,而是一条完整可审计的工程闭环。

8. 一周落地建议

  1. Day 1
    固定 E1/E2/E3 分级与审批矩阵
  2. Day 2
    在发布入口增加例外申请字段校验
  3. Day 3
    接入流量限制、观察窗口、自动回滚阈值
  4. Day 4
    接入到期提醒和自动回收检查
  5. Day 5
    用一次 Game Day 演练验证:申请、审批、执行、回滚、收尾是否都可跑通

总结

真正有用的紧急例外治理,不是把 freeze 打洞,而是把“不得不发”的动作放进更严格、可回收、可审计的控制框架。
如果你本周只能先做一件事,我建议优先完成:

为每次紧急例外强制记录 accepted_risk + rollback_plan + expires_at,并把到期回收做成自动检查。

这样风险接受才是“临时且可控”,而不是“默认且永久”。

参考资料

本文永久链接: https://www.mulianju.com/learning-notes/ai-learning-notes-llm-emergency-change-exception-risk-acceptance-governance-minimal-practice/