101 防御性架构把类型、契约、策略与沙箱钉成系统边界。边界要生效,必须挂进 每次变更都会跑的机器路径——否则只是仓库里一份「建议遵守」的文档。本文讨论这条路径:CI、策略即代码、评测(eval)hook、金丝雀与回滚如何组成 工程基础设施,在「人审不过来」时仍限制破坏。
不写:某个云厂商的 YAML 教程;不编造本站或未公开组织的「AI PR 缺陷率」。训练集群与推理评测基准见 llm-infra;在线 Agent 的 eval hook 在 95 仅点到为止,本文展开 开发期变更流 上的门禁。
系列导航: ← 防御性架构 · 系统架构设计索引 · 架构即 AI 上下文 →
相关专题: SLO 工程 · 混沌工程 · 可观测性索引 · 优雅降级
一、问题:变更速率超过人审吞吐
1.1 威胁模型(开发期)
把「AI 参与的变更」当作攻击面与事故面,比当作效率神话更有用:
| 威胁 | 描述 | 若不设门禁 |
|---|---|---|
| 批量浅层正确 | 多文件补丁局部自洽,跨模块不变量被破坏 | 合并后集成失败或静默坏数据 |
| 为过测试而放宽 | 改断言、改策略、删检查「让绿」 | 闸门被生成物反向削弱 |
| 密钥与环境泄漏 | 把本机 .env、临时
token 写进仓库 |
凭证扩散 |
| 不可逆迁移 | 破坏性 schema / 数据脚本进入主干 | 回滚困难 |
| 评测投机 | 只对 eval 集过拟合,生产分布不同 | 虚假信心 |
Humble 与 Farley 在 Continuous Delivery 中强调:质量内建于部署流水线,而非依赖发布前的英雄式测试[1]。Google SRE 将变更视为可靠性的主要风险来源之一,主张渐进发布与快速回滚[2]。AI 不改写这些结论;它提高 单位时间进入流水线的变更数,使「靠资深工程师盯 Diff」的假设更快失效。
1.2 本文核心问题
- 门禁应如何分层,每层失败语义是什么?
- eval 适合挡什么、不适合挡什么?
- 回滚与金丝雀如何与 28 SLO 的错误预算衔接?
- 「eval 替代人审」争论的证据边界在哪?
二、门禁分层
2.1 总览
flowchart LR
PR["PR / change"] --> G1["lint / secret scan"]
G1 --> G2["type / unit"]
G2 --> G3["schema / contract"]
G3 --> G4["policy as code"]
G4 --> G5["eval hooks"]
G5 --> G6["review gate"]
G6 --> G7["canary / progressive"]
G7 --> Prod["production"]
G7 --> RB["rollback"]
原则:越靠左越便宜、越确定;越靠右越贵、越接近真实风险。 左侧重机器确定性检查;右侧才引入统计性 eval 与人工。
2.2 Lint、密钥扫描与格式
- 作用:统一风格、挡住明显危险模式(
eval(、禁用 API)、扫描密钥形态。 - 失败语义:阻断合并;修复成本低。
- 对 AI:高价值——模型常引入格式噪声与偶然粘贴的密钥样例。
不把「lint 全绿」解读为安全或正确。
2.3 类型与单元测试
承接 101 的类型闸门。单元测试应覆盖 不变量与错误路径,而不是只断言快乐路径——否则生成代码容易「写过测试的实现」。
失败语义:阻断。若测试被生成物删除或空断言,应有 测试覆盖率/变异测试 类二次信号(可选);没有这类信号时,人审必须盯测试 diff(见 104)。
2.4 Schema 与契约测试
OpenAPI/JSON Schema 校验与 consumer-driven contract 在 CI 红灯,防止契约漂移进入主干。失败语义:阻断。与 101 一致:权威 spec 在仓库内版本化。
对「为过测而放宽 schema」应设
约束工件的额外审门槛(CODEOWNERS 保护
openapi/、policies/)。
2.5 策略即代码
OPA/Cedar 等策略变更与业务代码同 PR 时:
- 策略语法/单元策略测试失败 → 阻断;
- 策略放宽(允许集变大)→ 可要求 强制人审标签,与普通业务 diff 区分。
站内策略模型见 iam/13。
2.6 Eval hooks
此处 eval 指 针对助手/Agent/生成质量的自动评测集,不是机器学习训练的离线 benchmark 榜单。
| Eval 类型 | 例子 | 适合挡 | 不适合单独挡 |
|---|---|---|---|
| 确定性回归 | 固定输入 → 期望结构化输出 / 工具序列 | 格式回归、已知坏案例 | 新颖攻击 |
| 属性/不变量 | 「不得调用生产写工具」「SQL 只读」 | 权限类回归 | 复杂业务对错 |
| 评分模型 | LLM-as-judge | 粗粒度质量信号 | 作为唯一合并条件(偏置与不稳) |
| 安全套件 | prompt 注入、危险工具链用例 | 已知威胁类 | 未知 0-day 社会工程 |
95 文在运行时侧提到 eval hook;开发期应把 失败案例沉淀回仓库评测集,形成与缺陷跟踪的闭环。评测集本身是代码,需同样走门禁,防止「删案例让绿」。
证据边界:本文不声称某一公开 eval 框架在你的业务上「准确率 X%」——未在本站业务上复现则不作数字结论。
2.7 人审门禁
机器绿灯之后仍可能需要人审:高风险路径、策略放宽、数据迁移、安全相关 diff。人审不是「再跑一遍 lint」,而是判断 意图与全局权衡。编排细节见 104。
2.8 金丝雀与渐进发布
Nygard 强调发布后的快速感知与止损[3];SRE 实践常用 canary / 分批发布,用 SLI 自动或半自动中止[2]。对 AI 高频合并尤其关键:主干绿灯 ≠ 生产安全。
与 28 的衔接:金丝雀期间错误预算消耗加速 → 自动回滚或冻结发布。与 26 的衔接:可经 feature flag 关闭 AI 引入的功能切片。
三、失败语义与回滚
3.1 三类失败
| 失败类 | 发生点 | 默认动作 |
|---|---|---|
| 硬失败 | lint/类型/契约/策略语法 | 阻断合并 |
| 软失败 | eval 分数低于阈值、flaky 测试 | 阻断或「需人工确认」标签;忌静默忽略 |
| 生产信号失败 | canary SLI 恶化 | 回滚或暂停 rollout |
软失败最危险的处理方式是「先合并再说」——在 AI 吞吐下会系统性累积债务。
3.2 回滚设计前提
回滚能成立,依赖架构前置条件(与是否 AI 无关,但 AI 提高需求频率):
- 向前兼容的数据变更策略,或迁移分相位(expand/contract);
- 配置/旗标可关功能,而不靠「再推一次热修」;
- 制品不可变:回滚是重新部署旧制品,不是在生产上手工改文件;
- 可观测:能回答「这次发布之后哪个 SLI 坏了」——见 observability。
若迁移不可逆,门禁应上移到 强制人审 + 演练环境验证,而不是指望 canary 救场。
四、与邻接系列的分工
| 主题 | 本篇 | 外链 |
|---|---|---|
| 约束本身(类型/契约/沙箱) | 引用 | 101 |
| SLO / 错误预算定义 | 衔接口 | 28 |
| 指标/追踪实现 | 不展开 | observability |
| 在线 LLM 成本与超时 | 不展开 | 95 |
| 人机流程与责任 | 点到 | 104 |
| 模型训练评测榜 | 不展开 | llm-infra / rl-posttraining |
五、争论:eval 能否替代代码评审
5.1 双方
| 立场 | 主张 | 限制 |
|---|---|---|
| Eval 可替人审 | 确定性回归 + 安全套件覆盖常见回归,人审成瓶颈 | 对新意图、架构权衡、「不该做」的变更敏感度低 |
| 人审不可替 | 责任、意图、跨系统效应需人类担责 | 吞吐有限;疲劳导致漏审 |
5.2 有文献与工程传统支撑的折中
Continuous Delivery 传统主张自动化验证尽可能多,但并不取消对高风险变更的人工决策[1]。SRE 变更管理区分常规变更与高风险变更[2]。迁移到 AI 语境:
- 可用 eval/CI 替代的:格式、类型、已知契约、已知安全坏案例、策略单测;
- 不可用 eval 单独替代的:新的信任边界调整、数据模型破坏性变更、跨团队 API 语义、合规相关策略放宽。
因此「替代」应写成 范围限定的替代:在低风险路径上减少人审强制项;在高风险路径上人审仍是硬门禁。用一句「各有优劣看场景」结束争论不符合本站文风——场景必须用 副作用不可逆性 刻画(与 101 §五同一尺子)。
尚无公开、可复现的跨公司 RCT 证明「全自动 eval 门禁优于人审」;强结论停在机制层。
六、开放问题
Eval 成本与假阳性治理
每次 PR 跑大模型 judge 的费用与延迟可能反向激励团队关掉门禁。如何对 eval 本身设 SLO(时长、成本、抖动)仍缺通用做法。评测集所有权
安全团队、平台团队、业务团队谁有权删改案例?缺少所有权时,评测集会腐化为「谁都能改的绿灯开关」。多仓单逻辑变更
AI 常跨仓改动;单仓 CI 绿并不能代表系统级安全。跨仓「逻辑发布」的编排仍是开放工程问题(与微服务时代的相同问题,频率更高)。
七、落地检查清单
- PR 是否强制 secret scan + 类型/单测?
openapi/、policies/、evals/是否有 CODEOWNERS 或等价保护?- 契约测试是否在提供方 CI 阻断?
- eval 失败是阻断、标标签,还是被忽略?
- 生产是否有 canary + 基于 SLI 的自动/半自动回滚?
- 破坏性迁移是否被单独流水线与强制人审捕获?
参考资料
书与经典工程文献
- Humble, J., Farley, D., Continuous Delivery, Addison-Wesley, 2010.(A/B 级,工程经典)[1]
- Beyer, B. et al., Site Reliability Engineering, O’Reilly, 2016 — 变更管理与渐进发布相关章。(B 级)[2]
- Nygard, M., Release It! 2nd ed.(B 级)[3]
规范与工具文档
- OpenAPI Specification 3.1;OPA/Cedar 官方文档(钉所用版本)。(A/B 级)
- 各 CI 系统「required checks」机制文档(GitHub/GitLab 等,按平台钉版本)。(B 级)
站内交叉
核心文献(本主题)
| 文献 | 引用点 |
|---|---|
| Continuous Delivery | 质量内建于流水线 |
| Google SRE | 变更风险、渐进发布 |
| Release It! | 发布后止损与舱壁 |
实验与数据
- 本篇无集群压测;不报告未实测的缺陷率或 eval 准确率数字。
系列导航: ← 防御性架构 · 系统架构设计索引 · 架构即 AI 上下文 →
同主题继续阅读
把当前热点继续串成多页阅读,而不是停在单篇消费。
【系统架构设计】防御性架构:用系统设计约束 AI 犯错
当 AI 默认参与写代码与改系统,架构的任务从「选对模式」扩展为「把破坏半径钉死」。本文从失败场景出发,梳理类型、契约、策略引擎与沙箱组成的约束谱系,对照弹性工程里「失败必发生」的假设,并讨论过度约束与交付速度的争论边界。
【系统架构设计】架构的不变量:穿越技术周期的设计原则
单体、微服务、边缘、AI 原生换的是部署形态与运行时组件,失败、尾延迟、一致性权衡、爆炸半径、反馈控制、组织同构与可观测性前提在二十年间并未消失。本文把 Part XIV 前沿篇收束为可核对的不变量清单,逐条链回本系列已写篇章与经典文献,并给出开放问题与自检用法。
【系统架构设计】AI 原生开发流程:人机协同的架构实践
收束 Part XV:把防御性约束、流水线门禁与架构上下文编成可审计的人机开发流程。本文划分角色与责任面,给出 PR/变更门禁状态机,衔接 HITL 与 agent-identity,并讨论责任归属争论与开放问题。
【系统架构设计】优雅降级:如何体面地\"坏掉\"
系统过载时,被动失效和主动降级看起来结果相似,工程含义却完全不同。本文从 Google SRE 的负载脱落与优雅降级实践出发,给出可执行的降级目录、触发信号、开关编排与恢复顺序,讨论一致性边界、用户提示与常见反模式,并说明它如何与熔断、限流协同工作。