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
2
3
4
5
所有入口
→ 一个超长 Prompt
→ 里面放流程、格式、领域知识、工具纪律
→ Agent 自己判断当前应该做哪一步
→ 输出 Markdown / 执行命令 / 写外部系统

这个方案在 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. 职责边界图

先看一张完整链路图。

607

我更喜欢把它理解成六个问题:

层级 回答的问题 例子
Router 现在去哪? feature-testing、bug-regression、release-acceptance
Workflow 下一步是什么? Intake → Requirement Specification → Risk Analysis
Skill 这一步怎么做? 需求分析、测试点设计、自动化分类
Reference 格式和细则是什么? 用例写作规则、自动化转换规则
Knowledge 领域知识是什么? ePVS 术语、页面规则、计算口径
Tool / Gate 机器是否允许继续? stage_gate.pyvalidate_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
2
3
4
skills/<name>/
├── SKILL.md
└── references/
└── ...

以 ePVS 测试为例,目录大概长这样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
skills/
├── agent-next/SKILL.md # Router,只调度不写用例
├── epvs-requirement/ # 需求摄入 + 规格
├── epvs-test-points/ # 风险分析 + 测试点
├── epvs-test-cases/ # 测试用例设计
│ └── references/case-writing-rules.md
├── epvs-automation/ # 自动化分类 + 生成 + 执行协调
│ └── references/
│ ├── automation-conversion-rules.md
│ └── webtest-patterns.md
├── envision-apitest/ # API 自动化落地
├── envision-webtest/ # Web/UI 自动化落地
├── epvs-reporting/ # 报告 + 结项
├── epvs-zentao-sync/ # 禅道同步,条件加载
├── epvs-data-injection/ # 数据注入,条件加载
└── epvs-acceptance/ # 发布验收

为什么要这么碎?

因为一个“全能 Skill”看起来方便,实际会带来几个问题:

  1. 每次加载都要读一堆当前阶段用不到的规则。
  2. 修改自动化规则时,可能影响需求分析阶段。
  3. 格式细则、执行纪律、业务知识互相挤在一起。
  4. 门禁无法精确验证当前阶段该读的 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 先解析测试用例,再判断每条用例的 targetlevel

等级 含义 处理
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-apitestenvision-webtest 管“在具体测试仓库里怎么落地”。这比一个自动化大 Prompt 更啰嗦一点,但更容易维护,也更容易审。


5. Workflow:定义阶段,不承载知识

Workflow 只解决一件事:阶段顺序

agent-next 当前有三个入口:

Entry 何时用 阶段数
feature-testing PRD、需求单、特性 MR 8(含可选)
bug-regression Bug ID、修复 MR 8
release-acceptance 版本、tag、发布验收 6(含可选)

目录形态是:

1
2
3
4
5
6
workflows/<entry>/
├── README.md
└── phases/
├── 01-intake.md
├── 02-requirement-specification.md
└── ...

每个 phase 文件只保留当前阶段最小必要信息:

1
2
3
4
目标 / 输入 / 产出
Skills / Environment / Repository
Gate / Machine
Prev → Next

它不写长篇领域说明,不写用例标题规范,也不写 API 自动化工程的具体细节。

原因很现实:

  • Workflow 是流程资产,应该稳定、短小、可索引。
  • Knowledge 是领域资产,会随业务迁移。
  • Reference 是格式资产,会随产物规则变化。
  • Tool 是执行资产,应该用代码校验,不靠自然语言。

如果 Workflow 开始承载一切,Lazy Load 很快就会失效。Router 瘦了,下游 Skill 却又拉回一本 workflow 大书,最后只是换了一个地方堆 Prompt。


6. receipt:把“读过 Skill”变成证据

仅靠 Agent 说“我已经读过这个 Skill”没有意义。

agent-next 要求每次加载 Skill 后写入 skill_receipts[]

1
2
3
4
5
6
7
8
9
10
{
"skill_receipts": [
{
"skill": "epvs-test-cases",
"path": "skills/epvs-test-cases/SKILL.md",
"sha256": "e675403ea2c8987a7a9c69ac04595711753a0cf040f3cd39c0b118868588696e",
"supports_phase": "Test Design"
}
]
}

它把“读过 Skill”从一句聊天里的声明,变成 run state 里的证据。

704

这个闭环很小,但很有用。

没有 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 反过来:

当前阶段用不到的东西,不应该进入上下文。

原因很简单:

  1. Context 是有限资源。
  2. Workflow 是阶段性的。
  3. Knowledge 是条件性的。
  4. 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
2
3
4
用户意图:补测试点和测试用例
→ Router 确认仍在 feature-testing
→ Workflow 确认当前 phase 是 Test Design
→ phase_doc.py 解析 04-test-design.md

读完 phase 后,Agent 才知道这一阶段的边界:

  • 输入不是原始需求,而是上游 requirement_specrisk_analysis
  • 输出不是一份随手写的 Markdown,而是 test_pointstest_cases 两个 artifact。
  • 必须加载 epvs-test-pointsepvs-test-cases
  • 写用例前必须读取 case-writing-rules.md

接下来才进入 Skill 和 Reference:

1
2
3
4
5
Load epvs-test-points
Load epvs-test-cases
Record skill_receipts[]
Read references/case-writing-rules.md
Record case_rules_receipt:

这一步很像人做测试设计前先翻团队规范。区别是,Agent 不能只说“我看过了”,而要把 receipt 写进 run state。后面的 Gate 会检查这个证据。

然后才是生成产物。Agent 不会新建一个空 Markdown 文件,而是先走模板:

1
2
copy_template.py --template test-points
copy_template.py --template test-cases

模板给出 frontmatter、artifact type、producer phase、source artifacts、validation 等结构。Agent 在这个结构里填内容,才能保证后续工具读得懂。

产物写完也不是结束。Agent 还要把它交给机器校验:

1
2
3
validate_artifact.py --artifact-type test_points
validate_test_cases.py --artifact-file ...
stage_gate.py --state runs/<run-id>/state.json

如果 case_rules_receipt: 缺了,或者 test_cases 不是从模板创建的,即使内容看起来合理,阶段也不能通过。Gate 不关心 Agent 的解释,只看证据是否完整。

所以一次阶段推进,真正的顺序是:

1
2
3
4
5
6
7
8
9
10
11
User request
→ Router 定位 entry
→ Workflow 定位 phase
→ Phase 声明输入、输出、required skills
→ Skill 给出做法
→ Reference 给出细则
→ Knowledge 补领域语义
→ Template 约束产物结构
→ Artifact 落到 outputs/
→ Gate 校验证据
→ Next Phase

这就是 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-pointsepvs-test-cases。它不是从需求直接“生成一批用例”,而是沿着前两个阶段的产物往下走:

1
2
3
4
requirement_spec
→ risk_analysis
→ test_points
→ test_cases

这个案例里,最终产出:

  • 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-apitestenvision-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
2
API:  11 pass, 1 skip, 0 fail
Web: 7 pass, 0 fail

Gate 在这里关心的不是“终端里有没有绿色输出”,而是执行命令、目标环境、测试仓库分支、结果摘要和产物路径是否被记录到 execution record 里。共享环境执行前,还必须有用户确认。

10.5. Report:把链路收束起来

Optional Test Report 阶段加载 epvs-reporting,产出 run_summary。这一步不是简单写一句“测试通过”,而是把上游证据串起来:

1
2
3
4
5
6
REQ-SPEC-001
→ RISK-001
→ TP-001
→ TC-SET-001
→ AUTO-CLASS-001
→ RUN-SUMMARY-001

最终报告落在:

1
outputs/v2/reports/产线产量趋势视图-run-summary.md

到这里,Workflow 的作用才完整显出来:每个阶段不是孤立产物,而是把上一个阶段的证据继续结构化,直到最后可以从运行报告追溯回需求、风险、测试点、用例、自动化分类和执行记录。

10.6. outputs/ 目录结构

Markdown 交付物统一落在 outputs/,不和运行状态、自动化工程混在一起:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
outputs/
├── requirements/
│ └── 产线产量趋势视图-requirement-spec.md
├── risks/
│ └── 产线产量趋势视图-risk-analysis.md
├── test-points/
│ └── 产线产量趋势视图-test-points.md
├── test-cases/
│ └── 产线产量趋势视图-test-cases.md
├── automation/
│ └── 产线产量趋势视图-classification.md
├── execution/
│ └── 产线产量趋势视图-execution-record.md
└── reports/
└── 产线产量趋势视图-run-summary.md

对应边界是:

  • 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,而是职责边界。

最后希望大家可以点赞评论~