阅读材料: 应用部分 8. 争议变更的文件仲裁:角色、裁决与先例

模块「应用部分 8. 争议变更的文件仲裁:角色、裁决与先例」中第 1 / 5 节课
您正在未登录状态下查看课程。 请登录,以保存进度并参加测试。

应用部分 8. 争议变更的文件仲裁:角色、裁决与先例

状态:前沿。 验证者/实现者/安全员的文件仲裁(投票)配合协调员协议,并将结果记录在 judgment.md(争议裁决)和 precedents.md(先例)中——这是一种已被采用的技术,但在 Qwen Code 中尚未内置。兼容性与限制详见 appendix-b-qwen-code-compatibility.md

对于教学通关,只需从可运行示例中获取 judgment.md,并理解验证者接受哪些证据。层级轮换、外部协调员和模型矩阵属于完整的生产级流程。

与第 4 章的边界如下:LLM 对决回答的问题是"是否找到了最小反例以及如何关闭它"。文件仲裁回答的是另一个问题:"角色团队做出何种官方裁决、哪些证据被认定为可接受、以及为未来争议留下何种先例"。

文件仲裁本身不会自行查找所有缺陷。它将其他机制的结果作为证据接受:对决中的反例、Spec CI 报告、反古德哈特不变量、就绪门(readiness gate)或突变体记录。如果文件中没有证据,协调员不应将智能体的印象转化为裁决。

第一卷第 16 部分 的团队评审是基本方案:人类评审者根据证据包检查拉取请求。此处将同一方案提升到更高层级。不再由单人工作,而是由角色协作:验证者(Verifier)、实现者(Implementor)和安全员投票;协调员(Coordinator)负责记录协议但不投票。不再使用 PR 评论,而是两个文件:judgment.md(争议裁决日志)和 precedents.md(重复争议库)。支撑基础不变:裁决与 第 9 部分validation.md 事实核对,最终结果按 第 10 部分 的重新规划方式审视路线图。

阅读前

  • 第一卷的支撑基础:第 16 部分设定团队评审,第 10 部分展示事实后的重新规划。
  • 本地教学案例:autoscale_200pct,因为已为其准备好对决、不变量和 judgment.md
  • capstone/ 的产出:一个针对 high_memory_usageAPPROVEDENYDEFERRED 裁决,附带 evidence_ref
  • 首轮关键术语:文件仲裁和 judgment.md。角色(验证者/实现者/安全员 + 协调员-记录员)已在第 3 部分引入——此处为其提供程序性规范。
  • 可延后内容:模型矩阵、外部协调员和永久性 precedents.md 库。

目标

您将学会如何进行争议变更的文件仲裁。这是多个角色对单一变更的集体检查,结果记录在文件中而非聊天中。目标是设计一种方案,使单一规范即使在角色、模型和严格度模式轮换的情况下也能可复现地验证。

角色轮换是指通过不同的实现者/验证者配对(每位置使用本地或强力智能体)运行同一规范。其目的是使裁决不依赖于特定模型。

实际收益很简单:争议不再是聊天中的意见交换,而是转化为证据链。协调员主导流程。实现者提出变更。验证者按正式标准接受或拒绝。安全员在 critical_risk 时拥有否决权。最终结果固定为项目工件。

此方法延续 SDD 逻辑:规范仍是系统行为的真理来源,而非开发者意图的可选描述(GitHub Spec Kit)。

该机制的工程名称——多角色争议变更文件仲裁协议。tribunal 名称保留为可运行示例目录的技术标签,而非 Qwen Code 的独立产品。

最小教学场景

教学案例

同样是 autoscale_200pct,但现在不仅需要反例,还需要正式协议:对决、反古德哈特不变量和最终 judgment.md

准备

  • book2/examples/tribunal/specs/autoscale_spec.yaml
  • book2/examples/tribunal/cases/
  • book2/examples/tribunal/metrics/validation_metrics.json
  • 脚本 run_duel.pycheck_invariants.pywrite_judgment.py

步骤

  1. cd book2/examples/tribunal预期:您已进入可运行示例目录。
  2. python3 scripts/run_duel.py --spec specs/autoscale_spec.yaml --cases cases/ --out out/duel.json预期:对决已记录各案例的裁决。
  3. python3 scripts/check_invariants.py --metrics metrics/validation_metrics.json --out out/invariants.json预期:反古德哈特不变量已独立于对决完成检查。
  4. python3 scripts/write_judgment.py --duel-out out/duel.json --invariants-out out/invariants.json --to out/judgment.md预期:已生成最终的 markdown 协议。
  5. 打开 out/judgment.md,将一个可重复冲突迁移至 precedents.md:条件、证据、裁决、适用性。

验证事实

judgment.md 不仅包含 PASS/FAIL,还包含依据:检查了哪个案例、哪个不变量触发、实现者在重复争议时应做什么。没有这些,文件仲裁就只是第 4 章的对决。

如何进入 capstone/

将一项裁决、原因、evidence_ref 和下一步可验证步骤迁移至 capstone/judgment.md。若冲突可重复,添加简短先例记录。若可运行示例中的命令可复现,则无需迁移整个 out/duel.json

最小片段:

verdict: DEFERRED
reason: "readiness passes by score, but stateful blocker has no backup evidence"
evidence_ref: "fixtures/readiness_block_stateful.json"
next_step: "add backup_verified evidence or keep remediation manual"

可评审产出

judgment.md 或其在 precedents.md 中的摘录已成为教学证据包的一部分,则予以保留。本地 out/duel.jsonout/invariants.json 若可通过命令复现,可置于仓库外。

关键思想

文件仲裁的阶段契约始于协调员角色。他开启会话、设定轮次顺序、管理争议队列,并负责 judgment.md 中的正式协议。judgment.md 本身是会话裁决日志:经过哪些轮次、审查了哪个差异(diff)、哪些证据被认定为充分。

最小循环如下:协调员接收原始规范,将其分解为可检查文件,为关键风险指派实现者、验证者和安全员角色,并禁止在未记录前一轮结果的情况下进入下一阶段。完整的角色章程含投票权重(vote_weight)、法定人数和否决条件——详见 第 3 部分。此处我们关注这些角色如何围绕特定争议变更运作。

这在实践中意味着什么。以聊天中的简短裁决为例:

不佳: > "验证者拒绝了实现者的提议。"

问题:没有依据,没有证据链接(evidence_ref),争议不可复现。下一位评审者既无法质疑也无法支持该裁决。

良好: > verdict=DENY, reason=violates_invariant:silent_p0, evidence_ref=tests/regression_001.json, next_step=实现者在自动升级前添加严重性检查

此处的 evidence_ref第 1 部分 的证据标记相同:指向文件中具体位置的链接,而非转述。silent_p0 是不变量"任何 P0 事件不得在无升级情况下关闭"。若验证者返回 DENY,请勿手动关闭争议。要求对方提供正式依据:指向具体需求的链接、钩子日志、模式违规或未证实场景。这样 judgment.md 就不是"谁赢了"的报告,而是程序状态日志。

在 Qwen Code 中,此类仲裁并非单一内置命令。最小实现由 /review、无头(headless)qwen -p 运行、项目脚本以及必要时用户命令组合而成。所有裁决保存至文件,以便其他工程师无需聊天历史即可复现争议。角色与内置 CLI 功能的详细对应关系见 [appendix-b-qwen-code-compatibility.md](appendix-b-qwen-code-compatibility.md)。

> [可运行] — 文件仲裁的可运行示例位于 [examples/tribunal/](examples/tribunal/)(见 [examples/tribunal/README.md](examples/tribunal/README.md))。实际运行由三个脚本组合:

  • run_duel.py 写入对决的 JSON 结果;
  • check_invariants.py 检查反古德哈特阈值(禁止以牺牲其他指标为代价提升单一指标的规则);
  • write_judgment.py 从前两个输出组装最终 judgment.md

book2/examples/tribunal 目录运行。

cd book2/examples/tribunal
python3 scripts/run_duel.py \
  --spec specs/autoscale_spec.yaml \
  --cases cases/ \
  --out out/duel.json

python3 scripts/check_invariants.py \
  --metrics metrics/validation_metrics.json \
  --out out/invariants.json

python3 scripts/write_judgment.py \
  --duel-out out/duel.json \
  --invariants-out out/invariants.json \
  --to out/judgment.md

run_duel.py 读取规范并运行 cases/ 中的反例。check_invariants.py 将实际指标与阈值核对。write_judgment.py 组装最终 markdown 协议。不存在作为独立进程的"协调员"或"验证者"。在生产环境中,此类仲裁由内置命令 /review、带不同角色提示的无头 qwen -p 调用以及各自磁盘上有工件的项目脚本组合而成。

同一规范在不同实现者/验证者配置间的 A/B 比较显示,裁决在多大程度上依赖于特定层级的智能体。模型层级(tier)在此指模型级别:廉价本地(local-coder)或强力云端(frontier-reviewer)。同一 rate_limit_spec.md 通过多对组合运行:

  • C1:廉价本地实现者 对 强力验证者;
  • C2:强力实现者 对 本地验证者;
  • C3:对称本地组合;
  • C4:对称昂贵组合。

若 C1 和 C4 给出 PASS,而 C2 稳定返回 FAIL,这并非立即更换模型的信号。首先检查证据框架:较低层级的验证者可能未察觉请求限制、冷却窗口(cooldown)与队列安全状态之间的隐含关联。

此测试的价值恰恰在于保持规范不变,仅改变角色配置。

教学可运行类比位于 [examples/tribunal/matrix/](examples/tribunal/matrix/README.md):同一对决 judge()matrix/tiers.json 中描述的四个层级配对运行。配置模拟证据形式之间的差异——local-coder 给出简短 diagnostic_codeminimal_form),frontier-reviewer 给出 evidence_by_invariant 结构(extended_form),而弱验证者仅识别 minimal_form。因此 C2 组合(强力实现者 + 弱验证者)稳定失败,其余三个通过——这就是教学信号 signal: tier_dependent_spec

cd book2/examples/tribunal
python3 scripts/matrix.py \
  --spec specs/autoscale_spec.yaml \
  --cases cases/ \
  --tiers matrix/tiers.json \
  --out out/matrix.json

#### 控制:summary.signal != "tier_dependent_spec" —— 需在 validation.md 中解释差异或移入 precedents.md

在生产项目中,此输出由 scripts/tribunal_matrix.py 跟进——它将 judge() 替换为带不同角色提示的真实 qwen -p 调用,但工件接口(summary.signalpairs[*].verdictpairs[*].cases[*].reasons)保持不变。若教材中的矩阵出现差异——退出码 1,且在 smoke_all.sh 中包装为 expect_fail:此处的差异是目标教学信号,而非故障。

为验证者制定的不是笼统请求"检查解决方案",而是严格的证据要求。共三项:钩子日志、JSON Schema 符合性、以及形式化 Given/When/Then 场景。

PreToolUse 日志显示哪些工具调用在执行前被允许或阻止。PostToolUse 日志固定实际结果、退出码、差异校验和以及证据中的事件链接。

JSON Schema 关闭一类错误:智能体生成有说服力的文本但违反数据契约。此类违规示例:

  • 缺少必填字段;
  • 参数类型从 integer 变为 string;
  • 限制设定超出允许范围。

Given/When/Then 场景增加因果检查:在何种初始条件下动作可接受、何种事件触发它、以及何种可观察结果应确认安全性。

flowchart TD
    COORD[协调员:写入需求]
    IMPL[实现者:patch_plan 与 hooks]
    PRE[PreToolUse:阻止危险动作]
    POST[PostToolUse:证据与哈希]
    VER["验证者:与 validation 核对,裁决"]
    SAFETY["安全员:critical_risk 时否决"]
    DISPUTE["争议:requirements/hooks/validation 中的差异"]
    COORD --> IMPL
    IMPL --> PRE
    PRE --> POST
    POST --> VER
    VER --> SAFETY
    SAFETY --> DISPUTE
    DISPUTE --> COORD

冲突仅通过 requirements.mdhooks.mdvalidation.md 中的差异(diff)解决。聊天对话中的任何隐藏修改均排除在证据基础之外。

若实现者认为拒绝有误,他不会以自由形式重写解释。而是添加可检查变更:细化需求、强化钩子或扩展验证场景。

协调员仅在差异与原始规范及具体证据事件关联后,才接受新一轮。否则争议将变为不可复现的私人历史。重复冲突时,将裁决移入 precedents.md——先例日志,每个案例精确记录五个字段:

  • case_id —— 稳定的先例标识符;
  • verdict —— 仲裁规则下的结果(APPROVE / DENY / DEFERRED);
  • evidence_ref —— 指向差异、钩子日志、模式或证实裁决的场景的链接;
  • applies_to —— 先例的适用边界(层级、严格度模式、领域);
  • next_check —— 需重新审视先例的条件。
- case_id: PREC-021
  verdict: DENY
  evidence_ref: "tests/rate_limit_tenant_isolation.json"
  applies_to: "无 tenant_id 去重的速率限制,所有层级,strict_guardrails_prompt"
  next_check: "burst_window_sec 提升至 60 以上或出现 tenant_id 隔离证据"

反古德哈特规则保护文件仲裁免受单一指标以系统退化为代价提升的情况。MTTR(平均恢复时间)不能为虚假升级增长、静默失败(silent failure)或回滚抖动(rollback-flapping)开脱。即使单独一轮显示快速 PASS 也是如此。

因此请在 validation.md 中设定硬性停止条件:

  • false_escalation_rate <= 0.05
  • rollback_flapping < 3/小时
  • silent_p0_ratio == 0

任何阈值超限均将裁决转为 FAIL,与时间收益无关。这将反古德哈特保护从道德警告转变为可执行的仲裁规则。

示例与应用

示例:API 网关自动速率限制(rate limiting)的规范要求在请求突增时临时限制特定客户端(租户),但不阻断整个服务,也不将每次突增升级为 P0。

实现者提出补丁:

  • 在重复数据删除键中添加 tenant_id
  • 引入 burst_window_sec=60 窗口;
  • 每次应用限制后将事件写入 evidence/rate_limit.ndjson

验证者仅在具备三项证据时才做决定:

  • JSON Schema 要求 tenant_idlimit_reasonexpires_at
  • PreToolUse 禁止在无特定客户端作用域的情况下修改全局限制;
  • Given/When/Then 显示单一客户端突增不降低相邻客户端配额。

若缺少任何一项证据,即使补丁技术上看似合理,验证者仍返回 DENY

在 A/B 轮次中,实现者=local-coder, 验证者=frontier-reviewer 配置可能通过。强力验证者能识别模式、钩子日志与场景之间的充分关联。

反向配置 实现者=frontier-reviewer, 验证者=local-coder 可能拒绝同一方案。若安全证据隐藏在实现者的冗长推理中,而非置于 validation.md,则会出现此情况。

这并不意味着一个智能体"正确"而另一个"错误"。仲裁揭示的是需求在模型层级间的可移植性不足。修正应以差异(diff)形式出现——例如添加场景 Given tenant A exceeds burst limit / When tenant B sends normal traffic / Then tenant B quota remains unchanged

Scenario: 突增负载时的租户隔离
  Given 租户 A 发送 800 req/min
  And 租户 B 发送 40 req/min
  When 速率限制钩子应用限制
  Then 租户 A 获得 60 秒临时限制
  And 租户 B 保持基础配额
  And evidence 包含 tenant_id、limit_reason 和 expires_at

针对古德哈特陷阱的压力测试通过单独的小型分析进行。实现者获得将 MTTR 从 6 分钟降至 2 分钟的任务,并提议在首个告警事件时激进自动升级。

强制验证者不仅检查速度,还检查副作用:

  • 虚假升级比例;
  • 回滚抖动频率(rollback-flapping,短时间内的重复回滚);
  • 重复通知量;
  • 冷却窗口(cooldown)是否存在。

若快速方案将 false_escalation_rate 提升至允许阈值以上,协调员在 judgment.md 中记录 FAIL(reason=metric corruption) 并要求修正 validation.md,而非聊天中的表面解释。如此仲裁学会区分真正改进与以运营稳定性为代价的单一数字优化。

总结

文件仲裁使争议解决可复现。协调员管理阶段与协议。实现者仅修改受控工件。验证者要求钩子日志、JSON Schema 和 Given/When/Then。所有冲突通过 requirements.mdhooks.mdvalidation.md 中的差异进行,必要时进入 precedents.md

角色轮换将不同层级的智能体转化为规范稳健性的检验工具。若实现者/验证者配对更换时裁决变化,应强化证据而非依赖特定模型的权威。

反古德哈特规则完成闭环:禁止接受以虚假升级、静默失败或回滚抖动为代价改善 MTTR 的快速决策。此后该仲裁回路将转入层级路由经济学与角色间的令牌分配。

工件与就绪标准

工件就绪条件
judgment.md(或其摘录)裁决有原因和指向差异、钩子日志、模式或 Given/When/Then 的 evidence_ref,而非转述
out/duel.jsonout/invariants.json本地可复现;book2/examples/tribunal 中的可运行示例通过 smoke-pass
precedents.md 记录冲突可重复时创建;否则跳过

完整流程增加:投票角色(验证者/实现者/安全员)在协调员协议下的多轮 judgment.md、同一不变规范在不同层级配对间的裁决矩阵、以及作为仲裁强制组成部分的反古德哈特不变量。当其就绪时,应满足:层级配对间的裁决差异已通过 validation.md 中的差异解释、反古德哈特阈值阻止快速但有害的方案、且重复冲突已录入 precedents.md

实践

  1. cd book2/examples/tribunal && python3 scripts/run_duel.py --spec specs/autoscale_spec.yaml --cases cases --out out/duel.json && python3 scripts/check_invariants.py --metrics metrics/validation_metrics.json --out out/invariants.json && python3 scripts/write_judgment.py --duel-out out/duel.json --invariants-out out/invariants.json --to out/judgment.md —— *预期:out/judgment.md 中有带具体案例 evidence_ref 的最终 verdict。*
  2. 固定验证者有权接受的证据:差异、钩子日志、模式、Given/When/Then。 *预期:out/judgment.md 中的 evidence_ref 字段指向文件而非转述。*
  3. 按如下模板将重复冲突迁移至 capstone/precedents.md(最少字段):
   - case_id: "PREC-001"
     verdict: "DENY"
     evidence_ref: "tests/regression_001.json"
     applies_to: "无完整 audit_trace 的自动修复"
     next_check: "manual_review_floor 变更时重复对决"

*预期:下一次类似争议通过引用 PREC-001 解决,而非重复轮次。*

自测题

  1. 协调员与验证者和安全员有何区别,为何他不与他们平等投票?
  2. 为何争议应通过差异(diff)而非反复沟通解决?
  3. 更换层级智能体时裁决出现分歧说明什么?
  4. 实现者与验证者连续三轮未达成一致,事件队列不断增长。在将争议移交人工处理前,您会固定何种停止条件及何种工件?
我的笔记
0 / 10000

笔记保存在当前浏览器中。在其他设备上将不会显示。

课程菜单

课程

Production SDD for Qwen Code CLI. Part 2
进度 0 / 100