agent-next:Skills 与 Workflow——测试 Agent 的职责拆分与阶段驱动

1. 引子
上一篇文章讲的是 agent-next 这套 Harness 怎么接进测试流水线:入口怎么选、阶段怎么推进、状态怎么落盘、门禁怎么挡住越界动作。
这一篇不再从 Harness 全景展开,而是往里拆一层:Skills 和 Workflow 到底怎么分工。
如果你长期让 Agent 写测试用例,大概率会遇到一个很熟悉的问题:它不是不会写,而是太容易把事情混在一起。
用户说“帮我看下这个需求”,它可能直接开始写用例;用户说“验证一下”,它可能跳过影响分析去跑浏览器;你让它遵守用例模板,它这次记住了,下次又漏了 frontmatter;你把流程、格式、领域知识、执行纪律全塞进一个 Prompt,短期看起来省事,长期一定会变成一份越来越难维护的“大手册”。
agent-next 在这里做了一个比较克制的选择:
不指望 Prompt 变得越来越聪明,而是让职责边界变得越来越硬。
这篇文章的主线就是这句话。
一句话分工仍然是:
Router 指路,Workflow 定阶段,Skill 承载专长,Knowledge 解释领域,Tool 执行门禁。
后面会用 feature-testing 做例子,但重点不是“产线产量趋势视图”这个具体业务,而是 agent-next 怎么把一个测试 Agent 拆成可路由、可审计、可替换的阶段系统。
2. 为什么不是一个大 Prompt
最直接的做法当然是写一个很长的 Prompt。
1 | 所有入口 |
这个方案在 demo 里很顺。因为 demo 通常只有一个任务、一条路径、少量规则,Agent 只要把结果写得像样就可以。
但真实测试任务不是这样。特性测试、Bug 回归、发布验收共享很多能力,却有完全不同的入口、阶段和准入证据。把它们塞进一个 Prompt 后,常见问题会一起出现:
| 问题 | 结果 |
|---|---|
| Prompt 同时负责流程和技能 | 改一个阶段规则,可能影响其它阶段 |
| 所有知识一次加载 | 上下文膨胀,关键规则反而被稀释 |
| 格式规则靠模型记忆 | 产物缺 frontmatter、标题格式漂移 |
| 执行纪律靠模型自觉 | 可能提前写 ZenTao、跑共享环境、跳过确认 |
| 阶段完成靠口头声明 | 无法证明 Agent 真的读过某个 Skill |
agent-next 没有继续把 Prompt 做厚,而是把“规则”拆到几类仓库资产里。
| 资产 | 负责什么 | 不负责什么 |
|---|---|---|
| Router | 选择 entry、定位当前 phase | 不写需求、用例、报告 |
| Workflow | 定义阶段顺序、输入输出、当前阶段 required skills | 不承载领域细节 |
| Skill | 说明当前阶段怎么做 | 不决定全流程顺序 |
| Reference | 放格式细则、转换规则、写作纪律 | 不做阶段路由 |
| Knowledge | 放可复用领域知识 | 不替代本次任务证据 |
| Tool / Gate | 校验状态、模板、receipt、artifact | 不靠自然语言判断通过 |
上一篇讲的是这套 Harness 的整体骨架;这篇讲的是骨架里的边界为什么要这样切。
3. 职责边界图
先看一张完整链路图。

我更喜欢把它理解成六个问题:
| 层级 | 回答的问题 | 例子 |
|---|---|---|
| Router | 现在去哪? | feature-testing、bug-regression、release-acceptance |
| Workflow | 下一步是什么? | Intake → Requirement Specification → Risk Analysis |
| Skill | 这一步怎么做? | 需求分析、测试点设计、自动化分类 |
| Reference | 格式和细则是什么? | 用例写作规则、自动化转换规则 |
| Knowledge | 领域知识是什么? | ePVS 术语、页面规则、计算口径 |
| Tool / Gate | 机器是否允许继续? | stage_gate.py、validate_test_cases.py |
这几个问题不能混。
Router 一旦开始写用例,入口层就会变胖;Workflow 一旦塞进大量业务说明,Lazy Load 就失去意义;Skill 一旦接管流程顺序,下游阶段就容易跳;Knowledge 一旦混进本次任务证据,后续复盘时很难判断结论来自哪里。
拆开以后,每一层都能单独演进:
- 换领域:替换
knowledge/和 workflow 表头。 - 换流程:新增或修改
workflows/<entry>/phases/*.md。 - 换技能:更新某个
skills/<name>/SKILL.md。 - 换格式:更新 references 或 templates。
- 换模型:Harness 不变,只换 provider。
这里的稳定性不是来自某个万能 Prompt,而是来自边界不被打穿。
4. Skill:窄职责,不接管流程
在 agent-next 里,Skill 不是一本大手册,而是一个很小的能力包:
1 | skills/<name>/ |
以 ePVS 测试为例,目录大概长这样:
1 | skills/ |
为什么要这么碎?
因为一个“全能 Skill”看起来方便,实际会带来几个问题:
- 每次加载都要读一堆当前阶段用不到的规则。
- 修改自动化规则时,可能影响需求分析阶段。
- 格式细则、执行纪律、业务知识互相挤在一起。
- 门禁无法精确验证当前阶段该读的 Skill 是否真的被读过。
所以 Skill 的边界要小到可以被阶段声明、被 receipt 记录、被 gate 校验。
| Skill | 负责 | 不负责 |
|---|---|---|
epvs-requirement |
Intake、需求规格 | 不写测试用例 |
epvs-test-points |
风险、测试点 | 不上传 ZenTao |
epvs-test-cases |
用例设计、格式纪律 | 不决定是否执行自动化 |
epvs-automation |
分类、转换计划、执行协调 | 不直接替代 API/Web 工程规则 |
envision-apitest |
YAML + pytest API 自动化 | 不处理 Web PageObject |
envision-webtest |
Playwright + pytest UI 自动化 | 不写纯接口 YAML |
自动化这块最能体现这层拆分。
epvs-automation 先解析测试用例,再判断每条用例的 target 和 level:
| 等级 | 含义 | 处理 |
|---|---|---|
A0 |
selector、接口、数据稳定 | 可进入实现或执行计划 |
A1 |
可自动化,但缺 selector、fixture、PageObject 或上下文参数 | 先补支撑能力 |
M0 |
半自动,需要截图、图表、视觉或人工判断 | 生成辅助步骤和证据 |
N0 |
不适合自动化或风险过高 | 保留手工并记录原因 |
分类完成后,再落到具体工程:
| target | 后续 Skill | 仓库 | 典型产物 |
|---|---|---|---|
api |
envision-apitest |
repositories/test/envision-apitest |
testcases/data/*.yaml |
web |
envision-webtest |
repositories/test/envision-webtest |
Playwright + pytest cases |
hybrid |
envision-webtest |
repositories/test/envision-webtest |
UI 路径 + Network/API 观察 |
manual |
不进入自动化仓库 | 无 | 手工证据要求 |
也就是说,epvs-automation 管“怎么分类、怎么计划、怎么记录追溯”,envision-apitest 和 envision-webtest 管“在具体测试仓库里怎么落地”。这比一个自动化大 Prompt 更啰嗦一点,但更容易维护,也更容易审。
5. Workflow:定义阶段,不承载知识
Workflow 只解决一件事:阶段顺序。
agent-next 当前有三个入口:
| Entry | 何时用 | 阶段数 |
|---|---|---|
feature-testing |
PRD、需求单、特性 MR | 8(含可选) |
bug-regression |
Bug ID、修复 MR | 8 |
release-acceptance |
版本、tag、发布验收 | 6(含可选) |
目录形态是:
1 | workflows/<entry>/ |
每个 phase 文件只保留当前阶段最小必要信息:
1 | 目标 / 输入 / 产出 |
它不写长篇领域说明,不写用例标题规范,也不写 API 自动化工程的具体细节。
原因很现实:
- Workflow 是流程资产,应该稳定、短小、可索引。
- Knowledge 是领域资产,会随业务迁移。
- Reference 是格式资产,会随产物规则变化。
- Tool 是执行资产,应该用代码校验,不靠自然语言。
如果 Workflow 开始承载一切,Lazy Load 很快就会失效。Router 瘦了,下游 Skill 却又拉回一本 workflow 大书,最后只是换了一个地方堆 Prompt。
6. receipt:把“读过 Skill”变成证据
仅靠 Agent 说“我已经读过这个 Skill”没有意义。
agent-next 要求每次加载 Skill 后写入 skill_receipts[]:
1 | { |
它把“读过 Skill”从一句聊天里的声明,变成 run state 里的证据。

这个闭环很小,但很有用。
没有 receipt,Skill 只是 Prompt 建议;有了 receipt,Skill 就进入机器可检查的状态。Gate 不需要相信模型,只需要检查 state。
Reference 也是同样逻辑。例如写测试用例前必须读 case-writing-rules.md,并记录 case_rules_receipt:。即使用例内容看起来没问题,只要这个证据缺失,阶段就不能完成。
7. Lazy Load 的重点:Not Loaded
Lazy Load 经常被理解成“这一阶段加载了什么”。但更关键的是另一半:这一阶段没有加载什么。
如果 Phase 2 只是写需求规格,它就不应该加载自动化、报告、ZenTao 写入、发布验收。少加载不是省 token 的小技巧,而是在减少 Agent 可以误用的规则。
| Phase | Loaded | Not Loaded |
|---|---|---|
| Intake | agent-next, epvs-requirement, workflow index, current phase |
automation、reporting、ZenTao write、acceptance |
| Requirement Specification | epvs-requirement, relevant knowledge, source evidence |
test-cases、automation、execution |
| Test Design | epvs-test-points, epvs-test-cases, case rules |
ZenTao write、API/Web execution、release acceptance |
| Optional Case Sync Or Generation | epvs-zentao-sync and/or epvs-automation |
reporting、bug report unless needed |
| Optional Case Execute | epvs-automation, envision-apitest / envision-webtest |
requirement authoring、risk authoring |
| Optional Test Report | epvs-reporting |
new case writing、new automation generation |
传统 Prompt 的倾向是“为了保险,多给一点上下文”。agent-next 反过来:
当前阶段用不到的东西,不应该进入上下文。
原因很简单:
- Context 是有限资源。
- Workflow 是阶段性的。
- Knowledge 是条件性的。
- Tool 是执行性的,不需要全文读进 Prompt。
Lazy Load 的收益不只是 token 下降,而是 Agent 的注意力变窄了:它更难跳阶段,更难把报告规则带进用例阶段,也更难在需求阶段误触发自动化。
8. Stage Gate:Fail Closed
Stage Gate 不是提示词里的 checklist,而是机器门禁。
1 | python3 tools/stage_gate.py --state runs/<run-id>/state.json |
Gate 检查的不是“Agent 觉得做完了没有”,而是 state 和 artifact 是否满足规则。
| Gate | 检查什么 | 防什么问题 |
|---|---|---|
| Run state | runs/<run-id>/state.json 是否存在 |
对话丢失后无法复盘 |
| Product line | v1 / v2 是否记录 |
产物路径和分支选错 |
| Skill receipt | required skills 是否有 path + sha256 | Agent 声称读过但没读 |
| Template | artifact 是否由 copy_template.py 生成 |
手写 Markdown 格式漂移 |
| Artifact validation | validate_artifact.py / validate_test_cases.py |
缺 frontmatter 或必填段落 |
| Confirmation | 写 ZenTao、共享环境执行、数据变更前是否确认 | Agent 擅自执行副作用 |
| Traceability | REQ → RISK → TP → TC → AUTO → RUN | 无法从报告追溯到需求 |
这就是 Fail Closed:证据不完整时,默认失败。
Prompt 可以漏读,模型可以误判,阶段可以被用户催着跳。但 Gate 不允许在证据缺失时宣称完成。
9. Agent 生命周期总时序
把上面的边界串起来,一次阶段推进大致是这样:

这张图里没有一个步骤要求模型“自己记住所有规则”。规则在仓库里,证据在 state 里,校验在工具里。
9.1. 跟着 Agent 走一次
只看图还是有点抽象。我们拿 Test Design 阶段走一遍,看看 Agent 在一个阶段里到底怎么“想”。
用户不会说“请进入 feature-testing 的 Test Design 阶段”。用户通常只会说:“需求和风险都整理好了,帮我把测试点和用例补出来。”
这时 Agent 的第一步不是写用例,而是先定位自己在哪。
1 | 用户意图:补测试点和测试用例 |
读完 phase 后,Agent 才知道这一阶段的边界:
- 输入不是原始需求,而是上游
requirement_spec和risk_analysis。 - 输出不是一份随手写的 Markdown,而是
test_points和test_cases两个 artifact。 - 必须加载
epvs-test-points和epvs-test-cases。 - 写用例前必须读取
case-writing-rules.md。
接下来才进入 Skill 和 Reference:
1 | Load epvs-test-points |
这一步很像人做测试设计前先翻团队规范。区别是,Agent 不能只说“我看过了”,而要把 receipt 写进 run state。后面的 Gate 会检查这个证据。
然后才是生成产物。Agent 不会新建一个空 Markdown 文件,而是先走模板:
1 | copy_template.py --template test-points |
模板给出 frontmatter、artifact type、producer phase、source artifacts、validation 等结构。Agent 在这个结构里填内容,才能保证后续工具读得懂。
产物写完也不是结束。Agent 还要把它交给机器校验:
1 | validate_artifact.py --artifact-type test_points |
如果 case_rules_receipt: 缺了,或者 test_cases 不是从模板创建的,即使内容看起来合理,阶段也不能通过。Gate 不关心 Agent 的解释,只看证据是否完整。
所以一次阶段推进,真正的顺序是:
1 | User request |
这就是 agent-next 里“思考”的形状:模型负责在边界内完成内容判断,Harness 负责决定它能不能进入下一步。
10. feature-testing 压缩案例
下面用“产线产量趋势视图”这个 feature-testing 任务做一个压缩版案例。业务细节不展开,重点看每个阶段如何体现职责边界。
10.1. 阶段表
| Phase | 输入 | 输出 | Required Skills | Gate 关注点 |
|---|---|---|---|---|
| Intake | ZenTao Task / Requirement、设计文档、代码分支 | notes[]、knowledge_plan |
agent-next, epvs-requirement |
intake_input:、product_line、知识计划 |
| Requirement Specification | Intake 证据、源码、knowledge | requirement_spec |
epvs-requirement |
模板、artifact metadata、source evidence |
| Risk Analysis | 需求规格、源码证据 | risk_analysis |
epvs-test-points |
风险矩阵、repository evidence |
| Test Design | 需求规格、风险分析 | test_points, test_cases |
epvs-test-points, epvs-test-cases |
case_rules_receipt:、validate_test_cases.py |
| Optional Case Sync Or Generation | 已确认用例 | ZenTao 同步结果、automation_classification |
epvs-zentao-sync and/or epvs-automation |
用户确认、自动化分类 |
| Optional Case Execute | 用例、环境、测试仓库 | execution_record |
epvs-automation, API/Web Skill |
环境确认、执行证据 |
| Optional Bug Report | 失败证据 | bug_report |
epvs-reporting, epvs-zentao-sync |
bug 证据、写入确认 |
| Optional Test Report | 全链路证据 | run_summary |
epvs-reporting |
traceability、报告 artifact |
这张表给的是全局视图。真正能看出 Workflow 在驱动的,是后半段几个阶段怎么一层层收窄:先把需求和风险变成测试点,再把测试点变成用例,再把用例分到 API/Web 自动化,最后把执行证据收束成报告。
10.2. Test Design:把风险变成可执行用例
Test Design 阶段加载 epvs-test-points 和 epvs-test-cases。它不是从需求直接“生成一批用例”,而是沿着前两个阶段的产物往下走:
1 | requirement_spec |
这个案例里,最终产出:
outputs/v2/test-points/产线产量趋势视图-test-points.md:10 个测试点。outputs/v2/test-cases/产线产量趋势视图-test-cases.md:19 条测试用例。
这里的 Gate 关注两件事。
第一,测试用例必须从 copy_template.py --template test-cases 生成,不能手写一个看起来像 Markdown 的文件。第二,写用例前必须读取 skills/epvs-test-cases/references/case-writing-rules.md,并记录 case_rules_receipt:。也就是说,用例不是“写出来就算完成”,而是要带着格式规则的读取证据和 validate_test_cases.py 的校验结果一起进入下一阶段。
10.3. Automation:先分类,再落仓库
Optional Case Sync Or Generation 阶段有两个方向:同步到 ZenTao,或者做自动化分类。这个案例里两件事都做了:19 条用例上传到 ZenTao(IDs 2558-2576),随后进入自动化分类。
自动化不是把 19 条用例直接丢给某个测试仓库。epvs-automation 先判断每条用例适合哪条轨道、自动化等级是什么、还缺不缺 fixture、selector 或 PageObject。分类结果是:
| 轨道 | 数量 | 后续 Skill | 落地形态 |
|---|---|---|---|
| API | 12 | envision-apitest |
YAML 数据驱动 + pytest |
| Web | 7 | envision-webtest |
Playwright + pytest + PageObject/ViewObject |
这一步的重点不是执行,而是把“能不能自动化、在哪里自动化、需要补什么能力”说清楚。对于新分类出来的用例,不能从 classification 直接跳到 execution;必须先有 conversion plan、测试仓库草稿和窄范围验证。
10.4. Execution:执行证据不是一句 pass
Optional Case Execute 阶段才真正执行自动化。这个阶段加载 epvs-automation,再根据轨道加载 envision-apitest 或 envision-webtest。
API 轨道进入 repositories/test/envision-apitest,核心文件是 27_get_line_jph.yaml。用例通过 YAML 描述请求路径、参数和 assert_data,再由 pytest 参数化执行。这个案例里,API 分类 12 条,其中 11 条进入执行并通过,1 条因为环境 ClickHouse 查询超时标记为 is_run=false,不计入执行通过率。
Web 轨道进入 repositories/test/envision-webtest,核心文件是 test_s03_jph_trend.py。它不是散写 selector,而是通过 PageObject/ViewObject 表达用户路径、结构树、Tab、图表和下钻动作。这个案例里,Web 7 条全部通过。
1 | API: 11 pass, 1 skip, 0 fail |
Gate 在这里关心的不是“终端里有没有绿色输出”,而是执行命令、目标环境、测试仓库分支、结果摘要和产物路径是否被记录到 execution record 里。共享环境执行前,还必须有用户确认。
10.5. Report:把链路收束起来
Optional Test Report 阶段加载 epvs-reporting,产出 run_summary。这一步不是简单写一句“测试通过”,而是把上游证据串起来:
1 | REQ-SPEC-001 |
最终报告落在:
1 | outputs/v2/reports/产线产量趋势视图-run-summary.md |
到这里,Workflow 的作用才完整显出来:每个阶段不是孤立产物,而是把上一个阶段的证据继续结构化,直到最后可以从运行报告追溯回需求、风险、测试点、用例、自动化分类和执行记录。
10.6. outputs/ 目录结构
Markdown 交付物统一落在 outputs/,不和运行状态、自动化工程混在一起:
1 | outputs/ |
对应边界是:
outputs/:人审交付物。runs/<run-id>/:run state、receipt、门禁证据、中间规格。repositories/test/envision-apitest:API 自动化工程。repositories/test/envision-webtest:Web/UI 自动化工程。
10.7. 最终交付清单
| 阶段 | 状态 | 产物 |
|---|---|---|
| 需求分析 | 完成 | 需求说明书 |
| 风险分析 | 完成 | 10 项风险矩阵 |
| 测试设计 | 完成 | 10 测试点 + 19 测试用例 |
| 禅道上传 | 完成 | 19 条用例(IDs 2558-2576) |
| 自动化分类 | 完成 | API 12 条 / Web 7 条 |
| API 执行 | 11/11 通过,1 条配置跳过 | 27_get_line_jph.yaml |
| Web 执行 | 7/7 通过 | test_s03_jph_trend.py |
| 运行报告 | 完成 | outputs/v2/reports/产线产量趋势视图-run-summary.md |
这张表的意义不是展示业务复杂度,而是展示链路完整性:从 requirement 到 risk、test point、test case、automation、execution、report,每一步都有对应 artifact 和 gate evidence。
11. 传统 Prompt vs agent-next
最后放在一起看,两种模式的差异会更明显。
| 维度 | 传统 Prompt | agent-next |
|---|---|---|
| 规则存放 | 全塞进 Prompt | Router / Workflow / Skill / Reference / Tool 分层 |
| 流程推进 | 模型自行判断 | Workflow + Phase |
| 技能加载 | 一次性读大段上下文 | 当前阶段 required skills |
| 领域知识 | 混在 Prompt | knowledge/ 按需读取 |
| 格式校验 | 靠模型遵守 | template + validator |
| 是否读过 Skill | 只能相信模型 | skill_receipts[] |
| 阶段完成 | 模型声明 | stage_gate.py fail closed |
| 维护方式 | Prompt 越来越长 | 各层资产独立演进 |
传统 Agent 希望 Prompt 足够聪明;agent-next 希望流程足够可靠。
这不是否定模型能力,而是不把系统可靠性押在模型记忆上。
12. 结语
Skills 和 Workflow 的价值,不是把测试流程写得更复杂,而是把职责拆到足够清楚。
Router 只回答现在去哪。Workflow 只回答下一步是什么。Skill 只回答这一步怎么做。Reference 只回答格式和细则。Knowledge 只回答领域知识。Tool 和 Gate 只回答能不能继续。
Prompt 可以犯错,Gate 不允许越界。
Skill 可以升级,Workflow 可以替换,Knowledge 可以迁移,Tool 可以验证。
真正稳定的不是 Prompt,而是职责边界。
最后希望大家可以点赞评论~


