news 2026/9/9 9:41:18

AI测试Skill三层结构实战:SKILL.md+scripts+references打造稳定回归测试

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
AI测试Skill三层结构实战:SKILL.md+scripts+references打造稳定回归测试

最近我被一个老接口坑了整整一个下午。前端没有任何报错,服务端接口悄悄改了响应结构,等数据传到业务层才发现异常,测试用例已经积压了二十多条。那一刻我意识到,光靠人肉回归和临时写的 prompt,永远跟不上代码变更的速度;真正该做的,是把“怎么测试这部分功能”固化成一套可复用的测试Skill。于是有了这套SKILL.md + scripts + references三层结构:SKILL.md 是给 AI 助手看的触发条件与执行流程说明,scripts 是真正能跑起来的自动化测试脚本,references 存放用例模板、缺陷分级和历史问题清单。这篇文章就是这套方法论从 0 到 1 的完整记录,适合正在用 Claude Code、Codex 这类 Agent 开发能力包的开发者,也适合想把测试经验沉淀成资产的测试工程师。

很多同学一听“Skill 开发”就以为是要写多复杂的代码,实际上测试类 Skill 的难点从来不在代码量,而在结构设计。我见过太多人把一个测试方法直接糊成一大段 prompt,结果模型每次执行都“自由发挥”:今天用 requests,明天用 curl,断言维度丢三落四,报告格式随心所欲。换到三层结构之后,AI 助手的表现稳定了一个量级。下面我把每一步拆开讲清楚,包括为什么要这么设计、文件里具体写什么、以及我踩过的那些坑。

1. 为什么测试Skill必须拆成三层:我踩过的“只写prompt”的坑

1.1 只写prompt的Skill为什么不稳定

我最初做测试能力包的时候,走的是最省事的路线:写一个超长的 prompt,把测试目标、接口信息、断言要点、报告格式全部塞进去。看起来信息很全,实际用起来问题一大推。

首先是执行路径不可控。模型不会老老实实按照你写的步骤走,它会觉得某个步骤“没必要”,自动跳过;也会觉得“这里应该补充一下”,自作主张加断言。在普通问答场景这无所谓,但测试是一个对确定性和完整性要求极高的场景。一条用例漏跑了,可能就是一个线上事故。其次是输出格式漂移。同一份测试任务,我让它跑三次,三次报告的结构都不一样,第二次用的表格,第三次变成了一大段散文,后续想用脚本去解析报告根本没法做。

根本原因在于:prompt 是线性文本,它只有“建议”,没有“强制”和“校验”。模型对“必须做”和“可以做”之间的边界,理解得比我们想象中模糊得多。测试 Skill 必须给模型提供一套带强制节点的执行框架,否则它永远在即兴发挥。

1.2 三层结构分别解决什么问题

把问题拆开看,测试 Skill 其实要回答三个问题:什么时候用、怎么执行、用什么标准。这正好对应三层结构:

层级解决的问题对应测试场景核心价值
SKILL.md什么时候触发、按什么顺序做、做到什么标准算合格触发条件、执行流程、质量门禁决策稳定
scripts怎么执行才确定、可复现、可校验测试脚本、断言逻辑、报告生成执行可信
references用什么模板、按什么规范、有没有历史经验可参考用例模板、缺陷分级、历史风险清单知识完整

用生活里的话说,SKILL.md 像一份资深测试专家写给新人的上岗指导手册,scripts 是手册里提到的自动化测试工具箱,references 是工具箱旁边那排参考资料和模板。新人照着手册、用着工具、翻着资料,产出的结果就能稳定接近资深测试的水平。三层缺一不可:没有 SKILL.md,模型不知道该何时出手;没有 scripts,模型只能空谈方案不能落地;没有 references,每次执行都缺少规范和上下文,质量自然忽高忽低。

1.3 Skill与Agent到底是什么关系

这个话题在社区里反复被问,我在这里用一个尽量简洁的说法:Agent 是调度大脑,Skill 是专业能力单元。Agent 负责拆解用户的目标,判断当前任务属于哪个专业领域,然后决定调用哪个 Skill;Skill 则负责把某个专业任务的执行流程、工具、知识打包好,让 Agent 拿过来就能照着做。

放到测试场景里更直观。你让 Agent “帮我看下登录接口这次改动有没有问题”,Agent 先理解这是一个接口回归测试任务,于是加载 api-smoke-regression 这个 Skill。Skill 告诉它:先读用例模板,再定位受影响用例,接着运行 scripts 里的回归脚本,最后按 references 里的缺陷分级标准输出报告。Agent 负责中间的判断和沟通,Skill 负责把专业流程固定下来。搞不清这层关系的人,最容易犯的错就是让 Skill 越权去“思考”,在 SKILL.md 里写一堆开放式问题,结果 Skill 被 Agent 当成一个普通的上下文文档,完全失去了约束力。

2. 第一步:SKILL.md——把测试流程写成Agent能严格执行的文档

2.1 frontmatter:Agent决定是否调用你的关键

SKILL.md 的文件结构通常分两块:YAML frontmatter 和正文。frontmatter 是模型最先读取的元信息,也是决定“这个 Skill 会不会被触发”的关键。

--- name: api-smoke-regression description: 当接口请求或响应结构发生变更、修复了线上缺陷、或新增接口测试用例时,对目标接口执行冒烟回归测试,并输出结构化测试报告。 version: 1.2.0 when_to_use: - 接口字段发生变更 - 修复了与接口相关的缺陷 - 提交新的接口测试用例后 ---

写 description 有一条非常重要的经验:把触发时机和边界写进描述里,而不是泛泛写“执行接口测试”。Agent 判断是否调用 Skill,主要靠语义匹配,你的描述越具体,它选错的概率越低。比如我上面写的“当接口字段变更”“修复了线上缺陷”,这些就是非常清晰的触发信号。反之,如果只写“用于接口测试”,那么用户问“为什么登录失败”这种排查类问题时,Agent 也可能把这个 Skill 拉出来跑一遍,浪费执行时间不说,还可能给出误导性的结论。

2.2 正文结构:操作流程、质量门禁、回退策略

正文是给 Agent 的完整操作手册,我的固定格式是三段式:操作流程、质量门禁、回退策略。为什么一定要这三段?因为模型在执行任务时,最怕两种失控:不知道怎么开始失败后不知道怎么办

操作流程必须用有序列表。我对比过散文式描述和列表式描述,模型对后者的遵循度明显更高,每一步都像勾选清单一样推进,不容易漏步骤。

质量门禁是这类 Skill 的灵魂。测试和写代码不一样,写代码“能跑”就行,测试必须“可信”。门禁里要写清楚:每条用例必须包含哪些字段、报告必须输出哪些统计项、失败率达到多少要停下来检查环境。这些硬性条件会逼着 Agent 在交结果之前先做一轮自检。

回退策略用来兜底。脚本执行失败时,模型默认会尝试自己“脑补”执行结果,这是最危险的行为。我会明确写:脚本失败先检查依赖环境,重试一次,重试仍失败就如实报告环境错误,禁止伪造执行结果。这一条救过我很多次。

2.3 一个可复制的SKILL.md完整示例

下面是我在实际项目里用过的接口冒烟回归 Skill 的 SKILL.md,你可以直接参考结构改。注意 comments 部分我保留了,但实际文件里不要写“本段是干什么的”这种 meta 说明,模型读了会分散注意力。

--- name: api-smoke-regression description: 当接口请求或响应结构发生变更、修复了线上缺陷、或新增接口测试用例时,对目标接口执行冒烟回归测试,并输出结构化测试报告。 version: 1.2.0 when_to_use: - 接口字段发生变更 - 修复了与接口相关的缺陷 - 提交新的接口测试用例后 inputs: base_url: 被测环境地址 api_path: 接口路径 sample_file: 请求样例文件,默认读取 references/samples/login_request.json outputs: - 测试报告文件 test_report.md --- # API 冒烟回归测试 ## 执行步骤 1. 读取 references/templates/test_case_template.md,了解用例格式。 2. 根据本次变更点,在测试用例中标注受影响用例。 3. 运行 `python scripts/run_regression.py --config config.json` 执行测试。 4. 运行 `python scripts/generate_report.py --input results.json --output test_report.md` 生成报告。 5. 阅读报告摘要并反馈给用户,报告正文写入 test_report.md。 ## 质量门禁 - 每个用例必须包含:用例名、接口路径、请求样例、预期状态码、核心断言。 - 报告必须包含:总用例数、通过数、失败数、失败原因分类。 - 失败率高于 20% 时暂停,检查是否存在环境问题,不要继续补充业务断言。 - 断言字段缺失时,必须按 references/specs/assertion_standards.md 中的规范处理。 ## 回退策略 - 脚本执行失败时,先运行 `python scripts/check_env.sh` 检查依赖环境。 - 环境正常则重试一次;重试失败则如实报告错误,禁止伪造结果。 - 接口完全不可用时,标记为网络层失败,不生成业务断言。

这个示例里有几个设计细节值得说明。第一,第三步和第四步的命令写得非常具体,连参数都写清楚了,不给 Agent 留“自由发挥”的空间。第二,质量门禁里带了文件名引用,等于强制 Agent 去 references 里找规范,而不是凭自己的训练记忆编一套。第三,回退策略里那条“禁止伪造结果”,是对抗模型幻觉最有效的刹车片。

3. 第二步:scripts——让Skill真正动手执行测试与生成报告

3.1 scripts目录应该放哪些脚本

scripts 目录是 Skill 的“手”,里面放的是真正可执行的测试工具。我一般按职责拆成四类:

  • check_env.sh:环境自检脚本,检查 Python/Node 版本、依赖是否安装、被测环境是否可达。
  • run_regression.py:核心测试执行脚本,逐条运行用例并收集结果。
  • parse_response.py:响应解析工具,把接口返回的 JSON 按规则提取字段、执行断言。
  • generate_report.py:报告生成脚本,把 results.json 渲染成 Markdown 报告。

拆分的核心原则是单一职责。一个脚本只做一件事,这样哪个环节出问题,Agent 能精确定位到是哪个脚本挂了。我见过有人把所有逻辑塞进一个几百行的脚本,结果一旦报错,连排查都无从下手,Agent 也搞不清楚是测试失败还是脚本本身的 bug。

3.2 脚本与Agent的分工边界

这是我在 scripts 设计上踩过最深的一个坑,必须单独拿出来说。早期我犯过一个错误:试图把整个测试逻辑全部写进脚本,Agent 只需要执行一个命令。后来又犯了另一个错误:把断言逻辑全部交给 Agent “临场发挥”,脚本只负责发请求。

现在的原则是:确定性的事情交给脚本,判断性的事情留给 Agent

具体来说,接口请求的构造、响应字段的提取、数值计算、文件读写这些“输入输出可预测”的操作,全部塞进脚本,让它们每次执行结果一致。而测试计划的设计、失败用例的缺陷归类、风险分析这种需要结合上下文做判断的事,留给 Agent 结合 references 里的规范去完成。

打个比方,你不能让脚本决定“这个 bug 是 P0 还是 P2”,但脚本应该告诉 Agent“这个接口响应时间超过 3 秒”。前者是经验判断,后者是客观事实。两者边界清晰,整个 Skill 才既有稳定性又有灵活性。

3.3 脚本输出格式:机器可读是第一原则

脚本输出格式直接决定 Agent 解析结果的成功率,我把这条单独拿出来,因为它是细节中最容易翻车的地方。

我的硬性约定有三条。第一,stdout 只输出 JSON。JSON 是最容易被模型稳定解析的格式,不要输出人类可读的废话,更不要输出带 ANSI 颜色的字符串。第二,日志写到文件而不是控制台。排查问题需要看日志时,直接读 log 文件就行,不要污染 stdout。第三,退出码必须规范:0 表示全部通过,1 表示有用例失败,2 表示脚本自身异常。Agent 可以通过退出码快速判断下一步该走哪条分支。

下面这个 JSON 输出样例是我的标准格式:

{ "summary": { "total": 12, "passed": 9, "failed": 3, "error": 0 }, "cases": [ { "name": "login_with_valid_credentials", "status": "failed", "api_path": "/api/v1/auth/login", "expected_status": 200, "actual_status": 422, "failed_assertions": [ {"field": "token", "expected": "string", "actual": "missing"} ] } ] }

这种结构 Agent 一眼就能看懂:哪些用例挂了、挂在哪个字段、预期和实际分别是什么。它拿到这个结果,再去 references 里对照缺陷分级标准,就能给出高质量的分析。

3.4 核心脚本示例与运行方式

下面是 run_regression.py 的降噪版,保留了核心逻辑骨架,真实项目里你可以在这个基础上扩展丰富的断言能力。

#!/usr/bin/env python3 """接口冒烟回归测试执行脚本。""" import json import sys from pathlib import Path import requests def load_cases(case_file: Path) -> list[dict]: return json.loads(case_file.read_text(encoding="utf-8")) def run_case(case: dict, base_url: str) -> dict: url = base_url.rstrip("/") + case["api_path"] resp = requests.request( method=case.get("method", "POST"), url=url, headers=case.get("headers", {}), json=case.get("body", {}), timeout=10, ) result = { "name": case["name"], "api_path": case["api_path"], "status": "failed", "expected_status": case["expected_status"], "actual_status": resp.status_code, "failed_assertions": [], } if resp.status_code == case["expected_status"]: result["status"] = "passed" return result result["failed_assertions"].append({ "field": "status_code", "expected": case["expected_status"], "actual": resp.status_code, }) return result def main() -> int: config = json.loads(Path("config.json").read_text(encoding="utf-8")) cases = load_cases(Path("cases.json")) results = [run_case(c, config["base_url"]) for c in cases] summary = { "total": len(results), "passed": sum(1 for r in results if r["status"] == "passed"), "failed": sum(1 for r in results if r["status"] == "failed"), "error": 0, } Path("results.json").write_text( json.dumps({"summary": summary, "cases": results}, ensure_ascii=False, indent=2), encoding="utf-8", ) return 0 if summary["failed"] == 0 else 1 if __name__ == "__main__": sys.exit(main())

generate_report.py 的核心就是把 results.json 渲染成 Markdown 报告,逻辑不复杂,这里只给出运行方式:python scripts/generate_report.py --input results.json --output test_report.md

运行方式有个细节很关键:在 Windows 上直接写python scripts/run_regression.py,可能会遇到系统关联了 Microsoft Store 的 python 别名导致命令不生效。我在踩坑之后定了一个规矩:所有 Skill 脚本统一用python命令,但在 check_env.sh 里会检测python --version是否能正常输出,不能则给出明确提示。这类环境问题不在脚本里硬编码处理,而是交给环境自检脚本去暴露。

4. 第三步:references——测试模板与规范的价值沉淀池

4.1 静态资产与动态执行的本质区别

references 目录很多人不理解它的定位,觉得反正都是文件,放在 scripts 旁边不也一样吗?其实两者的性质完全不同。scripts 里是执行逻辑,每次调用都可能产生不同的结果;references 里是静态知识,内容是相对固定的,比如模板、规范、样例、历史经验。

这个区分之所以重要,是因为 AI 助手的上下文窗口是稀缺资源。如果 Skill 的所有文件都被塞进上下文,几千行的测试用例库很快就会把窗口撑爆,Agent 反而开始“丢三落四”。references 的正确使用方式是按需拉取:SKILL.md 里写明“什么场景去读哪个文件”,Agent 只有在需要时才去读取对应的 references 文件。这就是为什么 references 设计得好不好,直接决定 Skill 的响应质量和稳定性。

4.2 测试Skill的references内容清单

针对测试场景,我把 references 固定分成四个子目录,每个目录都有明确的用途和读取时机:

  • templates/:用例模板、缺陷报告模板。Agent 在开始设计用例、写缺陷报告时读取。
  • specs/:缺陷分级标准、断言规范。Agent 在执行结果归类、判断缺陷严重程度时读取。
  • samples/:接口请求和响应样例。Agent 在构造新用例、理解接口结构时读取。
  • knowledge/:回归风险清单、历史问题记录。Agent 在制定测试计划、评估本次变更影响范围时读取。

举个具体例子,缺陷分级标准文件 defect_severity.md 里会写明:

级别定义处理要求
P0核心链路不可用,阻塞发版立即通知开发修复,测试阻断
P1主流程受影响但存在绕行方案当天必须修复,可带病发布
P2非核心功能异常,不影响主流程计入迭代 backlog
P3样式、文案等非功能问题有时间再修

有了这份标准,Agent 在分析失败用例时就不再是“凭感觉说严重”,而是有据可依的等级判定。

4.3 目录结构与文件粒度怎么设计才不浪费上下文

references 目录的组织我推荐下面这个结构:

my-test-skill/ ├── SKILL.md ├── scripts/ │ ├── check_env.sh │ ├── run_regression.py │ ├── parse_response.py │ └── generate_report.py └── references/ ├── templates/ │ ├── test_case_template.md │ └── bug_report_template.md ├── specs/ │ ├── defect_severity.md │ └── assertion_standards.md ├── samples/ │ ├── login_request.json │ └── login_response.json └── knowledge/ └── regression_risk_checklist.md

文件粒度控制是我反复强调的一点:单个 references 文件最好控制在 100 到 200 行以内。超过这个规模,模型读取时容易出现信息衰减,开头和结尾记住了,中间的内容被忽略。如果测试知识特别多,就拆成多个主题文件,比如把“用户模块历史缺陷”和“支付模块历史缺陷”拆开,而不是堆在一个大文件里。同时在 SKILL.md 的对应步骤里写清楚什么情况读哪个文件,让 Agent 按需取用。

还有一点,references 里的内容要定期更新。我见过不少 Skill,模板文件从一开始写完之后就再没动过,里面的接口字段早就过时了。把 references 当成活资产,每次项目迭代顺手更新样例和风险清单,Skill 才会越用越准。

5. 实战演练:开发一个接口回归测试Skill并验证整条调用链路

5.1 需求定义与范围收敛

理论讲完了,我用一个真实的例子把整个流程串起来。假设我们有一个用户登录接口/api/v1/auth/login,最近接口响应结构发生了变化,原来返回token字段,现在改成了access_token,还新增了一个flag字段。我们希望开发一个 Skill,以后遇到这类接口变更,AI 助手能自动完成回归测试。

动手前第一件事不是写文件,而是锁定范围。我给自己定了几条边界:

  • 只做接口冒烟回归,不做 UI 自动化,避免范围膨胀。
  • 只覆盖登录模块和与之强关联的两个接口(获取用户信息、刷新 token)。
  • 报告输出到本地 markdown 文件,不接入 CI 系统。

范围收敛的好处是,Skill 的第一版可以快速跑通,后续迭代再逐步扩展。一上来就想做一个“万能测试 Skill”,大概率什么都做不好。

5.2 完整目录结构与关键内容

按照前三章的方法,我把目录搭出来,并填充对应内容。SKILL.md 用第二章的模板,scripts 用第三章的脚本,references 放了登录接口的请求样例、响应样例、用例模板和缺陷分级标准。关键目录结构如下:

my-test-skill/ ├── SKILL.md ├── scripts/ │ ├── check_env.sh │ ├── run_regression.py │ └── generate_report.py ├── references/ │ ├── templates/ │ │ ├── test_case_template.md │ │ └── bug_report_template.md │ ├── specs/ │ │ ├── defect_severity.md │ │ └── assertion_standards.md │ └── samples/ │ ├── login_request.json │ └── login_response.json └── config.json

config.json 里存放的是环境配置,包括 base_url、超时时间、公共请求头等信息。注意我刻意没有把用例直接写进 scripts 里,而是单独维护 cases.json,这样每次回归只需要更新用例数据,不用改脚本。

5.3 模拟一次完整的调用链路

下面这段是模拟用户与 Agent 的交互过程,我把 Skill 的触发和执行链路完整走一遍。

用户输入:“登录接口的响应里多了一个 flag 字段,原来的 token 字段改名成了 access_token,帮我做一下回归测试。”

Agent 收到后,判断这属于接口变更触发的回归测试,匹配到 api-smoke-regression Skill,读取 SKILL.md。它按执行步骤走:

  1. 读取 references/templates/test_case_template.md,了解用例格式规范。
  2. 读取 references/samples/login_response.json,对比新旧响应结构,发现token字段缺失,flag字段新增,于是标记已有用例中所有断言了token字段的用例为“受影响”。
  3. 在 references/knowledge/regression_risk_checklist.md 的提示下,Agent 补充了一条新用例:验证access_token存在且为用户私有。
  4. 运行python scripts/run_regression.py --config config.json执行测试,脚本产出 results.json。
  5. 运行python scripts/generate_report.py --input results.json --output test_report.md生成报告。

Agent 最终向用户反馈:“本次回归共执行 12 条用例,通过 9 条,失败 3 条。其中 2 条失败原因是断言字段 token 不存在,1 条失败原因是状态码从 200 变为 422 且响应体含 flag,疑似同时发生了兼容性问题。按 references/specs/defect_severity.md 的分级,前两条标记为 P1,第三条标记为 P0,建议优先排查。”

这条链路里,SKILL.md 决定了“按什么顺序做”,scripts 决定了“结果怎么算出来”,references 提供了模板、样例和分级标准。三层各司其职,整个过程的稳定性就非常高了。

5.4 怎么评估这个测试Skill好不好用

Skill 开发完不能直接说“完成”,得有一套衡量标准。我用的指标是四个:

  • 用例覆盖率:Skill 生成的测试用例是否覆盖了接口变更涉及的所有分支。
  • 脚本执行成功率:run_regression.py 是否稳定执行,环境问题占比多少。
  • 报告生成时间:从用户提问到输出完整报告花了多长时间,理想状态是 1 分钟以内。
  • 人工修正率:Agent 输出的缺陷分级和风险分析,有多少需要测试工程师手动纠正。修正率越低,说明 references 里的规范沉淀得越好。

这几个指标每次迭代跑一遍,就能量化看到 Skill 是变好了还是变差了。我自己的经验是,第一版往往人工修正率偏高,主要问题在 references 规范不够细,迭代两三轮之后会趋于稳定。

6. 踩坑清单:路径、格式、上下文与依赖环境的四类真实经验

6.1 工作目录与路径引用错位

这是我遇到的第一个大坑。Skill 里明明写了python scripts/run_regression.py,但 Agent 执行时的工作目录往往不在 Skill 的根目录,而是用户的某个项目目录下,导致脚本直接报“文件不存在”。后来我定了一条规矩:SKILL.md 里所有相对路径都以 Skill 根目录为基准,并且在脚本开头加一句切换到自身目录的逻辑。比如 run_regression.py 里加:

import os os.chdir(os.path.dirname(os.path.abspath(__file__)))

同时把“当前环境变量”也考虑进去。有些脚本会读取外部环境变量,一旦变量没设置就静默失败,所以我在 check_env.sh 里会预检关键变量,并输出一份环境清单,让 Agent 一眼看到环境状态。

6.2 frontmatter格式问题导致Skill直接罢工

YAML frontmatter 解析失败是最隐蔽的坑。有次我在 description 里写了一个带冒号的句子:“执行测试:包括接口与页面”,结果模型的 YAML 解析直接出错,Skill 根本不会被加载。排查了很久才发现是冒号后面没加空格,被 YAML 解析器当成了嵌套对象。

经验是:frontmatter 里的字符串尽量用纯文本,别用特殊符号。描述内容里如果要举例,避开{}:[]这些字符。写完以后最好用一个 YAML 解析工具做本地校验,或者最少在编辑器里确认 YAML 语法高亮正常。这个坑一旦踩上,问题往往不在执行阶段,而是在模型加载阶段,尤其难排查。

6.3 references文件过大导致上下文爆炸

我早期在 references 里放过一个 800 行的历史缺陷大表,结果 Skill 一被触发,模型就开始“失忆”——前面读过的用例规则后面就忘了,输出结果前言不搭后语。原因就是巨量静态内容把上下文窗口挤爆了,真正需要留给执行结果的注意力空间被占用殆尽。

解决方式前面已经说了:拆分文件,单文件控制在 200 行内,并且在 SKILL.md 里规定按需读取。这里还有一个隐藏经验:同一个 references 文件不要在一轮执行中反复读取。有段时间我的 SKILL.md 里两个步骤都要读同一份用例模板,模型会分别读取两次,白白浪费上下文。优化成“第一步读取并缓存,后续步骤引用第一步的结论”之后,输出稳定性提升明显。

6.4 依赖安装与环境问题:pnpm ignored build scripts 与 .venv 路径

Skill 的脚本如果依赖了 Node 生态的包,很容易遇到一类很典型的报错:[err_pnpm_ignored_builds] ignored build scripts: core-js@3.45.1, esbuild@0.2。这其实是 pnpm 安全策略在默认拦截依赖包的安装后构建脚本,导致像 esbuild 这种依赖二进制文件的包没有完整初始化。表现就是脚本运行时报模块找不到,或者二进制执行报错。

解决方法也不复杂:在 pnpm 项目里运行pnpm approve-builds交互式确认放行,或者在 package.json 里配置onlyBuiltDependencies,把确实需要构建脚本的可信包加进去。关键是出了问题要知道是构建脚本被拦截,而不是依赖没有安装。

Python 生态也有自己的环境坑。比如 Windows 下 PyCharm 执行脚本报e:\ip_location_tool\.venv\scripts\python.exe路径相关错误,多半是项目目录移动过,导致虚拟环境里的路径关联失效。我的习惯是:Skill 脚本启动时先做一次环境自检,检测python -c "import requests"能不能通过,不能就直接打印“依赖缺失,请运行 requirements.txt”,而不是让 Agent 在一堆晦涩的 traceback 里瞎猜。

6.5 让Agent更稳定地解析脚本输出

即使脚本本身没有 bug,Agent 解析输出时也可能出问题。我遇到过 Agent 把脚本输出的状态码 422 理解成“接口正常,因为 422 也是响应”,完全忽略了它不在预期状态码范围内。后来我把“预期状态码”和“实际状态码”写进了 JSON 输出的字段名里,同时在 SKILL.md 的质量门禁里加了一句“actual_status 与 expected_status 不一致时,一律视为用例失败,不允许解释为环境正常”。

还有一点,脚本 stdout 里不要出现任何和 JSON 无关的内容,比如打印“测试中,请稍候”这种提示语。有次我在脚本里留了一行调试打印,结果 Agent 解析 JSON 时把它也当成输出内容了,导致结果解析失败。调试输出一律走 log 文件,stdout 保持纯净。

6.6 安全边界:测试Skill也是有权限的执行者

最后聊一个容易被忽视的问题:Skill 的 scripts 是带执行能力的,尤其是测试脚本,它可能要往被测环境发大量请求,甚至写文件。我这里有三条安全底线:

  • 不在 scripts 里硬编码任何生产环境的地址和密钥,所有环境信息通过 config.json 注入,并且 config.json 不进版本库。
  • 给 Agent 限定可执行命令白名单。SKILL.md 里明确写了哪些脚本可以调用、参数长什么样,超出清单的命令一律不执行。测试场景下,Agent 不需要拥有任意 shell 权限。
  • 测试数据脱敏后再放进 references。samples 里的请求样例,该打码的打码,避免把真实手机号、邮箱、token 留在静态文件里。

安全这块很多人觉得“多此一举”,但 Skill 一旦被分享或者被自动化任务触发,权限失控的后果是被放大的。宁可前期多做一层约束,也不能拿生产稳定性去赌。

我在实际项目中把这套三层结构打磨了大半年,最大的感受是:一个测试 Skill 的价值不在它有多“聪明”,而在它有多“守规矩”。SKILL.md 管住决策流程,scripts 管住执行确定性,references 管住知识完整性,三者各守边界,AI 助手才能真正变成一个可信的测试协作者。这套方法论不只是接口回归能用到,单元测试、UI 冒烟、性能测试预处理这些场景,按同样的思路都能搭建出结构清晰的 Skill,值得你在自己的项目里试一遍。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/9 9:39:24

C++集成qrencode生成二维码:从编译到输出的完整工程实践

简介:使用C与qrencode库生成二维码的完整工程,面向需要在Windows下集成二维码功能的Visual Studio开发者。压缩包共34个文件,包含qrencode库源码(10个h头文件与9个c实现)、VS2015/2019/2022工程文件(sln、v…

作者头像 李华
网站建设 2026/9/9 9:37:12

React项目中Highcharts图表集成实战:从选型到性能优化

我大概统计了一下自己做过的React数据可视化项目,只要涉及图表需求,超过一半的同事第一反应是“装一个ECharts吧”。但如果你接手的项目是国际化产品、对浏览器兼容性有硬指标,或者对方是一家外企、金融公司,那Highcharts的出现频…

作者头像 李华
网站建设 2026/9/9 9:36:09

HTOOL-SL6H双通道射频信号源实战指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/9 9:34:13

基于SpringBoot+Vue的蛋糕店管理系统设计与实现

1. 毕设选题没头绪?蛋糕店这套业务逻辑为什么值得做 每年到毕业设计环节,大部分同学最先卡住的问题不是"怎么做",而是"做什么"。数据库课程设计也好、软件工程综合项目也罢,选一个既能体现工作量、又能讲清楚…

作者头像 李华
网站建设 2026/9/9 9:33:18

ECC内存纠错与MBIST测试:从uncorr. ecc错误计数到硬件排查指南

提到“ECC”这仨字母,干服务器、存储或嵌入式的人大概率会想到内存纠错码(Error Correction Code)。最近遇到一台设备日志里冒出“uncorr. ecc 显示2”,旁边还跟了一条MBIST ECC相关的告警,排查了一圈才把事情理顺。这…

作者头像 李华
网站建设 2026/9/9 9:33:08

Python+微信小程序打造考研资料共享平台:架构设计与实战避坑指南

去年帮朋友找考研专业课真题,翻了三个旧群、点了十几个失效网盘链接之后,我决定用 Python 做后端、微信小程序做前端,自己搞一个考研资料共享平台。这年头考研资料不是没有,而是碎得离谱:网盘链接说挂就挂,…

作者头像 李华