Blind Tribunal——盲评陪审团
Effort: heavy — 八位陪审员,每人一个视角,按层级路由到够用且最省的模型家族,每一轮都用全新信封重新开庭,直到全员一致;把它花在无人审查就落地的自主改动上。消除:只凭构建者一面之词把关的脱缰落地。
这套评审循环让人可以放心走开,agent 也不会脱缰。一个陪审团盲审改动,作者信息全部剥除。每条发现都变成一条新的失败测试。循环往复,直到每位陪审员都放行。任何东西都不能只凭构建者的一面之词合入。
什么时候跑
- 任何没有人会 review 的自主改动,合入之前。
- 任何高爆炸半径的改动:涉及安全、碰数据、挨着权限。
- 一个评审不够、你想要多个独立视角看同一份产物的时候。
席位
八位陪审员,每人一个视角。每位都是与构建者不同家族的模型(同一厂商 = 同一家族)。 让一个陪审员什么都查,等于什么都查不好。
| 陪审员 | 视角 id | 层级 | 它问的问题 |
|---|---|---|---|
| Defect(缺陷) | defect |
通才 | 到底什么会坏?逻辑漏洞、语法错误、新引入的缺陷。 |
| Proportion(分寸) | proportion |
通才 | 大小对吗?过度设计,还是与意图相称? |
| Consequence(后果) | operator_consequence |
操作者安全 | 一个人在自己机器上运行它,什么是破坏性的、不安全的、有害的? |
| Reversibility(可逆) | reversibility |
深层状态 | 会留下不可逆的副作用吗?半路挂掉,系统能干净回滚吗? |
| Continuity(连续) | state_continuity |
深层状态 | 会遗留孤儿变量、覆盖全局状态、丢掉下游节点需要的上下文吗? |
| Economy(经济) | resource_economy |
快速结构 | 未优化的循环、冗余的网络/API 调用、内存膨胀? |
| Boundary(边界) | boundary_condition |
快速结构 | 输入为空、为 null、类型不对或故意畸形时,能优雅失败吗? |
| Telemetry(遥测) | telemetry |
操作者安全 | 这里出了故障,能从日志和错误处理里诊断出来吗? |
路由层级(先用够用且最省的路线): 深层状态 → 最大的上下文与最深的推理,最好经由
一个能只读仓库的 harness(绝不写入);快速结构 → 先用免费的本地 GPU,并与一个便宜的云校验
模型融合:两者判同一份 prompt,只有都通过这一镜才通过;云全断时保留本地裁决,但标记为
UNVERIFIED,绝不悄悄算作"已校验";本地模型必须看到完整的工件(按 prompt 设定 num_ctx——
Ollama 默认 4096 会静默截断——放不下的在发送前就拒绝);校验模型绝不与主席位同一家族,UNVERIFIED 的席位算作搁置(绝不算一致通过);harness 陪审员以 read-only 运行,每次召集都带 run_id 并最后写入摘要;之后才轮到低延迟云模型;操作者安全
→ 你最强、且有安全基础的编码模型;通才 → 一个
大而可靠的通才模型。每条阶梯都以本地兜底一级收尾。
单模型条件。 只有一个模型家族可用时,明着降级:用一个从没见过作者对话的全新 上下文或会话当盲评审,或者由人来审那份脱敏信封。报告必须写明这道门被削弱了—— "同家族盲评,非跨家族"——绝不悄悄假装跨家族的门还立着。
构建者必须声明,排除是结构性的
"与构建者不同家族"曾是要求陪审员记住的规则。在法庭对自身的测试中,操作者安全席位由构建候选代码的同一个模型领衔, 而没有任何机制记录或排除它:作者连续两轮给自己的工作打分。因此:
- 召集时点名构建者(
--builder <模型或家族>)。运行记录携带builder_family。该家族的每一级在任何派发之前、 在每一架梯子上都被大声拒绝。没有可用级别的镜头进入等待——绝不回落到构建者。 - 同一供应商 = 同一家族。 一次声明排除整个供应商。
- 在真实梯子上证明,而不是在测试里: 路由表必须显示其席位已落到另一家族。否则排除只是装饰。
信封
陪审员看不到仓库、构建者、对话。他们只看到一个信封:
- 改动碰过的每个文件的完整当前版本,加上对应的测试文件。绝不给裸的 diff 片段 ——片段藏起了周边契约,会诱发假发现。
- 评审契约:一行话说清改动意图,加上放行标准。
- 零作者信息。 没有名字、没有模型 id、没有 commit 作者、没有聊天记录。身份一旦 泄漏,信封构建就大声失败——绝不在非盲状态下评审。
- 不写旧行为的说明文字。 描述代码"以前怎么干"会种下幻影缺陷。让文件自己说话。
裁决
严格的机器可解析 JSON,单个对象,不带说明文字:
{"verdict": "pass" | "refuse",
"findings": [{"severity": "blocker|major|minor|info",
"claim": "...", "evidence": "..."}]}
- 列出
[blocker]或[major]发现的 pass 不是 pass。 它自相矛盾,按关闭失败处理为 refuse,并点名矛盾的严重级别。 - 针对与所坐席位不同镜头的裁决是被拒绝的一级,不是裁决:记录两个镜头,继续走到下一级;只有所有级别都答错,镜头才进入等待。绝不是 pass。
- 输出目录先被认领再被清扫。 器官为其认领的目录盖章(stamp);带有这些文件形态却没有印章的目录被拒绝,点名文件与补救办法,什么都不删。只含他人文件的目录从未处于风险中,不会被阻止。
- 一个镜头崩溃绝不丢弃已付费的裁决。 每个席位失败按镜头记录;裁决与摘要在抛出错误之前写入。
- 变更证据点名被重写的文件(
changed_paths)。 - 器官写出的一切仅所有者可读(0600)。
- 溢出的本地模型只由最后一个持有者卸载。 两个镜头可能共用一张卡;先完成的不能在另一个调用中途抽走模型。
- 装不下工件的一级在调用前就被跳过,原因记录在案;容量拒绝是一种类型,行走继续——绝不停机。
- 回答得很糟的陪审员——乱码、非 JSON、拒答文本——按 refuse 计;从未回答的 陪审员(传输失败、连不上)是 hold:通过 fleet-ladder 换人重新入席,绝不悄悄当作放行。每位应答的陪审员每轮只有一次机会——不重试。
- 零发现、零证据的裸放行是一张低信息票。它算数,但绝不能当唯一证据——两张 裸放行压不过一张有细节的拒绝。一张有分量的放行会写明它查了什么。
循环
- 红灯先行:在修复动工之前提交会失败的契约测试,并记下那个 commit。构建者不许碰 测试(red-first)。
- 构建到绿。
- 用当前文件构建信封。
- 请八位陪审员按层级入席——与构建者不同家族(fleet-ladder 解析谁活着)。
- 每位陪审员不只读,还要验证:新测试通过;回归套件不差于基线;再加一道假绿检查 ——一条本该失败的测试(把 bug 重新引入)确实失败了。假绿即拒绝。
- 一旦有拒绝:每条发现——blocker、major、minor 全部——都变成一条新的失败测试, 且失败原因正是发现所指的真实原因。修掉它。在修订后的文件上重建信封。全体陪审员 重新开庭。基于过期文件的裁决不算裁决。
- 只有全票放行才能合入。最后一轮提出的 minor 发现也要关掉,绝不延后——"先修 blocker,minor 以后再说"正是本技能要堵死的那个漏洞。一条发现的结局要么是修好, 要么是带着记录在案的证据被驳回,绝不停在半路。
页脚点名镜头,被拒的梯级留下原话,底线是三级深
第 4 轮在零拒绝的情况下让两个镜头悬置,而每一环都在记录上。由此得出三条法则:
- 把答案的形状写在答案旁边。 协议页脚携带镜头的字面名称(
"lens": "defect"),绝不是<your lens>占位符。一位陪审模型被要求回忆 350 KB 之前声明的镜头,而工件本身点名了全部八个镜头,结果两轮里答错镜头三次。渲染时填好占位符。 - 被拒的梯级把原话留在记录上。 答错镜头或被作废的裁决,会在被拒条目上带一段有界的
raw_tail,让下一轮读到原因,而不是去推测。 - 两级云端不算底线。 每个层级在本地尾部之前至少有三个未声明
context_tokens的梯级(它们能承载 120k token 的工件)。一次答错镜头加一次作废,绝不能让镜头悬置。 - 结构化裁决绝不与思考共用预算。 一个被要求给出裸 JSON 裁决的推理模型,把 65536 token 的预算全花在思考一个 131k token 的工件上,什么都没输出(
finish_reason=length);角色的时间上限随后在走梯中途杀掉了下一级。每个要求 JSON 对象裁决的云端梯级都关闭推理通道(reasoning_effort: none),校验梯子在它后面保留一个走纯 HTTP 的第三家族。 - 陪审团开庭时,别的东西不得写入它的仓库。 一个并发评分器放在检出目录里的状态文件在某个席位下改变了字节,机关诚实地作废了那份裁决:它无法归因一次改动。把写入者串行化,或者在同一提交的独立 worktree 上开庭。
硬规则——破一条,评审作废
幸存者是一种主张;绿色证明也是一种主张。 在隔离的树中、用能熬过机器负载的上限,手工重跑每个上报的幸存突变体。 超时不是幸存者;收集错误不是击杀。证明工具的每条裁决路径都必须能说出 INVALID,无突变基线不是干净绿色时拒绝输出任何裁决。
构建者永远不评自己的活:不能是同一个实例,也不能是同一个家族。
陪审员拒绝的成色,取决于信封。 从一条发现写测试之前,先对照真实文件核实它。 发现指向信封里根本没装的代码?该修的是信封,不是代码。
收敛看每轮的新发现数,不看总数。新发现连续两轮持平或增长:停下,上报给人。 绝不硬磨。
绝不为了通过而削弱或改动失败测试。陪审员核验测试文件自红色 commit 起未被改动。
全票放行只是开了门,不是终点。合入,然后在真实表面上现场证明能力。没有现场证明 的绿不算完。
搭配使用
- red-first——构建者动工前就提交的失败契约。
- sniper-testing——真实副作用、范围化运行、不搞 mock 剧场。
- seam-engineering——修类而非修例、横扫同类、落一道守卫。
- repair-loop——这套陪审团评审的正是这个构建循环。
- blind-eval——问题是品味而非缺陷时,用这个更轻的保留或回滚门。
Scaffold credit: Matt Pocock, grill-me / grilling (mattpocock/skills, MIT). The cross-family blind adversarial tribunal design is BACKS AIOS.