
最近我被一个老接口坑了整整一个下午。前端没有任何报错服务端接口悄悄改了响应结构等数据传到业务层才发现异常测试用例已经积压了二十多条。那一刻我意识到光靠人肉回归和临时写的 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 负责拆解用户的目标判断当前任务属于哪个专业领域然后决定调用哪个 SkillSkill 则负责把某个专业任务的执行流程、工具、知识打包好让 Agent 拿过来就能照着做。放到测试场景里更直观。你让 Agent “帮我看下登录接口这次改动有没有问题”Agent 先理解这是一个接口回归测试任务于是加载 api-smoke-regression 这个 Skill。Skill 告诉它先读用例模板再定位受影响用例接着运行 scripts 里的回归脚本最后按 references 里的缺陷分级标准输出报告。Agent 负责中间的判断和沟通Skill 负责把专业流程固定下来。搞不清这层关系的人最容易犯的错就是让 Skill 越权去“思考”在 SKILL.md 里写一堆开放式问题结果 Skill 被 Agent 当成一个普通的上下文文档完全失去了约束力。2. 第一步SKILL.md——把测试流程写成Agent能严格执行的文档2.1 frontmatterAgent决定是否调用你的关键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(encodingutf-8)) def run_case(case: dict, base_url: str) - dict: url base_url.rstrip(/) case[api_path] resp requests.request( methodcase.get(method, POST), urlurl, headerscase.get(headers, {}), jsoncase.get(body, {}), timeout10, ) 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(encodingutf-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_asciiFalse, indent2), encodingutf-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非核心功能异常不影响主流程计入迭代 backlogP3样式、文案等非功能问题有时间再修有了这份标准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.jsonconfig.json 里存放的是环境配置包括 base_url、超时时间、公共请求头等信息。注意我刻意没有把用例直接写进 scripts 里而是单独维护 cases.json这样每次回归只需要更新用例数据不用改脚本。5.3 模拟一次完整的调用链路下面这段是模拟用户与 Agent 的交互过程我把 Skill 的触发和执行链路完整走一遍。用户输入“登录接口的响应里多了一个 flag 字段原来的 token 字段改名成了 access_token帮我做一下回归测试。”Agent 收到后判断这属于接口变更触发的回归测试匹配到 api-smoke-regression Skill读取 SKILL.md。它按执行步骤走读取 references/templates/test_case_template.md了解用例格式规范。读取 references/samples/login_response.json对比新旧响应结构发现token字段缺失flag字段新增于是标记已有用例中所有断言了token字段的用例为“受影响”。在 references/knowledge/regression_risk_checklist.md 的提示下Agent 补充了一条新用例验证access_token存在且为用户私有。运行python scripts/run_regression.py --config config.json执行测试脚本产出 results.json。运行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-js3.45.1, esbuild0.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更稳定地解析脚本输出即使脚本本身没有 bugAgent 解析输出时也可能出问题。我遇到过 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值得你在自己的项目里试一遍。