# 设计文档(DESIGN) > 为什么 qa-skills 长这样。本文是公开版设计说明书,记录设计动机与关键决策;**规范性内容以仓库内文件为准**——共享规范在 `skills/core/`,工作流在各 `SKILL.md`;评测契约(EXPECTED.md 冻结门等)在本地维护的评测链路中,公开侧经各版 Release 的增益矩阵快照呈现。 > > 配套阅读:[README](../README.md)(它是什么 / 怎么用)、[CONTRIBUTING](../CONTRIBUTING.md)(架构红线)。 ## 0. 一句话 qa-skills 不是"几个测试 Prompt",而是**方法论 + Skills + Benchmark** 三层体系:方法论沉淀在 `core/` 与 references,Skills 只做工作流编排,Benchmark 用预注册的门回答"这套东西到底有没有用、有多有用"。 ## 1. 两个设计动机(所有决策的出发点) **动机一:Skill 过载——规则越多 ≠ Agent 越强。** 把知识库、工作流、规则引擎、输出模板、QA 方法论五种角色塞进一个 SKILL.md,Agent 有效遵循的规则反而变少。外部实践(Red Hat ACE 团队对 Agent Skill 的总结,2026-07)验证了这条红线:L2 指令超过 500 行后性能开始退化,"试图覆盖整个领域的全能型 Skill 往往使性能退化"。超出 Agent 遵循能力的规则只是噪音,还会稀释真正重要的约束。 **动机二:生成"看似专业但不可执行"的用例。** 覆盖矩阵漂亮、术语专业,但执行者拿着无法开工:入口是虚构的、数据是占位符、判定无时限、断言超出可验证范围。这是 LLM 写测试用例最大的质量问题,因此可执行性在本框架是**一票否决**:不可执行的用例,覆盖再全也计零分。 > 评审任何新增规则时先问一句:它让 Agent 更强了,还是只是更长了? ## 2. 四大支柱 | 支柱 | 含义 | 落地 | |------|------|------| | **Code-aware** | 理解真实代码,而不是只读 PRD;代码是静态事实的最高来源 | `test-case-writing` 代码优先 + 测准声明 | | **Risk-driven** | 围绕风险设计测试,而不是机械生成;风险 → 策略 → 用例推导链 | `core/risk-model.md` + `test-strategy` | | **Evidence-driven** | 所有结论标注证据等级与来源,压幻觉 | `core/evidence.md`(E0–E4 + 裁决规则) | | **Evaluated** | 每个 Skill 有量化指标,回答"提升了多少"而不是"看起来好不好" | 本地评测链路(黄金集 + harness + 冻结门;每版 Release 附增益矩阵快照) | ## 3. 三层架构规范(L1 / L2 / L3) ```text L1 SKILL.md 头部 触发边界:什么时候用、什么时候不用、交给谁 L2 SKILL.md 正文 工作流:每次触发都要走的主干(≤500 行红线) L3 references/ + core/ 方法/规则/模板/方法论:按需加载,工作流步骤中显式引用 ``` 硬规则: 1. **SKILL.md ≤ 500 行**(性能阈值,不是风格建议;`scripts/validate_skills.py` + CI 强制) 2. **每次触发都需要的才进 SKILL.md**,分支性内容一律外移按需加载 3. **外移不降级**:硬约束外移后必须在工作流步骤中被显式引用执行("此步执行 references/xxx.md 全部检查项"),不得变成"可选参考" 4. **宁窄而深,不做全能**:单 Skill 职责收窄,跨阶段协作交给编排层 5. **core/ 是共享依赖单元**:核心文件纯共享引用、不参与触发竞争;core/SKILL.md 仅为安装依赖单元而存在(frontmatter 显式声明不可独立触发);新内容需至少两个 skill 消费 外部参考:[Building Skills for AI Agents: Pitfalls and Best Practices(Red Hat,2026-07)](https://next.redhat.com/2026/07/28/building-skills-for-ai-agents-pitfalls-and-best-practices/)——其"轻量路由 Skill""L1 负向约束""Eval 作为迭代质量门"与本项目 `qa` 编排、触发 / 反触发表、黄金集质量门相互印证。 ## 4. 证据体系:信什么、冲突听谁的 每个发现标注证据等级(E0 用户陈述 → E1 文档 → E2 代码 → E3 运行结果 → E4 交叉验证)与状态(Fact / Inference / Risk / Hypothesis / Verified)。冲突时按问题类型裁决: | 问题类型 | 裁决规则 | |---------|---------| | 静态问题(代码怎么写的) | E2 为王;文档与代码冲突默认以代码为准(测准声明),偏离记附录并澄清 | | 动态问题(系统实际怎么表现) | E3 为王;代码与运行不符本身就是发现(死代码 / 路径未覆盖) | | 意图问题(应该是什么行为) | 用户在澄清环节的明确答复具有最终裁决力,后续阶段不得推翻 | 关键区分:E0(用户初始陈述)是**低证据**、可被代码推翻;用户在澄清环节的**裁决**不是证据、是决策,不可推翻。完整规范见 `core/evidence.md`。 ## 5. 风险模型:评级必须挂证据 Risk Score = Impact × Likelihood(各 1–5)。三条铁律: 1. **没有证据的风险评级视为无效评级**——评级字段必须带 evidence(level + source) 2. **风险等级(Critical / High / Medium / Low)与用例优先级(P0 / P1 / P2)是两套体系**,不同名,避免歧义 3. **双向引用主从**:`case.risk_ref`(Schema 字段)为权威方向;`risk.anchors` 仅人读视图,机器消费一律走 Schema 反查 推导链:证据 → 风险 → 策略 → 用例,每一步可追溯。完整规范见 `core/risk-model.md`。 ### 类型决策矩阵(决策层,2026-08) "这个功能应该怎么测"的第二道决策:**类型域十轴全轴必答**(性能 / 业务安全 / 可靠 / 并发 / 兼容 / 无障碍 / 视觉 / 国际化 / 迁移 / 契约)——纳入必须挂信号(需求级或代码级),排除必须落 G+S 双清单理由,full 档两域合并预算 ≤3(冲突时触发预算裁决检查点)。三条机制要点: - **决策唯一真相源**:`core/test-type-matrix.md`(按轴成节、分组加载),策略产出 type_scope(每轴单行,V1–V5 机械校验兜底) - **G/S 信号分级**:G 级(可 grep)由 `core/scripts/scan_signals.py` 扫描出预填表,agent 从预填修订而非空白生成;S 级(语义模式)agent 照单复核——"脚本无命中"单独不构成排除依据,防脚本盲区被制度化为漏测 - **弱模型优先**:分轴组推进 + 受限选择 + 交付核对。首轮实测(最弱模型,n=3):Off 臂**宽松口径也是零显式决策**(prose 里"提到"了正确类型但没有每轴纳入/排除——盲区在决策纪律,不在类型知识);格式锤复验轮 On 臂类型查全率 0 → 0.88 详见 `docs/decision-layer-design.md`(含取代 v2"性能/安全不自研"决策的论证)。 ## 6. 编排层:`qa` 与"文件即流水线状态" **矛盾**:用户终态是"帮我测试这个需求"一句话,但 Skill 靠 description 触发,多个阶段 Skill 的 description 必然重叠。**解法**:唯一端到端入口(`qa` 独占"端到端 / 帮我测试"意图词)+ 阶段 Skill 各司其职("帮我审一下这份用例"只命中审查)。 `qa` 是**薄编排**:不含任何测试方法与框架知识,只做意图路由、阶段调度、检查点暂停(澄清 / 执行策略 / Bug 定性 / 预算裁决等用户裁决)、收尾报告。它失败的唯一合理原因是编排错误,不是测试判断错误。 ### 文件即流水线状态 每个阶段的产出落盘为文件,下一阶段只消费**文件**而非会话记忆。这有三重身份: 1. **断点续跑**:中断后新会话读文件即可继续,不依赖上下文 2. **上下文隔离的传递介质**:阶段之间唯一的耦合方式 3. **回归追溯的数据基础**:Schema 的 `code_refs` / `risk_ref` 是"用例 ↔ 代码 ↔ 功能"追溯映射的来源 ### 编排会话模型 单任务同时激活的 Skill 超过 1–3 个会引发指令冲突——而流水线要经过 9 个阶段 Skill。解法不是把所有 Skill 装进一个会话,而是**阶段间上下文隔离**: - 每个阶段运行在独立上下文(子会话 / 子代理):只加载当前阶段 SKILL.md + 按需 references + 上一阶段落盘产物 - 主会话只持有流水线状态(阶段清单、产物路径、检查点状态) - 任一时刻活跃指令 ≤ 1–2 个 Skill - **降级路径**:宿主不支持子会话时,退化为顺序会话 + 文件衔接——正确性不受影响,损失的只是上下文卫生 ## 7. 触发与反触发 每个 SKILL.md 必须有 When NOT to Use 且指明"交给谁"。description 措辞按触发 / 反触发表划界(完整表见各 SKILL.md):`qa` 独占端到端意图词,阶段 Skill 只描述本阶段意图并写明"不用于 X → 对应 skill"。没有负向约束的触发竞争会让整个体系形同虚设。 ## 8. 双轨产物 Schema 测试用例是给人还是给机器?都要,但不维护两份: - **markmap 文件**:给人的交付物与唯一人工维护源——业务语言、TC 编号、导读四件套,全部可执行性硬约束作用于此 - **`测试用例.schema.yaml`**:机器可读元数据层,由 skill 从 markmap **单向抽取**,供审查 / 回归 / 执行层消费,永远可由 markmap 再生 这个设计同时服务三类消费者:测试工程师读 markmap 开工;`test-case-review` 用 Schema 做覆盖分母;`regression-testing` 用 `code_refs` / `risk_ref` 做影响面分析——没有它,回归范围选择就只是"让模型读一遍 diff 猜"。 ## 9. 可执行性:一票否决的标准 先理解 AI 为什么会生成不可执行的用例: | # | 失败模式 | 典型表现 | |---|---------|---------| | 1 | 凭空想象系统 | 没见过真实页面 / 接口,凭 PRD 虚构入口、字段、文案 | | 2 | 写给评审者而非执行者 | 追求覆盖矩阵漂亮,不关心执行者能否操作 | | 3 | 前置不可得 | 默认环境 / 账号 / 数据随手就有,不交代从哪获得 | | 4 | 判定不可操作 | 预期结果写"功能正常";异步行为无判定时限 | | 5 | 断言超出验证强度 | 两个样本断言"全局唯一";UI 操作断言数据库约束 | 对应的 8 条硬标准(细则见 `core/executability.md`):代码优先、执行模型判定(无 UI 转开发协作清单)、具体数据禁占位符、页面可达性、异步判定时限、断言范围 ≤ 验证强度、前置可得性(TODO 指明找谁)、零上下文新人复述。 **闭环靠评测**:harness 的 Executability 指标量化脏率,不可执行用例的有效覆盖记零。 ## 10. 评测体系:预注册的门,如实的数字 Eval 要回答的是"**用了 Skill 后,Agent 的测试能力到底提升了多少**",不是"看起来好不好"。方法学对齐行业实践: - **多样本生成**(n=3)量化生成方差——单采样的表观差距可能是抽到了弱基线(本项目实测过:+28.8pp 的校准值被多样本复验证实为噪声,实际 +6.2pp) - **任务层配对 bootstrap** 报 95%CI;成对评审 + 位置互换(MT-Bench 范式);judge 3 采样多数表决 + GT-id 本地校验 - **真实执行验证**(SWE-bench 式):E2E 产物跑真实浏览器 + mock 被测应用,API 产物跑真实 HTTP 服务 + pytest - **GT 标注独立审计**:标注者不得既写标注又复核;一致率落盘 - **门预注册冻结**(pre-registration):阈值在校准轮后、验证轮前冻结并记录于 EXPECTED.md(本地评测链路);验证轮结果按冻结门判定,**不因数据改门**;任何阈值修订须独立提交先行入库 - **失败与反向结果如实记录**:门判定 4/7、API 执行的历史反向结果(后经逐失败归类定案为评测侧缺陷而非 skill 缺陷,干净复验后两组持平并勘误,见 CHANGELOG 2026-08-26)、成本 3.3× 都在 README 与报告中呈现——评测失去诚实就失去意义 完整契约(本地评测链路维护,不随仓库分发):EXPECTED.md(冻结门)、harness README(方法学)、最新运行报告——公开侧浓缩为每版 Release 附带的增益矩阵快照。 ## 11. 设计决策速查 | 决策 | 备选 | 为什么选这个 | |------|------|-------------| | 10 个窄 Skill + 薄编排 | 1 个全能 Skill | 500 行红线 + 触发边界清晰(§1、§3) | | markmap 为唯一人工维护源 | 人维护双份 | 双份必然漂移;Schema 可再生(§8) | | 风险与优先级两套命名 | 统一 P0–P3 | 同名歧义会让"P0 风险"与"P0 用例"混淆(§5) | | 类型域方法论自研、执行对接专业工具(性能 / 安全为矩阵正式轴) | 全部自研专项 Skill / 完全不自研仅 handoff 占位 | 方法论与决策是框架灵魂,工具装执行;首版"不自研"造成 handoff 断链,2026-08 决策层升级(`docs/decision-layer-design.md`) | | 检查点暂停等用户裁决 | Agent 自动决策 | Bug 定性 / 执行策略是人的责任;Agent 只提案 | | 评测先于扩容建设 | 先堆功能再评测 | 没有度量的迭代是凭感觉;黄金集同时是质量门 |