--- name: skill-tester phases: ["all"] description: >- SKILL 体系自动化测试工具。通过 LLM-as-Judge 模式对 SKILL.md 的行为逻辑进行回归测试, 验证阶段守卫、规则遵循、输出格式等维度。触发关键词:"测试Skill"、"测试 [skill名]"、 "回归测试"、"skill test"、"跑测试"。 --- # 相位守卫(Phase Guard) **本 Skill 加载后的首个强制动作:** 1. 读取 `.opencode/phase/current.json` 2. 若 `phases` 不包含 `"all"` 且当前 `phase` 值不在 `phases` 列表中: - 立即中止,输出:"当前阶段为 [phase],skill-tester Skill 不可用。" - 不得执行本 Skill 的任何后续流程 3. 否则:继续执行 --- # 概述 skill-tester 是元层测试工具,分两层: - **Layer 1(静态检查)**:无需 LLM,毫秒级。检测文件间交叉引用一致性。每次框架变更后必跑。 - **Layer 2(行为测试)**:LLM-as-Judge,验证 SKILL.md 的指令逻辑。 **建议顺序**:先跑 Layer 1(免费+快),通过后再跑 Layer 2(消耗 token)。 **核心原理**:将 SKILL.md 内容 + 模拟用户输入注入 sub-agent,观察其输出是否符合预期, 再用另一个 sub-agent 作为裁判评分。 **不测试什么**:opencode 的 Skill 加载机制本身(那是 opencode 的责任)。 **测试什么**:SKILL.md 中的指令逻辑——当 LLM 忠实执行这些指令时,产生正确的行为。 --- # Layer 1:静态一致性检查(无需 LLM) ## 概述 Layer 1 是纯文件级检查,检测 canonical-manifest.json、opencode-init SKILL.md、 registry.md、各 SKILL.md 之间的交叉引用一致性。**不需要 LLM 调用,毫秒级运行。** 适合作为 git pre-commit hook 或 CI 检查项。 ### 安装 git pre-commit hook(可选) ``` # Windows copy .opencode\skills\skill-tester\hooks\pre-commit .git\hooks\pre-commit # Unix ln -sf ../../.opencode/skills/skill-tester/hooks/pre-commit .git/hooks/pre-commit ``` 安装后,每次 `git commit` 如果涉及 `.opencode/skills/` 下的文件变更,会自动运行 7 项检查。不通过则阻止提交。 ## 检查项 | 检查 | 描述 | 覆盖的问题 | |------|------|-----------| | manifest-skills-sync | manifest canonical_skills 与 init Skills 白名单一致 | 新增 Skill 后忘记更新 init → 被误删 | | manifest-phase-sync | manifest template_phase_files 与 init 阶段数据占位目录一致 | 新增 phase 文件后落入 C 组 | | registry-types | registry 中 phases≠["all"] 的 Skill 类型为"基础设施" | game-design 被标为"项目级"而被误删 | | phase-guard-all | 所有 SKILL.md Phase Guard 包含 "all" 处理 | "all" 特殊值未处理导致基础设施 Skill 被错误拒绝 | | init-templates | manifest 每个文件在 init 模板内容章节有对应模板 | 缺少重置模板导致 init 时文件丢失 | | frontmatter | 所有 SKILL.md 的 YAML frontmatter 完整(name + phases) | opencode 无法注册该 Skill | ## 运行方式 ```bash python .opencode/skills/skill-tester/static-checks/run.py ``` 退出码:全部通过 = 0,有失败 = 1。可直接集成到 CI/pre-commit。 ## 新增检查项 编辑 `static-checks/run.py`,在 `CHECKS` 列表追加新函数即可,格式为: ```python ("check-id", "检查名称", check_function) ``` --- # Layer 2:LLM-as-Judge 行为测试 --- # 操作 A:测试单个 Skill ## 触发 用户说"测试 [Skill 名称]"、如 "测试 game-design"、"测试 dev-changelog"。 ## 流程 ``` 0. 【强制】先运行 Layer 1 静态检查: python .opencode/skills/skill-tester/static-checks/run.py → 如有 FAIL,提示用户先修复再跑 Layer 2 → 全部 PASS 则继续 1. 读取目标 Skill 的 SKILL.md 2. 读取 .opencode/skills/skill-tester/test-cases/ 下匹配该 Skill 的测试用例 3. 列出测试用例清单,询问用户确认 4. 用户确认后,逐一执行 5. 汇总报告 ``` ## 步骤 3:测试用例预览 ``` Agent 输出: "找到 [N] 个针对 [Skill名] 的测试用例: | # | ID | 场景 | 严重度 | |---|-----|------|--------| | 1 | phase-guard-001 | 非匹配阶段拒绝加载 | critical | | 2 | ... | ... | ... | 预计消耗约 [估算token] tokens。是否全部执行?(y/n/选择特定用例)" ``` ## 步骤 4:单用例执行 ### 4.1 构造模拟 Sub-agent 将以下内容组装为一个 prompt,通过 Task tool(sub-agent type = general)执行: ``` 你正在模拟一个 opencode agent,该 agent 刚刚加载了以下 Skill: --- [目标 SKILL.md 的完整内容] --- **当前会话上下文:** - 当前阶段 (phase):[test_case.phase] - 用户消息:"[test_case.user_message]" - state.json 状态:[test_case.state](如适用) **你的任务**:严格按照上述 Skill 中的指令行事。 你拥有所有 opencode agent 的工具(bash/read/write/edit/...)。 用户说了:"[test_case.user_message]" 请输出你的响应。只输出你作为 agent 会输出的内容。 注意: - 如果是 phase guard 测试,第一个行为应该是检查阶段并可能中止 - 如果 Skill 要求写文件,输出你打算写什么以及写到哪个文件(但不要实际写) - 如果 Skill 有强制规则(如 Hallucination 防御),务必遵守 ``` ### 4.2 执行并收集输出 ``` Agent 调用 Task tool → 等待 sub-agent 完成 → 收集其文本输出 ``` ### 4.3 Judge 评估 将模拟 sub-agent 的输出 + 预期行为 + 评分标准传给 Judge sub-agent。 Judge 的详细指令见 [judge-prompt.md](judge-prompt.md)。 调用方式: ``` Agent 调用 Task tool,prompt 为 judge-prompt.md 的内容(已填充变量)→ 等待完成 ``` ### 4.4 记录结果 ```json { "test_id": "phase-guard-001", "skill": "game-design", "timestamp": "...", "scores": { "behavior_match": 5, "output_clarity": 4, "rule_compliance": 5 }, "overall": 4.7, "judge_feedback": "Agent 正确识别了阶段不匹配..." } ``` ## 步骤 5:汇总报告 ``` Agent 输出(Markdown): ## 测试报告:[Skill 名称] **执行时间**:[timestamp] **测试用例数**:[total] | 通过:[pass] | 失败:[fail] | 跳过:[skip] | # | ID | 场景 | 行为 | 清晰度 | 合规 | 总分 | 状态 | |---|-----|------|------|--------|------|------|------| | 1 | phase-guard-001 | 阶段拒绝 | 5 | 4 | 5 | 4.7 | ✅ | | 2 | ... | ... | ... | ... | ... | ... | ❌ | ### 失败用例详情 #### [ID] — [场景] - **预期**:[expected 描述] - **实际**:[agent 实际输出摘要] - **裁判反馈**:[judge 的具体反馈] - **建议**:[改进建议] ``` --- # 操作 B:回归测试(全部 Skill) ## 触发 用户说"回归测试"、"跑全部测试"、"test all skills"。 ## 流程 ``` 1. 读取 test-cases/ 下所有测试用例 2. 按 Skill 分组展示 3. 询问用户确认(因为消耗较大) 4. 按 Skill 逐一执行(每个 Skill 内部用例并行执行) 5. 汇总全部报告 ``` ## 执行策略 - 同一 Skill 内的多个用例可以**并行执行**(无状态依赖) - 不同 Skill 之间**顺序执行**(避免混淆) - 单个用例超时 60 秒 - 如有用例执行失败(sub-agent 错误),标记为 ERROR 而非 FAIL --- # 操作 C:查看历史报告 ## 触发 用户说"查看测试报告"、"上次测试结果"。 ## 流程 读取 `.opencode/skills/skill-tester/reports/` 下最新报告,展示摘要。 --- # 评分标准说明 每个测试用例在 3 个维度上评分(1-5): | 维度 | 含义 | 5 分标准 | |------|------|---------| | **行为匹配 (behavior_match)** | Agent 的输出行为是否符合预期 | 核心决策(如加载/拒绝加载)完全正确 | | **输出清晰度 (output_clarity)** | 输出是否清晰、无歧义 | 信息完整、结构清楚、用户可直接理解 | | **规则合规 (rule_compliance)** | 是否遵守了 SKILL.md 中的强制规则 | 所有强制检查点均已执行 | **通过标准**:总分 >= 4.0(即平均每维度 >= 4.0)。 **警告标准**:3.0 <= 总分 < 4.0。 **失败标准**:总分 < 3.0。 --- # 自迭代日志 本节记录使用本 Skill 过程中发现的必要检查项。 ### 已知必要检查 1. **Layer 1 必须在每次框架结构变更后运行** — 新增 Skill、修改 manifest 分组、新增数据文件后,`static-checks/run.py` 的 6 项检查必须全部通过。历史教训:新增 `template_phase_files` 后未同步 init Skill 的 3 个截面,导致 phase 文件落入 C 组;`game-design` 被标为"项目级"导致 init 时被 registry 删除。