Appearance
AI 技能工程:测试资产三层分层架构设计
以「回票跟进助手 wuba-invoice-followup」为实战案例,总结从 v0.1.2 → v0.2.5 演进过程中形成的标准化技能测试工程架构。
背景与问题
在 AI 技能(Claw Skill)的迭代过程中,随着版本增多,测试资产容易演变为"散落各处的泥潭":
- 业务反馈的排查记录(Markdown)和机器可读的回归数据(JSON)混放在同一目录,没有清晰边界
examples/是test-skills/的完全镜像拷贝,每次同步都产生大量冗余 difftest_cases.json(测试数据)放在执行层而不是文档层,导致"数据归属模糊"- 报告文件(自动生成)与手工编写的文档放在同一个根目录,混乱
最终架构:三层职责分离
财务接入美事claw需求/
│
├── test-cases/ ← 【测试资产层】产研可读 + 机器可读
│ ├── incidents/ ← 线上故障 / 产研内部验证报告(按日期归档)
│ │ └── case_7.6.md
│ ├── regression/ ← 正式回归用例(机器可读,自动化执行)
│ │ ├── test_cases.json ← ✅ 唯一数据源
│ │ └── test-execution-report.md ← 脚本自动生成
│ ├── call-flow-architecture.md ← 技术架构说明文档
│ ├── user-handbook.md ← 用户手册(面向财务业务人员)
│ └── README.md
│
├── test-skills/wuba-invoice-followup/ ← 【技能执行层】开发 & 测试沙箱
│ ├── invoice_followup_skill.py ← 核心逻辑(唯一权威代码源)
│ ├── run_regression_tests.py ← 测试运行器(跨目录读取数据)
│ ├── SKILL.md / CHANGELOG.md / README.md / _meta.json
│ ├── references/ ← API 设计文档、架构参考
│ └── skills/ ← 依赖子技能
│
├── delivery-skills/wuba-invoice-followup/ ← 【生产交付层】最小干净包
│ ├── invoice_followup_skill.py
│ ├── SKILL.md
│ ├── CHANGELOG.md
│ └── README.md
│
└── examples/ ← 【集成示例层】(极简,仅一个文件)
└── README.md ← 外部研发集成引导说明三层职责对比
| 层级 | 目录 | 职责 | 受众 |
|---|---|---|---|
| 测试资产层 | test-cases/ | 人工可读文档 + 机器可读用例数据 | 产研、QA、AI |
| 技能执行层 | test-skills/ | 代码开发、本地回归执行 | 研发工程师 |
| 生产交付层 | delivery-skills/ | 纯净发布包,上传技能市场 | Claw 平台 / 用户 |
核心生命周期流水线
📥 业务反馈 / 线上异常
│
▼
test-cases/incidents/case_X.Y.md ← 人工整理故障现场
│
产研分析 → 提炼标准用例
│
▼
test-cases/regression/test_cases.json ← 追加新 JSON entry
│
▼
test-skills/.../run_regression_tests.py ← 本地执行回归
│
▼
test-cases/regression/test-execution-report.md ← 自动写回报告
│
回归 100% 通过
│
▼
node scripts/sync_invoice_followup.mjs ← 分流生成交付包
│
┌─────────┴──────────┐
▼ ▼
delivery-skills/ examples/README.md
(4 个白名单文件) (仅集成说明)
│
▼
wubahub publish delivery-skills/... ← 发布至内部技能市场examples/ 瘦身策略
问题:同步脚本曾将 test-skills/ 全量复制到 examples/,包括 test_cases.json、run_regression_tests.py、skills/、references/ 等,导致每次同步产生大量冗余 diff。
解决方案:在 sync_invoice_followup.mjs 中将 examples/ 的同步策略改为"只拷贝 README.md":
javascript
// ❌ 旧方案(全量拷贝)
copyRecursiveSync(SRC_DIR, TARGET_EXAMPLES, filterFn);
// ✅ 新方案(仅同步集成说明)
const readmeSrc = path.join(SRC_DIR, 'README.md');
const readmeDest = path.join(TARGET_EXAMPLES, 'README.md');
fs.copyFileSync(readmeSrc, readmeDest);效果:examples/ 从 11 个文件 / 2 个子目录,缩减为 1 个文件。每次 commit diff 减少 ~2400 行。
test_cases.json 标准结构
每个 case 包含:id、name、description、input(技能入参)、mockData(发票 + 凭证 Mock 数据)、expectedSummary(期望输出)。
json
{
"id": "case-01",
"name": "完美回票已入账:R1-R5 全命中",
"description": "四维度全部命中,判定为 FULL",
"input": {
"buyerName": "北京五八信息技术有限公司",
"sellerName": "河北顺丰速运有限公司",
"queryMonth": "2026-06"
},
"mockData": {
"invoices": [...],
"vouchers": [...]
},
"expectedSummary": {
"totalInvoices": 1,
"fullyMatched": 1,
"suspiciousMatched": 0,
"notMatched": 0
}
}迭代规范:
- 每当线上出现新的异常场景,先在
incidents/归档,再在regression/test_cases.json追加 - ID 按
case-N顺序递增,不删除历史 case,只新增 - 每次提交新 case 必须确保
run_regression_tests.py100% 通过才合并
cybervisor.yaml 流水线集成
在 finance-spec/cybervisor.yaml 中,SyncInvoiceFollowup 管道负责整个同步链路:
yaml
SyncInvoiceFollowup:
description: "同步更新回票跟进助手技能、子技能、文档与在线用例流水线"
steps:
- name: sync-skill-packages
description: "同步至 delivery-skills 和 examples(仅 README)"
command: "node scripts/sync_invoice_followup.mjs"
- name: sync-test-cases-to-workbench
description: "同步测试用例至前端在线验证工作台"
command: "node scripts/sync_cases.mjs"Verify 管道可以集成回归测试:
yaml
Verify:
steps:
- name: verify-implementation
command: "python3 Versions/财务接入美事claw需求/test-skills/wuba-invoice-followup/run_regression_tests.py"版本发布 SOP(5 步)
bash
# 1. 修改代码
vim test-skills/wuba-invoice-followup/invoice_followup_skill.py
# 2. 本地回归验证
cd test-skills/wuba-invoice-followup && python3 run_regression_tests.py
# 3. 更新版本号(五文件一致性):
# invoice_followup_skill.py / SKILL.md / _meta.json / CHANGELOG.md / README.md
# 4. 同步分流到交付目录
cd finance-spec && node scripts/sync_invoice_followup.mjs
# 5. 发布到内部技能市场
WUBAHUB_TOKEN=<token> wubahub publish delivery-skills/wuba-invoice-followup --version X.Y.Z --tags tools