---
title: 发布验收、灰度与恢复
url: https://doc.liz6.com/ai/04-evaluation-and-production/03-release-and-recovery
locale: zh
area: ai
tags:
- 大模型与 Agent
- 评估与生产
date: 2026-06-30
modified: 2026-09-10
description: 发布的是代码、模型、提示、工具、权限和索引共同构成的版本。将前面的检查组织成对应这个版本的证据，再决定灰度、扩大流量或停止。本文负责整合验收流程，具体公式和执行边界回到各专题查阅。
---

# 发布验收、灰度与恢复

发布的是代码、模型、提示、工具、权限和索引共同构成的版本。将前面的检查组织成对应这个版本的证据，再决定灰度、扩大流量或停止。本文负责整合验收流程，具体公式和执行边界回到各专题查阅。

## 固定候选版本与任务边界

先写清系统完成什么，以及怎样确认完成。查询型助手可以要求答案有可核验来源；执行型助手还需要检查实际业务状态。模型返回结束、HTTP 200 或工具没有抛异常，都不能独自证明任务成功。人工处理也是一个明确的结果分支，应统计其比例和成本，不能静默算作自动成功。

候选版本至少需要能够定位应用代码、模型标识与参数、提示模板、工具 schema 和权限策略。使用检索时还要记录文档快照、分块与嵌入配置、索引版本；使用持久状态时要记录状态格式与迁移规则。不要只给 prompt 一个版本号，却让其余依赖在验证后悄悄变化。对于只能使用浮动模型别名的服务，记录实际可获得的版本信息与验证时间，并承认供应方变化会降低复现能力。

<svg viewBox="0 0 760 331.6076965332031" xmlns="http://www.w3.org/2000/svg" role="img" aria-label="上线的是一组版本，放行依据必须属于这一组版本" style="max-width:100%;height:auto" font-family="Source Han Sans CN,Microsoft YaHei,sans-serif">
<defs><marker id="ai-release-evidence-arrow" markerWidth="8" markerHeight="8" refX="7" refY="4" orient="auto"><path d="M0,0 L8,4 L0,8 Z" fill="#64748b"></path></marker></defs>
<rect width="760" height="331.6076965332031" rx="12" fill="#f8fafc"></rect>


<g transform="translate(0 0)"><rect x="30" y="85" width="190" height="80" rx="8" fill="#e0e7ff" stroke="#c7d2fe"></rect><text x="125.0" y="122.0" font-size="15" fill="#1e293b" text-anchor="middle" font-weight="600">候选版本</text><text x="125.0" y="144.0" font-size="12" fill="#475569" text-anchor="middle" font-weight="400">模型、提示、工具、索引</text><rect x="285" y="85" width="190" height="80" rx="8" fill="#e0e7ff" stroke="#c7d2fe"></rect><text x="380.0" y="122.0" font-size="15" fill="#1e293b" text-anchor="middle" font-weight="600">验证证据</text><text x="380.0" y="144.0" font-size="12" fill="#475569" text-anchor="middle" font-weight="400">质量、权限、恢复、容量</text><rect x="540" y="85" width="190" height="80" rx="8" fill="#e0e7ff" stroke="#c7d2fe"></rect><text x="635.0" y="122.0" font-size="15" fill="#1e293b" text-anchor="middle" font-weight="600">有限放量</text><text x="635.0" y="144.0" font-size="12" fill="#475569" text-anchor="middle" font-weight="400">同版本观察与退回</text><line x1="220" y1="125" x2="280" y2="125" stroke="#64748b" stroke-width="1.8" marker-end="url(#ai-release-evidence-arrow)"></line><line x1="475" y1="125" x2="535" y2="125" stroke="#64748b" stroke-width="1.8" marker-end="url(#ai-release-evidence-arrow)"></line><rect x="180" y="225" width="400" height="50" rx="8" fill="#fef3c7" stroke="#c7d2fe"></rect><text x="380.0" y="255.0" font-size="15" fill="#1e293b" text-anchor="middle" font-weight="600">配置变更 → 判断哪些证据失效</text><line x1="635" y1="170" x2="635" y2="250" stroke="#64748b" stroke-width="1.8"></line><line x1="635" y1="250" x2="585" y2="250" stroke="#64748b" stroke-width="1.8" marker-end="url(#ai-release-evidence-arrow)"></line><line x1="175" y1="250" x2="125" y2="250" stroke="#64748b" stroke-width="1.8"></line><line x1="125" y1="250" x2="125" y2="170" stroke="#64748b" stroke-width="1.8" marker-end="url(#ai-release-evidence-arrow)"></line><text x="28" y="306" font-size="13" fill="#475569" text-anchor="start" font-weight="400">离线通过不等于线上无风险；回退版本也不能撤销已经发生的业务动作。</text></g><text x="24" y="29" font-size="19" fill="#0f172a" text-anchor="start" font-weight="700"><tspan x="24" dy="0">上线的是一组版本，放行依据必须属于这一组版本</tspan></text>
</svg>

相关解释：[Agent 循环](/ai/03-agent-systems/01-agent-loop.md)、[多 Agent 编排](/ai/03-agent-systems/06-multi-agent-orchestration.md)。

## 发布前检查表

每一项记录负责人、候选版本、验证时间、证据位置和结论。未执行与失败分开记录，但两者都不能冒充通过；不适用项写明原因，不能仅删除勾选框。

### 质量与模型配置

| 核对项 | 应留下的证据 | 不能替代它的信号 |
|---|---|---|
| [ ] 定义任务成功与失败 | 输出要求、业务后置条件、拒绝/转人工规则 | 模型自述“已完成” |
| [ ] 覆盖代表性任务与边界 | 固定评估集，按难度、语言、工具类型等分组结果 | 单条演示或总体平均分 |
| [ ] 保留独立验收集 | 调参集与验收集的划分、重复试验策略 | 在同一批题上反复调到满分 |
| [ ] 校准评分方法 | 程序检查覆盖范围、人工复核、裁判误判样例 | “用了程序评分所以一定客观” |
| [ ] 核对模型能力与参数 | 所选端点实际支持的参数、停止/拒绝/截断分支验证 | 给所有模型统一设置 high effort |
| [ ] 验证结构与业务约束 | schema 校验及数量、状态、资源归属等负例 | JSON 能解析 |

评估的“观察什么”与“谁来评分”是两个维度：业务结果既可由程序检查，也可由人工或模型裁判评估，不能把 outcome 排在程序评分后面当成低级方法。一次成功也不能说明重复执行稳定，应说明每个任务的试验次数与聚合口径。[Anthropic：Agent 评估](https://www.anthropic.com/engineering/demystifying-evals-for-ai-agents)

采样、推理预算和输出上限作用不同。不要把 temperature 机械翻译成 effort，也不要假定所有新模型都取消采样参数。相关原理见 [Token 与采样](/ai/01-model-foundations/01-tokens-and-sampling.md)、[推理与 thinking](/ai/01-model-foundations/04-reasoning-and-verification.md)、[评估与可观测](/ai/04-evaluation-and-production/01-evaluation-and-observability.md)、[结构化输出](/ai/02-context-and-interfaces/01-prompt-and-output-contracts.md)。

### 上下文、知识与状态

| 核对项 | 应留下的证据 | 典型失败分支 |
|---|---|---|
| [ ] 给完整请求留预算 | 工具定义、检索材料、历史与输出预留的总预算 | 单篇文档能放下，完整请求超限 |
| [ ] 验证检索与答案两层 | 候选召回、排序、引用对应及无证据时行为 | 答案通顺但引用不支持结论 |
| [ ] 检查版本与权限变化 | 文档更新、删除、撤权后的索引及缓存测试 | 原文已撤权，旧片段仍返回 |
| [ ] 验证会话恢复 | 已完成步骤、待确认结果与外部对象 ID 的恢复记录 | 恢复后把未知结果当未执行 |
| [ ] 验证状态兼容性 | 旧状态读取、新状态写入与回退兼容范围 | 回退应用无法读新 checkpoint |

详见 [上下文工程](/ai/02-context-and-interfaces/02-context-engineering.md)、[RAG](/ai/02-context-and-interfaces/03-retrieval-and-evidence.md)、[记忆与状态](/ai/03-agent-systems/04-memory-and-recovery.md)。模型选型中的权重、KV 与硬件预算见 [模型架构](/ai/01-model-foundations/03-inference-and-kv-cache.md)。

### 执行权限、可靠性与观测

| 核对项 | 应留下的证据 | 典型失败分支 |
|---|---|---|
| [ ] 执行器独立核验授权 | 跨用户/项目、伪造主体与多余参数的拒绝测试 | 模型传入 approved 就放行 |
| [ ] 限制通用工具能力 | 文件边界、命令参数、网络出站等隔离验证 | 命令名合法却能任意写文件 |
| [ ] 检查注入与敏感数据流 | 合成注入用例、日志脱敏、输出端处理 | 工具资料被提升为可信指令 |
| [ ] 区分超时与业务失败 | 未知写结果的查询、去重与恢复记录 | 超时后重新执行已经成功的动作 |
| [ ] 约束重试和排队 | 总 deadline、最大尝试、有界队列及过载策略 | SDK 与外层重试叠加放大 |
| [ ] 观察完整任务 | 关联 ID、关键步骤耗时、任务结果与完整费用 | 只统计模型响应时间和单次 token |
| [ ] 验证故障分支 | 限流、工具异常、断流、截断、部分批次失败 | 流式请求建立成功就算完成 |

已有任务授权应由系统沿操作链传递，需要额外确认的动作再按具体策略处理；逐次人工点击并不能替代资源权限和幂等机制。详见 [安全与防护](/ai/03-agent-systems/05-authority-and-tool-boundaries.md)、[成本、性能与可靠性](/ai/04-evaluation-and-production/02-cost-performance-and-reliability.md)。接入协议与工具发现的边界见 [MCP 与 Skills](/ai/03-agent-systems/02-tools-and-mcp.md)。

## 证据状态与版本匹配

可以使用四种状态：`pass`（达到约定条件）、`fail`（未达到）、`not_run`（未执行）、`not_applicable`（有理由且经负责流程确认不适用）。报告存在不代表通过，报告通过也不代表属于当前候选。对必要检查，缺失、失败、未执行或版本不匹配都应阻止自动放行。

下面的本地教学例子仅演示这一规则，不会部署任何东西。把多个实际依赖版本的组合抽象成 `candidate`；真实系统还要验证证据来源、内容、时效和适用范围，不能信任任意调用者自报的 pass。

```python
from copy import deepcopy

REQUIRED = {"quality", "authorization", "recovery"}

def blockers(candidate, evidence):
    problems = []
    for name in sorted(REQUIRED):
        item = evidence.get(name)
        if not isinstance(item, dict):
            problems.append((name, "missing"))
        elif item.get("candidate") != candidate:
            problems.append((name, "stale"))
        elif item.get("status") != "pass":
            problems.append((name, "not_passed"))
        elif not isinstance(item.get("report"), str) or not item["report"].strip():
            problems.append((name, "no_report"))
    return problems

reports = {name: {"candidate": "release-17", "status": "pass",
                  "report": f"reports/{name}-17.json"} for name in REQUIRED}
assert blockers("release-17", reports) == []
assert len(blockers("release-18", reports)) == 3
for state in ["fail", "not_run", "not_applicable"]:
    changed = deepcopy(reports)
    changed["quality"]["status"] = state
    assert blockers("release-17", changed) == [("quality", "not_passed")]
changed = deepcopy(reports)
del changed["authorization"]
assert blockers("release-17", changed) == [("authorization", "missing")]
changed = deepcopy(reports)
changed["recovery"]["report"] = ""
assert blockers("release-17", changed) == [("recovery", "no_report")]
print("匹配版本放行；旧版本、未通过、缺项和缺报告均阻止放行")
```

这里的必要项不允许用“不适用”跳过。条件项则可以由发布规则在明确场景下判定不适用，例如完全无业务写入的查询服务不需要退款去重检查，但仍需要自身的超时恢复检查。不能让候选版本自行缩减必要项列表。

### 绿色检查，属于哪个候选版本？

清单的勾选状态需要绑定候选版本、输入集合和检查环境，而不是永久存在的布尔值。这个模型只展开版本维度，让“曾经通过”与“当前可用的验收证据”显式分开。

**绿色检查，属于哪个候选版本？**

发布门检查的是当前候选的有效证据集合；之前版本的绿色结果不能自动继承。


## 灰度与恢复

离线验收通过后，用有限范围的真实任务观察新版本，并与可比较的旧版本流量对照。灰度需要预先定义指标、观察条件和停止规则；只把流量比例设为 1% 并不会自动得到足够证据。低流量业务可能很久都遇不到重要失败场景。[Google SRE：Canarying Releases](https://sre.google/workbook/canarying-releases/)

| 阶段 | 重点确认 | 继续或停止的依据 |
|---|---|---|
| 影子验证（适用时） | 同一输入下的输出与资源消耗 | 写工具应隔离或模拟，不能重复真实副作用 |
| 小范围灰度 | 质量分组、人工接管、任务费用、尾延迟 | 达到预设观察条件且没有触发停止规则 |
| 逐步扩大 | 配额、排队、缓存与下游容量 | 规模增长后仍在预算与服务目标内 |
| 退回稳定版本 | 新任务路由、在途任务和状态兼容 | 确认恢复结果，并单独处理已发生副作用 |

例如，100 个任务中 95 个成功，并不意味着真实成功率已经被证明至少为 95%。在独立、同分布的简化假设下，95/100 的双侧 95% Wilson 区间下界约为 88.8%；真实任务还有分布变化和相关性。是否放量应结合样本量、关键分组与业务容忍度，不能用一个漂亮的点估计代替判断。

回退计划需要回答三个不同问题：新请求怎样回到旧配置，在途任务怎样停止或完成，已经发生的退款/发信等效果怎样核对。恢复旧 prompt 不会撤销退款；强行给进行中的任务换模型或工具版本也可能破坏其状态契约。优先让任务绑定候选版本，并明确升级、排空和恢复策略。

### 95% 成功率，证据有多强？

发布证据除了版本正确，还要有足够的样本信息。固定观测比例时，增大样本量会收窄区间；但更多重复的相似任务并不自动满足独立性，也不能替代分组覆盖。这里展示不确定性，不把一个置信下界直接当成通用上线标准。 [NIST: Wilson interval](https://www.itl.nist.gov/div898/handbook/prc/section2/prc241.htm)

$$
\frac{\hat p+\frac{z^2}{2n}\ \pm\ z\sqrt{\frac{\hat p(1-\hat p)}n+\frac{z^2}{4n^2}}}{1+\frac{z^2}{n}}
$$

**95% 成功率，证据有多强？**

同样的观测成功率，小样本区间更宽；零失败也不证明失败概率为零。


## 发布后的闭环

事故进入回归前，先保存足以解释失败的版本与必要轨迹，并对个人信息和敏感数据做适当处理。将真实数据直接复制到长期评估集可能扩大暴露范围；可以构造保留同一失败条件的合成案例。

一条有用的回归不只是“再次问同一个问题”，还要记录预期结果和失败位置。例如跨租户工单事件可以拆成执行器拒绝测试与端到端注入测试：前者验证权限边界，后者观察模型是否继续正确完成本来任务。修改后跑直接相关测试，再根据依赖影响补充回归，发布前重新确认必要证据属于当前组合。

检查表会随系统变化调整。删除失效、重复的检查并保留理由，新增能覆盖真实缺口的检查；维护目标是让证据更能预测生产行为，而不是让勾选项越来越多。
