离线发布门项目与自测

项目目标

运行一个不调用真实 LLM API 的 LLMOps 门禁。它完成四件事:

  1. 严格校验复合发布清单,拒绝重复/缺失/未知字段、错误类型和常见浮动别名;
  2. 将评测 artifact 绑定到 release,并在 baseline/candidate 的 suite、dataset、rubric、grader 或 harness 不一致时返回 INCOMPARABLE;
  3. 把离线测试、质量、安全、性能、Trace、脱敏、Canary、回滚和人工审批转成 promote/block;
  4. 将 candidate gate的完整SHA-256、仅供展示的短指纹、晋级时点、固定审计时点、同期 control、时间窗、assignment、标签覆盖、样本分母和降级证据绑定后,再把观察转成 continue/investigate/pause/fallback/rollback/human_review。

项目文件:

JSON 中的质量、安全、延迟、费用和漂移门槛只是为了让脚本产生可验证结果的本地练习数值,不是行业阈值、供应商价格或安全保证。当前严格比例、时间、降级证据和联合审计语义由 local-llmops-policy-v6 标识,在线观察 schema 为 local-online-observation-v6;策略中的率、跌幅和本项目相对增幅上限限制在 0..1。每个评测 artifact 还要声明artifact_digest_format,观察 bundle 顶层要声明evidence_digest_format,两者都必须是本项目当前支持的版本化教学格式。读取器会把原始无效 UTF-8、不能作为严格 UTF-8 标量序列编码的 Unicode surrogate,以及无法表示为有限 float 的数字转为受控契约错误,避免输入在计算完整摘要时泄露未受控异常。若生产政策需要表达更宽范围,应版本化扩展 schema 与审批规则,不能用超大数静默关闭安全门。政策、在线观察 schema 或门禁语义升版会改变相应证据的完整摘要,已有观察窗口必须重新绑定,不能沿用旧摘要或仅用短指纹。

环境与运行

脚本只依赖当前稳定 Python 3 的标准库。先学习 venv + pip 的隔离方式,但把虚拟环境放到 vault 外,避免产生缓存和大量未跟踪文件:

cd "X:\path\to\your-vault" # 切到 vault 根目录;若你的本机路径不同,请替换为自己的根目录。
$venv = Join-Path $env:TEMP "llmops-learning-venv" # 将临时环境放到系统临时目录,避免写入知识库。
python -m venv $venv # 创建隔离 Python;项目本身只依赖标准库。
& "$venv\Scripts\Activate.ps1" # 激活该环境,使随后 python/pip 使用隔离解释器。
python -m pip --version # 只核验 pip 可用与解释器归属,不安装任何第三方包。
 
$example = ".\Knowledge\AI Agent Engineer\docs\LLMOps\03-项目与自测\examples" # 保存示例目录,避免重复书写长路径。
python "$example\release_gate.py" candidate --release-id release-safe # 只评估离线候选门,预期得到 PROMOTE。
python "$example\release_gate.py" observe --observation-id obs-healthy # 只评估一条固定的健康线上观察窗口。
python "$example\release_gate.py" audit --release-id release-safe --observation-id obs-healthy # 联合检查候选与正确绑定的观察证据。

本项目不需要 pip install,不读取 .env,也不需要 API key。已有可用 Python 3 时可以不创建虚拟环境直接运行。

发布清单包含什么

一个候选必须固定:

  • 应用 commit、API contract 和 SDK 锁文件摘要;
  • Prompt 版本与内容摘要、上下文策略;
  • 检索快照与配置;
  • 供应商、模型快照和生成参数;
  • 工具名称、schema 与实现;同一 manifest 中工具名称必须唯一,避免同名工具指向两个不同契约;
  • 护栏、数据处理、路由、价格口径,以及降级发布的 release_id、manifest 完整 SHA-256 和 gate evidence 完整 SHA-256;
  • 评测 suite、dataset、rubric、grader、harness、subject release 与 artifact 完整 SHA-256;
  • 合同测试、任务/高风险切片、安全样本量、延迟和成本证据;
  • gate 决策时点、实际 promoted_at、Trace、脱敏、Canary、回滚与人工审批记录。

脚本拒绝 latest、current、production、model:latest、HEAD 和任意 refs/heads/*、refs/remotes/*、origin/*/upstream/* 分支引用,同时不因普通标识含有 main 子串就误杀;这仍只是教学检查。真实系统需按字段和供应商语义核对内容摘要、模型快照或 commit 是否能重建当时行为。Baseline 与 candidate 的 release_id 在同一 manifest 内必须全局唯一。

Baseline 与 candidate 只有在 suite/dataset/rubric/grader/harness 完全一致时才进入数值比较;否则输出 INCOMPARABLE,退出码 1。完整 SHA-256 与 subject_release_id 防止明显错绑,但当前 Layer A 仍只校验 manifest 中声明的摘要,没有读取、签名或验证外部 eval/fallback artifact 本体;生产 CI 必须实际装载报告与降级 manifest、重算摘要并核验来源、gate 结果和批准。

在线观察契约

每个观察窗口同时记录:

  • 严格 RFC 3339 UTC window_start/end(Z 或 +00:00,不能只给日期)、assignment 与 population revision;
  • candidate/control release 及 eligible、labeled、critical-labeled、safety-checked 分母;
  • task-success、critical-slice-success 与 safety-violation 的整数分子,由脚本分别除以已标注、关键切片已标注和安全已检查分母得出比率;分母为零时该比率是未知而不是零;
  • 最大标签年龄、p95 与实际费用;
  • candidate gate的完整candidate_gate_evidence_sha256、其展示用candidate_gate_fingerprint、Trace/脱敏状态、供应商信号,以及观察侧实际可用的 fallback_evidence;摘要格式由 bundle 顶层的evidence_digest_format统一声明。

时间契约使用 fixture 中固定的 policy.decision_as_of,不读取当前 wall clock,因此历史复算是确定的。candidate 必须满足 gate_decided_at <= promoted_at <= decision_as_of;线上窗口还必须满足 promoted_at <= window_start < window_end <= decision_as_of。这会拒绝拿发布前历史流量冒充 Canary,也会拒绝越过本次审计时点的“未来窗口”。candidate gate摘要有意不包含发布后才写入的promoted_at,避免控制面推进改变已审批的离线证据;但promoted_at仍在绑定观察前被独立严格校验。若要审计更晚窗口,应生成新版本 policy/candidate gate摘要并重新绑定,而不是修改旧审计的时钟。

线上质量、延迟和成本与同期 control比较,不再把离线冻结集聚合值冒充线上参考;质量/关键切片的自动回滚比较只在 candidate 与 control 都满足样本、覆盖、关键切片、安全检查和标签新鲜度门后才执行。观察侧非空 fallback_evidence 必须在绑定阶段与 candidate gate 所绑定的 candidate.routing.fallback_manifest 完全一致,错摘要或错发布属于契约错误;供应商退化但证据缺失时只能 HUMAN_REVIEW,完整匹配时仍须 candidate 当前窗口满足上述证据充分性,才允许自动 FALLBACK。否则即使降级发布已预验,也进入 HUMAN_REVIEW(并停止自动扩大),不能用稀疏或陈旧信号驱动自动切换。Manifest 还拒绝自引用、已知 fallback 链循环,以及已知但未通过 gate、未晋级或晚于主候选晋级的 fallback candidate。因此布尔型“已就绪”自声明不能触发自动切换。audit --release-id A --observation-id B 必须证明 B 的 candidate release 正是 A;跨发布拼接属于契约错误,退出码 2。只给 audit --release-id A 时也必须至少存在一个绑定到 A 的线上窗口,否则不能把纯离线 candidate 复算冒充“联合审计”;纯离线检查应使用 candidate 子命令。无参数批量 audit 则要求每个已经通过 candidate gate 的 release 都至少有一个绑定窗口;离线已阻断的 candidate 不要求伪造线上观察。

摘要格式与真实证据边界

python-json-sorted-utf8-v1精确命名本项目的 Python 字节表示:将位置参数作为外层数组,以json.dumps(ensure_ascii=False, sort_keys=True, separators=(",", ":"), allow_nan=False)序列化,UTF-8 编码后计算 SHA-256。Decision.evidence_digest_format、eval artifact 的artifact_digest_format与观察 bundle 的evidence_digest_format都必须带这个值;线上决策还将 bundle 的schema_version和格式字段共同纳入完整摘要,因此二者升版会改变其证据。固定 golden vector 测试同时锁定格式标签和相同输入的字节摘要,防止三个离线教学项目在无意中漂移。

这只让受控的同实现交接可复算、让未知格式可被拒绝;它不会读取外部 artifact 本体,也不会证明某个 64 位摘要确实来自上游、制品未被替换、来源已签名或批准已存在。当前 fixture 彼此独立,不能假装是一次真实 eval→gate→Canary 传递。真实跨语言哈希或签名应交换已验证的原始字节,或采用并互操作测试明确规范(例如 RFC 8785 JCS);本地 profile 不是通用 canonical JSON,也不能代替受控制品库、访问控制、签名和人工批准。完整交接图与字段边界见 离线到线上证据交接与回归闭环。

预期结果

候选发布:

  • release-safe:严格契约和全部本地门均满足,输出 PROMOTE,进程退出码为 0;
  • release-regression:工具合同、高风险切片、安全样本量、费用和人工审批失败,输出 BLOCK,退出码为 1。

线上观察:

观察预期动作原因
obs-healthyCONTINUE证据齐全且满足本地策略
obs-low-sampleINVESTIGATE不能把样本不足误当成功
obs-provider-driftFALLBACK供应商信号退化且已验证降级路径就绪
obs-provider-insufficient-evidenceHUMAN_REVIEW虽已绑定 fallback,但 candidate 安全检查分母不足,不能自动切换
obs-quality-regressionROLLBACK任务、高风险切片和安全门失败
obs-no-fallbackHUMAN_REVIEW供应商退化但没有已验证备选
obs-capacity-costPAUSE延迟与费用退化,先暂停扩大

没有指定 ID 时,命令会检查全部样例;只要其中存在阻断或动作要求,整体退出码就是 1。输入文件不存在、JSON 无效或契约错误时退出码是 2。

可直接复现“已绑定 fallback 但证据不足”的保守结果:

python .\release_gate.py audit --release-id release-safe --observation-id obs-provider-insufficient-evidence # 验证证据不足时保守进入 HUMAN_REVIEW,而非自动降级。

该命令应输出 HUMAN_REVIEW,并以退出码 1 停止自动扩大;它不是自动 fallback 的成功路径。

测试与验证

$example = ".\Knowledge\AI Agent Engineer\docs\LLMOps\03-项目与自测\examples" # 再次定义示例目录,使这段可独立复制执行。
$env:PYTHONDONTWRITEBYTECODE = "1" # 禁止 Python 在知识库生成 __pycache__。
Push-Location $example # 进入测试文件所在目录,确保相对 fixture 路径稳定。
try {
    python -c "from pathlib import Path; [compile(p.read_text(encoding='utf-8'), str(p), 'exec') for p in (Path('release_gate.py'), Path('test_release_gate.py'))]" # 在内存中编译实现与测试,先做无 .pyc 的语法检查。
    python -m unittest -v .\test_release_gate.py # 普通解释器模式运行全部回归测试。
    python -O -m unittest -v .\test_release_gate.py # 确认生产逻辑没有依赖会被优化移除的 bare assert。
    python -W error -m unittest -v .\test_release_gate.py # 将 warning 当作失败,及时发现兼容性问题。
    python -O -W error -m unittest -v .\test_release_gate.py # 组合最严格的解释器与告警条件。
} finally {
    Pop-Location # 即使任一测试失败也恢复调用前的工作目录。
}

这里用内存中的 compile() 做语法检查,不生成 .pyc。-O 会移除生产代码中的普通 assert,所以测试专门验证优化模式仍保持门禁。项目的生产判定不依赖 assert;测试中的 self.assert* 是测试框架断言,不会被优化模式静默删除。本版74项测试还验证完整摘要篡改、短指纹不能替代完整绑定、未知摘要格式、bundle schema/profile 会改变在线决策摘要、格式标签与固定 golden vector、结果分子不能超过其分母、重复工具名被拒绝、原始无效 UTF-8 / 不可编码 surrogate / 无法表示为有限 float 的数字会成为契约错误、fixture/CLI 中证据不足的供应商漂移不会自动降级,以及promoted_at不会重写已批准的候选门证据。

分步实践

  1. 运行健康联合审计,记录 policy 版本与 evidence 指纹;
  2. 运行 release-regression,逐条映射到工具、质量、安全、成本和治理风险;
  3. 将安全违规率保持为零,但把安全样本量改为 1,解释为什么仍被阻断;
  4. 将模型快照改成 latest,确认这是输入契约错误(退出码 2),而不是普通候选失败;
  5. 把 candidate dataset version 改成与 baseline 不同,确认得到 INCOMPARABLE;
  6. 尝试把 release-regression 与 obs-healthy 联合审计,确认错绑以退出码 2 失败;
  7. 将 obs-provider-drift.fallback_evidence.manifest_sha256 改成另一个合法的 64 位摘要,确认绑定以契约错误失败;再把整个字段改为 null,确认供应商退化只能进入人工复核;运行 fixture 中的 obs-provider-insufficient-evidence,确认即使 fallback 已绑定,候选安全检查分母不足也只能人工审查,不能自动切换;
  8. 新增一个质量正常但 redaction_check_passed=false 的观察,确认隐私失败优先于性能信号;
  9. 给策略新增“生效时间、风险理由、批准记录摘要”时,先扩展严格契约和测试,再修改 fixture。

自测题

  1. 为什么 Prompt、API contract、工具 schema 和 grader 都应进入 manifest?
  2. 为什么整体任务成功率上升时,高风险切片仍可以阻断发布?
  3. 为什么“观察到零个安全违规”还需要检查样本量与覆盖范围?
  4. 为什么 Trace 完整性是发布条件,而不只是事故后的可选功能?
  5. 供应商漂移时,为什么观察侧布尔值不足以触发自动切换,而必须匹配 candidate gate 已绑定的降级发布身份与摘要?
  6. 为什么重新计算历史费用时必须固定当时的价格策略版本?
  7. 证据指纹能证明什么,不能证明什么?

掌握检查

  • 能解释严格 JSON 契约与业务门禁是两个层次;
  • 能区分 0/1/2 三类退出码,并在 CI 中正确处理;
  • 能解释每类候选检查对应的生产风险;
  • 能把 Canary 观察映射为继续、调查、暂停、降级、回滚或人工复核;
  • 能新增 fixture 和测试,并在普通、-O、warnings-as-errors、-O + warnings-as-errors 四种模式通过;
  • 能说明本地摘要格式为何可用于受控复算,却不能替代跨语言规范化、制品来源验证或批准;
  • 能区分“本地练习门满足”与“真实系统已安全”。

项目边界与下一步

本项目验证的是证据结构、release/window/fallback 绑定和决策逻辑;它没有调用真实模型、装载外部 eval/fallback artifact、测量真实 token/费用、执行真实 Canary,也没有证明供应商、数据区域、随机分流、标签正确性或业务因果效果。完整SHA-256在接收端已验证同一版本算法、格式和字节时,才能检测同一声明输入是否变化;短指纹仅是其展示前缀。二者都不能证明输入真实、内容完整、来源已签名或已经获批。fixture 中固定 decision_as_of 只提供可复算的时间上界,不代表现实中的可信时间戳服务。

下一步可将相同清单接入 CI,并用 运行监控 建立真实观察面;线上异常先作为受控人工分诊候选,而不是自动写入评测集,完整边界见 离线到线上证据交接与回归闭环。任何真实供应商接入都要重新核对当前 API、价格、保留能力和合同。

参考资料

以下动态资料均核验于 2026-07-22: