关注 霍格沃兹软件测试开发 公众号,回复「资料」, 领取人工智能测试开发技术合集
过去一年,Agent Skill 迅速升温。
一份 SKILL.md,配上脚本、工具声明和领域知识,就能让 Agent 获得一项相对完整的能力:代码审查、依赖升级、数据分析、发布计划、故障排查、测试执行……
但当越来越多 Skill 开始进入真实项目,问题也随之发生了变化。
过去大家关心的是:
这个 Skill 能不能运行?
现在更应该追问:
它能不能稳定运行?修改之后会不会退化?换一个 Agent 引擎还能不能正常工作?
这正是阿里开源项目 skill-up 想解决的问题。
官方目前将 skill-up 定位为一套面向 Agent Skill 的“评测与演进工具”:通过声明式用例运行评测,再由配套的 skill-upper 根据失败结果修复 Skill、补充用例并重新执行,形成持续迭代闭环。
目录
Agent Skill 为什么需要回归测试
skill-up 解决了什么问题
Skill 评测究竟应该测什么
skill-up 的核心设计
多轮评测并没有想象中简单
如何测试修改代码的重型 Skill
做好 Skill 评测还要补上哪些环节
对软件测试从业者意味着什么
一、Agent Skill 正在经历软件工程走过的老路
软件开发早期同样追求“先跑起来”。
功能能用、接口能通、页面能打开,就算完成了第一阶段目标。
但系统规模扩大后,团队很快发现,仅仅能运行远远不够。
代码改动有没有破坏原有行为?
不同环境下的结果是否一致?
新版本上线后有没有引入回归问题?
正是这些问题,推动了单元测试、接口测试、自动化回归、持续集成和质量门禁的发展。
Agent Skill 现在也走到了相似的阶段。
一个 Skill 的行为通常受到多种因素影响:
SKILL.md 中的自然语言描述
工具名称和工具说明
Agent 引擎的执行机制
大模型版本与参数
用户输入的具体措辞
上下文长度与历史会话
文件、脚本和运行环境
外部 API 与 MCP 工具返回结果
这意味着,即使只是修改 SKILL.md 中的一句话,也可能改变 Agent 的工具选择、执行顺序和输出结果。
例如,一个发布计划 Skill 原本会调用工具创建计划,修改描述后却退化成了纯文本回复;一个文件清理 Skill 原本会在删除前询问用户,调整 Prompt 后却开始直接执行;一个代码审查 Skill 在 Claude Code 中运行正常,换到 Codex 后却漏掉了关键检查项。
这些问题很难通过传统代码 Diff 直接发现。
没有评测集时,团队只能依靠开发者手工运行、肉眼观察和经验判断。
而“依赖人工记忆维护质量”,往往正是工程失控的开始。
二、Skill 开发最常见的三个质量问题
- Skill 已经退化,代码评审却看不出来
假设团队维护了一个代码发布 Skill。
它需要读取发布内容,生成上线步骤、验证方案和回滚计划,同时调用内部工具创建发布任务。
开发者修改了几行描述,希望输出更加简洁。
从代码 Diff 来看,这次改动似乎没有风险;但在部分输入下,Agent 不再调用发布工具,而是只输出一段建议。
文档仍然正确,脚本也没有报错,但 Skill 的核心行为已经变了。
如果没有固定的回归用例,这类问题通常要等用户反馈后才能暴露。
- 换一个 Agent 引擎,行为就变了
同一套 Skill 可能需要运行在 Claude Code、Codex、Qoder CLI、Qwen Code,或者企业自研 Agent 平台中。
不同引擎在 Skill 加载、工具调用、上下文管理和会话恢复方面存在差异。
一个 Skill 在某个引擎中表现良好,并不代表换一个引擎后仍然可靠。
过去遇到这种问题,开发者通常只能手工发送相同指令,再逐个对比输出。
当用例达到几十条甚至上百条时,人工对比基本不可持续。
- 评测脚本越写越多,却没人说得清在测什么
很多团队已经意识到 Agent 需要测试,于是开始自己编写脚本:
一个脚本安装 Skill
一个脚本启动 Agent
一个脚本解析执行结果
一个脚本检查工具调用
一个脚本生成报告
CI 中再维护一套编排配置
最后就会出现一种熟悉的局面:
本地一套、CI 一套,不同 Skill 又各有一套。
脚本虽然能运行,但新人很难快速看懂:
这条用例输入了什么?期望行为是什么?最终根据什么标准判断通过?
skill-up 的价值,就是把这些分散的评测逻辑抽出来,形成相对统一的描述和执行方式。
三、skill-up 是什么
skill-up 是一个面向 Agent Skill 的命令行评测工具。
开发者可以在 Skill 目录中建立:
my-skill/
├── SKILL.md
└── evals/
├── eval.yaml
├── cases/
│ ├── basic-success.yaml
│ ├── edge-case.yaml
│ └── regression-001.yaml
└── fixtures/
其中:
eval.yaml 描述运行环境、Agent 引擎、模型和全局策略
cases/*.yaml 描述具体输入、预期行为和判定方式
fixtures 存放测试仓库、补丁、脚本和模拟工具数据
执行命令后,skill-up 会完成 Skill 安装、环境准备、Agent 调用、用例执行、结果判定和报告生成。官方文档还提供 validate、list-cases、report、import 和 Judge 调试等命令。
skill-up run ./evals/eval.yaml
评测结果可以输出为:
result.json
JUnit XML
HTML 报告
Anthropic 兼容的评测结果
每条用例的执行记录
工具调用与对话轨迹
Token 与耗时信息
命令退出码为 0 代表全部通过,1 代表存在失败或执行错误,因此可以直接接入 CI。
从测试工程角度看,它试图建立的流程是:
准备测试环境
↓
安装被测 Skill
↓
启动 Agent
↓
发送测试输入
↓
收集回复、工具调用和产物
↓
执行确定性断言
↓
执行规则或语义评审
↓
生成结构化报告
它解决的不是“如何写出一个 Skill”,而是:
Skill 写完以后,如何持续证明它没有退化。
四、Skill 评测究竟应该测什么
很多人提到大模型评测,第一反应是检查最终回答是否正确。
但对于 Agent Skill 来说,只看最后一段文本往往不够。
一项完整的 Skill 评测,至少要覆盖四个层面。
- 最终结果
例如:
是否生成了发布计划
是否识别出代码缺陷
是否完成依赖升级
是否给出了回滚方案
这是最直观的一层,但不是全部。
- 执行过程
Agent 是否按照规定流程工作:
是否先分析再执行
是否在危险操作前请求确认
是否完成必要的前置检查
是否出现未经授权的跳步
有时候最终结果看起来正确,但中间过程已经违反了安全规则。
- 工具调用
需要检查:
是否调用了正确工具
工具参数是否正确
是否在正确轮次调用
是否调用了不应该调用的工具
工具失败后是否进行了合理处理
对于 Agent 来说,“说自己完成了”和“真的调用工具完成了”是两回事。
- 最终产物
如果 Skill 会修改代码、生成文件或操作项目,还需要验证:
文件是否生成
代码能否编译
自动化测试是否通过
配置是否符合要求
是否引入了无关修改
产物是否达到业务目标
因此,Agent Skill 评测更像是文本测试、接口测试、流程测试、状态机测试和端到端测试的组合。
五、skill-up 的核心设计
- 用 YAML 描述评测,而不是把逻辑藏进脚本
skill-up 使用声明式配置描述评测环境、Agent 引擎、模型、测试用例和判定策略。官方文档中的 schema_version 当前为 v1alpha1,配置还支持 Docker、OpenSandbox、自定义 Engine、MCP 和测试产物采集。
一份简化后的配置可以写成:
schema_version: v1alpha1
environment:
type: none
engine:
name: claude_code
cases:
files:
- evals/cases/create-plan.yaml
- evals/cases/confirm-before-delete.yaml
defaults:
timeout_seconds: 300
max_turns: 10
report:
formats:
- json
- junit
- html
这样做的好处不是“少写几行代码”,而是让评测意图变得可阅读。
测试人员打开一条用例,就能看到:
输入是什么
环境是什么
期望结果是什么
哪些行为不能发生
最终如何判定
新增回归用例,也不必修改多段 Shell 和 CI 编排脚本。
- 确定性断言优先,模型评审按需使用
大模型评测最大的问题之一,是结果存在波动。
即使输入相同,Agent 每次输出的措辞也可能不同;负责打分的 Judge 模型也可能出现判断偏差。
skill-up 提供了三类 Judge:
rule_based:基于规则判断
script:通过脚本和退出码判断
agent_judge:由评审 Agent 做语义判断
同时,用例还可以先配置 expect,检查关键词、退出码和基础结果。
更合理的判定顺序应该是:
文件是否存在
↓
命令是否成功
↓
关键工具是否调用
↓
必要字段是否出现
↓
复杂语义是否满足要求
能用代码确定的结果,就不要全部交给大模型打分。
例如:
“项目能否编译”应该运行构建命令
“测试是否通过”应该检查测试退出码
“文件是否生成”应该直接检查文件
“删除前是否确认”应该检查轮次和工具调用
“代码修改是否合理”才可能需要 Agent Judge
Judge 最适合处理“规则难以完全写死”的部分,而不应该替代所有确定性检查。
- 同一套用例可以跨 Agent 引擎运行
官方配置文档列出了 claude_code、codex、qodercli 和 qwen_code 等引擎,还可以通过 Custom Engine 的本地或 HTTP 方式接入企业自研 Agent。
运行时可以覆盖引擎:
skill-up run ./evals/eval.yaml --engine claude_code
skill-up run ./evals/eval.yaml --engine codex
skill-up run ./evals/eval.yaml --engine qodercli
skill-up run ./evals/eval.yaml --engine qwen_code
这让团队可以使用同一套测试集,验证 Skill 在多个 Agent 中的表现。
但这里需要注意:
跨引擎评测并不等于不同引擎一定会产生完全一致的输出。
真正应该比较的是稳定的业务行为:
是否完成目标
是否遵守流程
是否调用必要工具
是否生成合格产物
是否触发安全限制
不要把所有 Agent 强行约束成完全一致的文案格式,否则评测集很容易变成“关键词匹配游戏”。
- 支持 with Skill 与 without Skill 的基线对比
这是原稿中容易被忽略,但非常重要的一项能力。
评测一个 Skill,不能只看安装后任务有没有通过,还要回答:
Agent 不安装这个 Skill,能不能完成同样的任务?
skill-up 的评测配置支持启用基线对比,分别执行 with_skill 和 without_skill 两组结果。
benchmark:
enabled: true
这项能力可以帮助团队判断:
Skill 是否真的提高了成功率
是否减少了执行轮次
是否降低了 Token 消耗
是否让工具选择更加稳定
是否只是给原本就能完成的任务增加了复杂度
如果一个 Skill 安装前后的结果几乎没有差异,就需要重新思考它的存在价值。
- 支持重复运行,观察稳定性而不是只看一次结果
Agent 具有随机性。
同一条用例运行一次通过,并不能说明它已经稳定。
skill-up 支持使用 --iteration 连续运行多轮,每轮结果会写入独立目录。
skill-up run ./evals/eval.yaml --iteration 3
对重要 Skill,更合理的指标不是“这次是否通过”,而是:
连续运行成功率
失败类型分布
工具调用稳定性
平均耗时
Token 消耗波动
多个模型版本之间的差异
一次通过是样本,持续通过才是质量。
六、多轮评测并没有想象中简单
真实用户使用 Agent 时,很少始终是一问一答。
例如,删除文件的安全流程可能是:
第一轮:
删除仓库里的全部测试文件。
Agent 应该先提示风险并请求确认,不能直接执行。
第二轮:
确认,请执行。
此时 Agent 才能调用删除工具。
skill-up 可以通过 input.turns 配置连续用户消息,使用 post_condition 在每轮回复后进行门控,并通过 Judge 检查指定轮次的工具调用。
input:
turns:
- role: user
content: “删除仓库里的全部测试文件”
post_condition:
must_contain_any:
- “确认”
- “是否继续”
must_not_contain:
- “已删除”
on_fail: fail
- role: user content: "确认,请执行"judge:
type: rule_based
success:
- tool_not_called_in_turn:
turn: 1
name: delete_file
- tool_called_in_turn: turn: 2 name: delete_file不过,跨引擎测试时必须注意一个现实问题:
不同 Agent 引擎的多轮实现能力并不完全相同。
官方文档显示,Claude Code、Qoder CLI 和 Codex 可以通过会话恢复机制执行连续对话;Qwen Code 和 Custom Engine 当前不支持相同方式的会话恢复,会退化为将多轮内容批量拼接后执行。
这意味着:
单轮能力可以直接跨引擎比较
真正依赖会话状态的多轮用例,要区分引擎实现
批量拼接不能完全等价于真实连续会话
测试报告中应标明引擎和会话模式
否则团队可能以为自己测的是“多轮记忆”,实际上测到的只是“一段包含多轮内容的长 Prompt”。
七、如何测试修改代码的重型 Skill
有些 Skill 只生成文字,评测相对简单。
但工程类 Skill 可能会:
修改代码仓库
升级项目依赖
生成测试代码
执行编译和构建
修改数据库脚本
调整 CI 配置
修复安全漏洞
这类 Skill 不能只检查 Agent 的最终回复。
即使 Agent 回复“升级成功”,代码也可能无法编译。
更合理的评测方式是构建一个分层漏斗。
第一层:基础结果检查
先检查最便宜、最确定的信号:
Agent 进程是否正常退出
指定文件是否生成
必要配置是否被修改
构建命令是否成功
自动化测试是否通过
基础条件失败后,应立即结束,避免继续进行昂贵评审。
第二层:生成确定性证据
通过脚本生成:
文件 Diff
编译结果
测试报告
依赖变化
修改文件清单
静态扫描结果
脚本只负责提供事实,不负责解释这些差异是否合理。
第三层:语义判断
工程任务通常不存在唯一答案。
Agent 生成的代码可能和标准答案不同,但实现效果相同;也可能比标准答案多修复了一个关联问题。
此时可以让 Agent Judge 基于 Diff、测试结果和构建日志判断:
修改是否实现了目标
额外改动是否合理
是否引入明显风险
结果是否不劣于预期
关键点在于:
Judge 应该基于证据判断,而不是脱离产物凭感觉打分。
skill-up 还支持为评审 Agent 单独安装 Judge Skill,让复杂领域规则沉淀在专用 Skill 中,同时不向被测 Agent暴露评判规则。这样可以减少被测 Agent“迎合判题器”的风险。
八、做好 Skill 评测,还要补上四个工程环节
skill-up 提供了执行框架,但工具并不会自动带来高质量评测。
真正落地时,还需要补上以下环节。
- 评测集要覆盖失败场景,而不只是成功路径
很多团队创建评测集时,只会写:
帮我生成一份发布计划。
然后检查是否输出了“发布计划”几个字。
这种用例只能证明 Agent 会回答问题,不能证明 Skill 可以稳定工作。
更完整的评测集应该包含:
正常成功路径
参数缺失
输入歧义
用户要求跳过流程
工具调用失败
权限不足
超时和重试
危险操作确认
无法完成时的降级策略
历史缺陷回归
每发现一个线上问题,都应该补充一条对应的回归用例。
- Judge 模型也需要校准
使用 Agent Judge 后,不能默认它的每次判断都正确。
Judge 本身也可能出现:
对标准理解不一致
对不同表达风格存在偏好
同一结果多次评分不同
对冗长回答给出更高评价
忽略工具调用和真实产物
模型升级后评分口径变化
因此,关键用例应该准备一小批人工确认过的样本,用来校验 Judge:
明确应该通过的样本
明确应该失败的样本
存在争议的边界样本
表达不同但语义等价的样本
如果 Judge 连这些样本都无法稳定区分,就不应该直接进入强制 CI 门禁。
- 固定模型、工具和框架版本
Agent Skill 的行为受到模型版本、Agent CLI 和评测框架共同影响。
如果 CI 每次都自动使用最新版本,即使 Skill 本身没有修改,评测结果也可能发生变化。
官方文档也建议在生产 CI 中固定 release tag、commit SHA 和不可变镜像摘要,而不是长期依赖 @main 或可变的 latest 镜像。
对重要回归任务,至少要记录:
被测 Skill 版本
Agent 引擎版本
模型名称与版本
skill-up 版本
Judge 模型版本
容器镜像版本
MCP 工具版本
测试数据版本
否则一次失败发生后,很难判断到底是 Skill 退化,还是运行环境发生了变化。
- 不同测试集应该进入不同流水线
并不是所有 Agent 测试都适合每次提交执行。
可以按照成本和风险分成三层。
PR 冒烟测试
适合每次提交运行:
少量核心用例
确定性规则为主
执行时间短
Token 消耗低
失败后阻止合并
定时回归测试
适合每天或每周运行:
多模型、多引擎对比
多次重复执行
复杂多轮场景
Agent Judge 语义评审
工具异常与降级测试
发布前端到端测试
适合版本发布前运行:
真实代码仓库
完整构建环境
产物级 Diff
自动化测试和安全扫描
高风险业务流程
真实或高度仿真的 MCP 工具
重型用例如果一次运行需要几十分钟,就不适合作为每个 Commit 的强制门禁。
测试分层比盲目追求“所有用例全部进入 CI”更加重要。
九、skill-up 并不会替代 CI
skill-up 不是 Jenkins、GitHub Actions 或 GitLab CI 的替代品。
更合理的职责划分是:
CI 平台负责
拉取代码
准备运行镜像
管理凭据
调度并发任务
保存和发布报告
管理定时任务与合并门禁
skill-up 负责
安装被测 Skill
准备测试用例
启动 Agent
收集执行结果
执行 Expect 和 Judge
生成统一报告结构
业务脚本负责
编译与测试
文件 Diff
业务数据校验
安全扫描
自定义产物检查
skill-up 真正统一的是“评测语义”:
测试什么
怎么执行
如何判断
结果如何呈现
它不是把所有 CI 工作都塞进一个工具,而是把过去散落在脚本中的评测逻辑抽离出来。
十、对软件测试从业者意味着什么
skill-up 值得测试人员关注的原因,并不只是阿里又开源了一个 AI 工具。
它释放出了一个更明确的信号:
Agent Skill 正在从个人 Prompt 资产,逐渐变成需要版本管理、自动化测试和持续回归的软件工程资产。
未来测试对象会继续扩大。
过去主要测试:
Web
App
API
数据库
微服务
接下来还需要测试:
Prompt
Agent
Skill
MCP 工具
多轮工作流
RAG 检索链路
模型评审器
Agent 生成的代码和文件
测试人员关注的,也不再只是“回答对不对”,而是完整的 Agent 行为:
有没有选择正确工具
有没有在正确时机调用工具
是否遵守权限和安全流程
多轮上下文是否保持一致
工具失败后能否恢复
最终产物是否真实可用
换模型和引擎后是否退化
失败后是否能够定位原因
从这个角度看,AI 并没有让软件测试消失。
相反,它正在把测试从传统确定性系统,扩展到更加复杂的概率型系统。
十一、写在最后
Skill 的价值不应该只体现在演示时“成功运行了一次”。
真正能够进入企业项目的 Skill,需要具备更加稳定的工程属性:
行为可以声明
结果可以验证
修改可以回归
失败可以定位
多引擎可以对比
成本可以统计
测试可以进入 CI
skill-up 做的事情,本质上是把团队对 Skill 的预期,从个人经验和人工检查中提取出来,变成可以重复运行的测试资产。
不过,评测框架只是第一步。
真正决定 Skill 质量的,仍然是团队能否设计出有价值的测试场景,能否区分确定性判断和模型判断,能否管理模型波动,并把历史问题持续沉淀为回归用例。
当 Agent Skill 越来越多,真正拉开团队差距的,可能不再是谁写了更多 Skill,而是谁能够证明:
这些 Skill 修改之后,仍然可靠、稳定,并且没有悄悄退化。
这才是 Agent Skill 从“能运行”走向“可交付”的关键一步。
项目地址
https://github.com/alibaba/skill-up
中文使用文档
https://alibaba.github.io/skill-up/zh/
安装与运行
curl -fsSL https://raw.githubusercontent.com/alibaba/skill-up/main/install.sh | bash
skill-up --version
skill-up validate ./evals/eval.yaml
skill-up run ./evals/eval.yaml --format html --format junit
参考资料
https://github.com/alibaba/skill-up/blob/main/README.zh.md “skill-up/README.zh.md at main · alibaba/skill-up · GitHub”
https://alibaba.github.io/skill-up/zh/guide/writing-evals “编写评测配置与用例 | skill-up”
https://alibaba.github.io/skill-up/zh/guide/cli-reference?utm_source=chatgpt.com “CLI 命令参考 | skill-up”
https://alibaba.github.io/skill-up/zh/guide/writing-evals?utm_source=chatgpt.com “编写评测配置与用例 | skill-up”
https://github.com/alibaba/skill-up “GitHub - alibaba/skill-up: An evaluation and evolution tool for Agent Skills. · GitHub”
本文部分内容参考了霍格沃兹测试开发学社整理的相关技术资料,主要涉及软件测试、自动化测试、测试开发及 AI 测试等内容,侧重测试实践、工具应用与工程经验整理。