用可校验凭证把 AI 上线检查落到 CI
文章将 AI 原型的就绪检查转为可机器校验的 JSON 凭证,记录时间、哈希与有效期。统一检查脚本在证据缺失、过期、失败或未签名时返回失败,避免沿用失效的检查结果。
AI 深度解读
AI 原型能不能进入下一阶段,不能只看文档里有没有打勾。作者提出的做法是:每项检查生成一份 JSON 凭据,记录时间、代码提交和证据,再由脚本统一判断;缺失、过期、失败或缺少必要的人类签署,都必须拦住流程。
这套方案值得看,因为它解决了一个具体问题:原型准备上线时,团队能否回答「检查过什么、对应哪次提交、结果还有效吗」。但文章里的示例脚本,距离它宣称的完整校验还有几处差距。
打勾为什么不够,JSON 凭据又多解决了什么
作者描述的失效过程很常见:第一个迭代认真检查,第二个迭代沿用上个月的结果,第三个迭代只能去聊天记录里找证据。到了真正要推进原型的时候,没人能把结论和代码状态对应起来。
他们采用的办法,是给每道门禁留下一份可由机器读取的凭据。门禁就是一个决定流程是否继续的检查点。它必须回答三个问题:有没有检查、检查是否通过、结果是否还在有效期内。
下面这份凭据把检查结论和执行证据放在一起,避免只留下一个孤立的「通过」。
{
"gate": "json_contract",
"status": "pass",
"checked_at": "2026-11-08T09:12:00Z",
"commit": "9f3c1ab",
"evidence": {
"command": "python -m gates.json_contract --fixtures tests/fixtures/bad_json",
"exit_code": 0,
"artifact": "artifacts/json_contract_2026-11-08T09-12-00Z.log",
"sha256": "3b1f...c07a"
},
"signed_by": "taylor"
}
要留意 evidence:命令、退出码、产物路径和哈希,才是追查结果的依据;示例里的 sha256 是缩写展示,不能直接用于完整性校验。
作者要求,checked_at 必须采用带时区的 ISO 8601 格式,status 只能是 pass 或 fail,不接受含糊的「部分通过」。evidence.artifact 指向的文件应当真实存在。自动检查的 signed_by 留空,需要人承担责任的检查则必须填写。
这里的「签署」先别理解成密码学签名。原文展示的是一个姓名字符串,没有给出身份认证或防伪机制。
检查结果为什么必须过期
凭据能证明过去执行过检查,却不能自动证明现在仍然安全。延迟、成本和外部依赖会变化,所以作者给每道门禁分别设置 TTL,也就是结果的最长有效期。
示例包含六项规则:
json_contract检查 JSON 契约,有效期为24 * 7小时,即 7 天。latency_probe检查延迟,有效期为 24 小时。degradation_drill检查降级演练,有效期为24 * 14小时,即 14 天。cost_ceiling检查成本上限,有效期为 7 天。egress_allowlist检查出站访问白名单,有效期为24 * 30小时,即 30 天。human_signoff记录人工确认,有效期为 30 天,并要求填写签署人。
作者特别强调降级演练和人工确认:前者关注用户真正遇到的故障,后者明确谁接受了风险。不过,原文没有展开降级演练具体测什么,不能据此假定超时、重试、备用模型等场景已经覆盖。
凭据还必须由检查程序生成。下面的命令展示了延迟检查怎样同时接收采样参数、预算和输出位置。
python -m gates.latency_probe \
--samples 30 \
--p95-budget-ms 2500 \
--receipt gate-receipts/latency_probe.json \
--artifact-dir artifacts/
重点是 --receipt:执行检查的程序要自己写出结果。--samples 30 和 --p95-budget-ms 2500 分别指定 30 次采样与 2500 毫秒的 P95 预算;它们只是示例参数,原文没有提供采样设计或稳定性数据。
真正控制流程的是退出码
只有非零退出码能实际阻断合并和部署,检查结果才构成门禁。
作者提供的 gatecheck.py 读取 gate-receipts/,逐项检查规则。全部满足返回 0;存在失败、过期或缺少必要签署的凭据返回 1;凭据目录不存在则返回 2。
本地可通过 python tools/gatecheck.py; echo "exit=$?" 查看退出码。接入 CI 时运行 python tools/gatecheck.py,并把任何非零结果设为硬阻断。目录缺失尤其不能解释成「暂时没有需要检查的东西」,否则新仓库或配置不完整时,门禁反而自动失效。
作者建议一开始只启用 json_contract、latency_probe、human_signoff 三项。自动生成的凭据放进 .gitignore,human_signoff.json 则作为决策记录进入评审;检查在默认分支和修改模型客户端的 PR 中运行。
随后主动破坏流程:删除一份凭据、把另一份回拨 30 天、清空人工签署。这三种情况都应返回 1。再记录两周退出码,观察是否频繁因 STALE 被拦住。
这里有个落地细节:示例脚本默认要求六项,采用三项起步时必须同步修改 RULES。另外,自动凭据被忽略后,CI 需要先执行检查并生成它们;只提交校验脚本,干净的运行环境里不会凭空出现证据。
我的判断
我赞成把准备状态从口头判断变成可检查的记录。相比 wiki 清单,它更容易追溯;相比单纯的 CI 红绿灯,它还能表达结果的有效期和人工决策。但如果现有流水线已经保存测试产物、绑定提交并要求审批,新增账本的收益主要在统一这些信息,未必需要另建一套系统。
示例脚本也不能照搬后就视作完成。它检查了产物路径字段是否非空,却没有验证文件存在或重新计算 sha256;记录了 commit 和 exit_code,却没有核对当前提交与执行退出码。未来时间戳也可能通过年龄检查,部分缺字段和读取异常没有被整理成明确的诊断信息。
因此,这份代码演示了阻断思路,还没有实现完整的证据校验。 凭据本身也只能证明某项检查留下了记录,不能证明检查设计正确。
TTL 同样是经验起点。作者认为 STALE 最常见时说明期限太紧,我会先排查检查是否按计划运行、生成和消费凭据的流程是否接通,再决定是否放宽期限。原文没有提供事故率、维护成本或对照实验,不能据此认定这些时长普遍合适。
还有商业披露需要带上:文章属于 MonkeyCode 的产品推广。作者称自己用其免费模型生成候选故障模式,再删掉约三分之二;文中以枚举 40 种故障、选出 6 种为例说明筛选思路,但没有给出完整实验结果。免费服务器被建议用于展示账本缓存,权威记录仍留在仓库和 CI,也不应把免费托管放进部署关键路径。
能拿来做什么
- 如果前端或 Node 服务接入模型后依赖结构化 JSON,可以先把现有契约测试接上凭据输出,保留命令、退出码和日志哈希,再让 CI 消费这些结果。
- 如果要沿用延迟检查示例,先明确请求样本和计时范围,再决定是否采用 30 次采样、2500 毫秒 P95 预算及 24 小时有效期,避免把演示参数直接当成服务标准。
- 接入流水线前,除了测试删除、过期和清空签署,还应检查产物丢失、哈希不符、提交不符和未来时间戳,补齐示例脚本没有验证的证据链。
- 对已有用户或数据的原型,可以从三道门禁起步;对一次性脚本或周末演示,先衡量维护成本。作者也明确反对为了形式给所有项目套满六项检查。