关于 surrogate-verifier
用于独立验证 skill 包的技能,通过 skill 定义、任务提示和输出生成结构化断言与失败诊断。它隔离生成器的推理上下文,以减少验证偏差;本身不执行断言。
主要功能
- 01基于任务生成 5–10 条断言
- 02覆盖完整性、格式与事实信号
- 03按根因分类失败
- 04提供可执行的修复建议
- 05不执行测试,仅检查文本输出
适用场景
- 01为 skill 包生成评测断言
- 02根据失败断言定位定义或流程问题
- 03在隔离上下文中审查 Agent 生成结果
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ mathews-tom/ armory --skill surrogate-verifier安装后在 Claude Code 中输入/surrogate-verifier确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
evals/cases.yamlreferences/assertion-patterns.mddiagnostic-templates.md详细介绍
替代验证器
通过信息隔离验证,为技能包生成结构化测试断言和失败诊断。验证器无法访问技能生成器的推理过程——它只能看到技能定义、任务提示词和输出产物。这种隔离可避免确认偏误,是共同演进式生成中提升技能质量的最大因素(据 EvoSkills 称,提升 30 个百分点)。
参考文件
| 文件 | 内容 | 加载时机 |
|---|---|---|
references/assertion-patterns.md | 按技能类别整理的断言目录及权重指南 | 始终 |
references/diagnostic-templates.md | 包含根本原因类别的失败诊断模板 | 生成失败报告时 |
信息隔离协议
这是最关键的约束。违反隔离要求会降低验证质量。
验证器不得访问:
- 生成器的对话历史或推理链
- 先前的演进迭代或优化上下文
- 生成器的内部笔记或决策依据
- 下方明确列出的内容之外的任何上下文
验证器仅接收:
- 技能的
SKILL.md内容(定义文件) - 一个或多个代表预期用途的任务提示词
- 技能的输出(诊断失败时)
scripts/eval_assertions.py的断言结果(诊断失败时)
实现方式:由 test-engineer Agent 调用时,必须将此技能加载到一个单独启动的 Agent 中,并使用 isolation: "worktree";或者至少使用一个没有共享上下文的新会话。调用方 Agent 应将产物作为明确文本传递,而不是引用对话内容。
工作流
模式 1:生成断言
根据技能定义和任务提示词为技能生成断言。
阶段 1:技能分析
阅读 SKILL.md 定义并提取:
- 声明的能力——技能声称能做什么(根据描述和工作流章节)
- 输出格式——技能输出的预期结构(Markdown、JSON、表格等)
- 错误处理——文档中说明的失败模式和恢复路径
- 先决条件——所需工具、依赖项或上下文
- 触发边界——技能不处理的内容(负向范围)
阶段 2:断言设计
针对每个任务提示词,生成 5–10 条断言,覆盖以下维度:
| 维度 | 使用的断言类型 | 目的 |
|---|---|---|
| 输出完整性 | contains、matches_regex | 包含所有声明的章节/组件 |
| 格式合规性 | output_format、contains | 输出符合声明的结构 |
| 事实信号 | contains、not_contains | 包含关键领域术语,排除典型问题 |
| 工具使用 | calls_tool | 调用了预期工具 |
| 负向约束 | not_contains | 不包含禁止的模式 |
权重分配:
- 输出完整性断言:权重 1.0(必须具备)
- 格式合规性:权重 0.8(结构正确性)
- 事实信号:权重 0.6(内容质量)
- 工具使用:权重 0.5(方法验证)
- 负向约束:权重 0.3(缺失检查是较弱的信号)
按类别整理的断言目录请参见 references/assertion-patterns.md。
阶段 3:输出
按照 evals/cases.yaml 架构格式生成断言:
assertions:
- type: contains
target: "## Scalability"
weight: 1.0
- type: output_format
target: markdown_table
weight: 0.8
- type: not_contains
target: "TODO"
weight: 0.3
- type: calls_tool
target: Read
weight: 0.5
上下文上限: 使用的上下文窗口不得超过可用窗口的 70%。如果技能定义很长,请重点围绕工作流阶段和输出格式部分生成断言。概述内容,不要逐字引用。
模式 2:失败诊断
当预言机返回 fail 时,生成结构化诊断,说明失败原因。
输入
- 技能的
SKILL.md(与模式 1 相同) - 已执行的任务提示词
- 失败的输出
- 断言结果:哪些断言通过、哪些失败,以及详细信息
阶段 1:失败分类
将每项失败的断言归类到一个根因类别:
| 类别 | 信号 | 严重程度 |
|---|---|---|
| 缺少能力 | 声明的功能对应的 contains 断言失败 | 高 |
| 格式不匹配 | output_format 断言失败 | 高 |
| 输出不完整 | 同一部分中的多个 contains 断言失败 | 中 |
| 幻觉内容 | not_contains 断言失败(存在禁止的模式) | 高 |
| 工具使用错误 | calls_tool 断言失败 | 中 |
| 部分成功 | 同一组中的部分断言通过,其他断言失败 | 低 |
阶段 2:根因分析
针对每项失败的断言:
- 找出
SKILL.md中承诺提供缺失能力的具体部分 - 比较技能定义中的指示与实际输出内容
- 推测差距产生的原因(缺少工作流步骤、指示不明确、工具选择错误)
阶段 3:修复建议
针对每个根因,提供具体可执行的修复方案:
- 缺少能力:“在阶段 2 和阶段 3 之间添加一个工作流步骤,明确生成 [X]”
- 格式不匹配:“将输出格式指示从‘生成摘要’改为‘生成包含以下列的 Markdown 表格:[A、B、C]’”
- 幻觉内容:“在工作流中添加一条负面约束:‘除非满足 [条件],否则不要包含 [X]’”
- 工具使用错误:“将‘使用 Bash 读取文件’替换为‘使用 Read 工具读取文件内容’”
阶段 4:诊断输出
生成结构化诊断字符串:
DIAGNOSTIC: [skill-name] failed on [task-prompt-summary]
FAILED ASSERTIONS (N/M):
1. [SEVERITY] type=contains target="..." — Missing capability: [explanation]
2. [SEVERITY] type=output_format target="..." — Format mismatch: [explanation]
ROOT CAUSES:
- [category]: [specific explanation with SKILL.md section reference]
REMEDIATION:
1. [Concrete change to SKILL.md with exact section and wording]
2. [Concrete change to workflow with step numbers]
请参阅 references/diagnostic-templates.md,了解各根因类别的示例。
预算参数
根据 EvoSkills 算法 1:
- 上下文上限: 0.7(可用上下文窗口的 70%)
- 代理重试上限: 每轮预言机最多 15 次
- 预言机轮数上限: 5 轮(由编排 Agent 强制执行,而非验证器)
验证器不会跟踪自身预算;test-engineer Agent 负责管理迭代次数限制。
局限性
- 无法执行: 验证器会生成断言,但不会执行断言。执行由
scripts/run_evals.py(预言机)负责。 - 仅文本验证: 无法验证视觉输出、交互行为或副作用。断言仅针对文本输出进行操作。
- 单轮范围: 每次验证相互独立。验证器不会记住之前的轮次(编排 Agent 会按需提供上下文)。
- 断言粒度: 这 5 种断言类型覆盖了常见模式,但无法满足所有可能的验证需求。扩展断言类型需要修改
scripts/eval_assertions.py。
错误处理
| 错误 | 解决方案 |
|---|---|
| 技能定义过大 | 仅保留工作流阶段和输出格式部分的摘要 |
| 无法生成断言 | 返回空断言列表并发出警告;技能可能过于含糊 |
| 输出格式不明确 | 默认使用 contains 断言;避免检查 output_format |
| 超出上下文上限 | 截断诊断详情;保留失败断言列表 |