From ae0ff5d4def185f2c299861eba2a9fa2f1eca364 Mon Sep 17 00:00:00 2001 From: Peter Zhang <18501667167@qq.com> Date: Tue, 2 Jun 2026 14:16:51 +0800 Subject: [PATCH] =?UTF-8?q?test:=20=E7=BB=9F=E4=B8=80=20Agent=20Issue=20?= =?UTF-8?q?=E8=BD=AE=E8=AF=A2=20label=20=E4=BD=93=E7=B3=BB=E4=B8=8E?= =?UTF-8?q?=E5=88=9B=E5=BB=BA=E8=A7=84=E5=88=99=20-=20Closes=20#40?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - test-dev → test-code:QE-Agent 一致化 label - Dev-Agent 新增 product-code label + [product] 前缀规则 - agent_poller.py 新增 create-issue action - QE/Dev Agent 轮询改为多轮递进:label → title 前缀 → 无标识分析 Co-Authored-By: Claude Opus 4.7 --- agents/DEV_AGENT.md | 42 ++++++- agents/QE_AGENT.md | 59 +++++++--- docs/QE_AGENT_WORKFLOW.html | 213 ++++++++++++++++++++++++++++++++++++ scripts/agent_poller.py | 34 +++++- scripts/start_qe_agent.sh | 8 +- 5 files changed, 331 insertions(+), 25 deletions(-) create mode 100644 docs/QE_AGENT_WORKFLOW.html diff --git a/agents/DEV_AGENT.md b/agents/DEV_AGENT.md index b1cec09..e186bb0 100644 --- a/agents/DEV_AGENT.md +++ b/agents/DEV_AGENT.md @@ -60,7 +60,10 @@ description: AI 开发专家,负责 document_analyzer 项目的功能开发、 1. 读取项目章程和全局状态:`docs/PROJECT_CHARTER.md` 和 `docs/GLOBAL_STATE.md` 2. 确认环境变量已设置(GITEA_URL, GITEA_REPO, GITEA_API_TOKEN) 3. 用 `/loop 10m` 开启 10 分钟间隔的自动轮询 -4. 轮询内容:`agent_poller.py --action list` 列出所有打开的非纯测试 Issue +4. 轮询内容(多轮递进): + a. `--action list --labels product-code` — 先捡带 `product-code` 标签的 Issue + b. `--action list` 无过滤,筛选 title 带 `[product]` 前缀的无标签 Issue + c. 都无则分析无标签、无标识的 Issue,判断是否在 Dev 域内 5. 有 issue → 走完整闭环处理(分析 → 开发 → push → PR → CI → merge → 自行验证 → 关闭) 6. 无 issue → 报告 "main healthy,无待处理 Issue",等待下次轮询 7. 同时保持对话开放,随时响应用户指令 @@ -69,17 +72,30 @@ description: AI 开发专家,负责 document_analyzer 项目的功能开发、 ### 1. 轮询 Issue -使用 `python scripts/agent_poller.py --action list` 列出所有当前开启的 Issue。 +**第一轮:捡带标签的 Issue** +```bash +python scripts/agent_poller.py --action list --labels product-code +``` + +**第二轮:捡无标签但 title 带前缀的 Issue** +```bash +python scripts/agent_poller.py --action list +``` +从输出中筛选 title 以 `[product]` 开头的无标签 Issue。 + +**第三轮:分析无标识 Issue** +如果以上两轮都无结果,分析所有无标签、无 title 标识的 Issue,判断是否属于 Dev 域。 **处理范围**:Dev-Agent 负责处理**所有非纯测试开发**相关的 Issue。具体来说: | 处理 | 跳过 | |------|------| -| `ci-failure` — CI 测试失败 | 标注为 QE-Agent 负责或纯测试实现的 Issue | +| `product-code` — 产品/功能开发 | 标注为 QE-Agent 负责或纯测试实现的 Issue | +| `ci-failure` — CI 测试失败 | | | `bug` — 功能缺陷 | | | `qe-feedback` — QE 反馈的功能/质量问题 | | | `feature` / `enhancement` — 新功能或改进需求 | | -| 无标签或自定义标签的 Issue | | +| `[product]` 前缀的无标签 Issue | | **判断原则**:如果 Issue 涉及功能代码、算法逻辑、IR 生成质量、一致性、覆盖率改进 — 你负责。如果 Issue 纯粹是关于测试框架搭建、测试用例编写 — 那是 QE-Agent 的领域。 @@ -207,12 +223,30 @@ QE-Agent 开 Issue (qe-feedback / bug / ci-failure) - **范围**:不混入与当前 Issue 无关的改动 - **PR**:Push 后立即创建 PR,CI 通过后 merge,PR 信息写入 Issue 后关闭 +## Issue 创建规则 + +创建 Issue 时,必须指定 label 以明确 Issue 归属: + +- **产品/功能 Issue** → `product-code` label(Dev-Agent 域) + ```bash + python scripts/agent_poller.py --action create-issue \ + --title "issue 标题" --labels product-code --body "..." + ``` +- **测试代码 Issue** → `test-code` label(QE-Agent 域) + ```bash + python scripts/agent_poller.py --action create-issue \ + --title "[test] issue 标题" --labels test-code --body "..." + ``` +- 多个 label 用逗号分隔,如 `--labels "ci-failure,product-code"` + ## agent_poller 命令速查 | 命令 | 用途 | 阶段 | |------|------|------| | `--action list` | 列出所有待处理 Issue | 1. 轮询 | +| `--action list --labels X` | 按标签筛选 Issue | 1. 轮询 | | `--action get --issue N` | 查看 Issue 详情 | 2. 分析 | +| `--action create-issue --title "..." --labels X --body "..."` | 创建 Issue | — | | `--action create-pr --issue N --branch X --body "..."` | 创建 PR | 4. 提 PR | | `--action comment --issue N --body "..."` | 评论 Issue(记录 PR 链接等) | 4. 提 PR | | `--action pr-status --pr N` | 查看 PR + CI 状态 | 5. 等 CI | diff --git a/agents/QE_AGENT.md b/agents/QE_AGENT.md index d6fc4ff..8fa2224 100644 --- a/agents/QE_AGENT.md +++ b/agents/QE_AGENT.md @@ -1,13 +1,13 @@ --- name: QE-Agent -description: QE Agent — 自动化验收测试开发与质量门禁。轮询 Gitea test-dev issue,开发验收测试,提交 PR,监控 CI,合并并关闭 issue。 +description: QE Agent — 自动化验收测试开发与质量门禁。轮询 Gitea test-code issue,开发验收测试,提交 PR,监控 CI,合并并关闭 issue。 --- # QE-Agent **你是 QE-Agent,始终以 QE-Agent 自称。你不是通用助手,你是 document_analyzer 项目的专属 AI 质量工程代理,通过 Gitea Issues 与 Dev-Agent 协同迭代。** -你的工作是:根据 Gitea 上的 `test-dev` issue 开发新的验收测试,确保测试通过 CI,并推进到 main branch。 +你的工作是:根据 Gitea 上的 `test-code` issue 开发新的验收测试,确保测试通过 CI,并推进到 main branch。 ## 启动行为 @@ -16,7 +16,11 @@ description: QE Agent — 自动化验收测试开发与质量门禁。轮询 Gi 1. 读取项目章程和全局状态:`docs/PROJECT_CHARTER.md` 和 `docs/GLOBAL_STATE.md` 2. 设好环境变量(见下方"环境要求") 3. 用 `/loop 10m` 开启 10 分钟间隔的自动轮询 -4. 轮询内容:`agent_poller.py --action list --labels test-dev` 和 `--labels acceptance-failure` +4. 轮询内容(多轮递进): + a. `--action list --labels test-code` — 先捡带 `test-code` 标签的 Issue + b. `--action list` 无过滤,筛选 title 带 `[test]` 前缀的无标签 Issue + c. 都无则分析无标签、无标识的 Issue,判断是否在 QE 域内 + d. 同时检查 `--labels acceptance-failure` 5. 有 issue → 走完整闭环处理(Step 2-8) 6. 无 issue → 简短报告 "main healthy",等待下次轮询 7. 同时保持对话开放,随时响应用户指令 @@ -41,19 +45,29 @@ GITEA_API_TOKEN 需要 `write:issue`、`write:repository`、`write:user` 权限 验证环境: ```bash -python scripts/agent_poller.py --action list --labels test-dev +python scripts/agent_poller.py --action list --labels test-code ``` ## 工作流程 ### Step 1: 轮询待处理 Issue +**第一轮:捡带标签的 Issue** ```bash -python scripts/agent_poller.py --action list --labels test-dev +python scripts/agent_poller.py --action list --labels test-code ``` -如果有输出(如 `#5 [test-dev] 添加海外策略IR覆盖率测试`),说明有待处理的测试开发任务。 -如果无输出,报告"当前没有待处理的 test-dev issue"。 +如果有输出(如 `#5 [test-code] 添加海外策略IR覆盖率测试`),说明有待处理的测试开发任务。 +如果无输出,进入第二轮。 + +**第二轮:捡无标签但 title 带前缀的 Issue** +```bash +python scripts/agent_poller.py --action list +``` +从输出中筛选 title 以 `[test]` 开头的无标签 Issue。 + +**第三轮:分析无标识 Issue** +如果以上两轮都无结果,分析所有无标签、无 title 标识的 Issue,判断是否属于 QE 域。 同时检查 `acceptance-failure` 标签的 issue: ```bash @@ -128,18 +142,18 @@ python -m pytest tests/acceptance/ -v --run-acceptance -k "not test_layer_c_qe_a 测试必须全部通过(至少 Layer A 和 Layer B),才能提交。 **Issue 关闭规则**: -- QE 测试通过 → 关闭 test-dev issue -- QE 测试失败 + 发现新问题 → 开 dev issue (agent-task 标签),**test-dev issue 保持 open**,评论 `阻塞: #` -- QE 测试失败 + dev issue 已存在 → test-dev issue **保持 open**,更新 dev issue -- Dev issue 修复 + e2e 重新通过 → 关闭 test-dev issue -- **绝不**在问题未修复时关闭 test-dev issue +- QE 测试通过 → 关闭 test-code issue +- QE 测试失败 + 发现新问题 → 开 dev issue (agent-task 标签),**test-code issue 保持 open**,评论 `阻塞: #` +- QE 测试失败 + dev issue 已存在 → test-code issue **保持 open**,更新 dev issue +- Dev issue 修复 + e2e 重新通过 → 关闭 test-code issue +- **绝不**在问题未修复时关闭 test-code issue **Issue 重开规则**: - Dev issue 被关闭但 QE 重验仍失败 → **重开 dev issue**,加 `## REOPEN 原因` 评论: 1. 已修复项(肯定进展) 2. 仍存在的问题(具体数据 + 阈值对比) 3. 结论:为什么修复不完整 -- 重开后同步更新关联 test-dev issue +- 重开后同步更新关联 test-code issue ### Step 4: 提交并推送 @@ -202,7 +216,7 @@ python scripts/agent_poller.py --action lifecycle --issue ### 完整闭环图 ``` -Gitea "test-dev" Issue +Gitea "test-code" Issue │ ▼ QE-Agent 领取 (step 1-2) @@ -233,6 +247,23 @@ QE-Agent 领取 (step 1-2) └── 分析新 issue ─────────┘ ``` +## Issue 创建规则 + +创建 Issue 时,必须指定 label 以明确 Issue 归属: + +- **测试代码 Issue** → `test-code` label(QE-Agent 域) + ```bash + python scripts/agent_poller.py --action create-issue \ + --title "[test] issue 标题" --labels test-code --body "..." + ``` +- **验收失败 Issue** → `acceptance-failure` label,同时加 `agent-task` 分配给 Dev-Agent + ```bash + python scripts/agent_poller.py --action create-issue \ + --title "acceptance failure: ..." --labels "acceptance-failure,agent-task" --body "..." + ``` +- **产品/功能 Issue** → `product-code` label(Dev-Agent 域),一般由 Dev-Agent 自行创建 +- 多个 label 用逗号分隔,如 `--labels "acceptance-failure,agent-task"` + ## 测试开发指南 ### 添加新的 Schema 检查 diff --git a/docs/QE_AGENT_WORKFLOW.html b/docs/QE_AGENT_WORKFLOW.html new file mode 100644 index 0000000..efe2824 --- /dev/null +++ b/docs/QE_AGENT_WORKFLOW.html @@ -0,0 +1,213 @@ + + + + + +QE-Agent Workflow + + + + +

QE-Agent Workflow

+ +

QE-Agent 是一个自动化质量工程代理,专注于 main branch 的发布质量。 +通过三层验收测试(Schema / Coverage / LLM Audit)验证 IR 管道的输出质量, +并与 Dev-Agent 通过 Gitea Issue 协同工作。

+ +
+ 启动方式
+ bash scripts/start_qe_agent.sh — 三种模式:单次 / 持续轮询 / 交互
+ claude --agent agents/QE_AGENT.md — 直接启动交互模式(默认 /loop 10m 轮询) +
+ +

1. 角色与边界

+ + + + + + + + + + +
QE-AgentDev-Agent
关注范围main branch 健康功能开发与 bug 修复
代码tests/acceptance/skills/ scripts/
测试验收测试 (三层)UT/IT
分支test/issue-Ndev/issue-N-*
Committest: ... - Closes #Nfix: ... - Closes #N
签名[qe-agent: qa-01][da-01]
Issue 标签test-codeagent-task ci-failure
+ +

2. 三层验收测试

+ +
+
Layer A
Schema
确定性验证
+
+
Layer B
Coverage
结构溯源覆盖率
+
+
Layer C
QE Audit
LLM 专家审计
+
+
Report
JSON 报告
+
+ + + + + + +
Layer方法阈值LLM
A — SchemaIR 结构验证 (rule_id / trigger / sources / actions)0 errors不需要
B — CoverageIR sources[] 对文档内容单元的引用率≥ 70%不需要
C — QE AuditLLM 逐章节评估 IR 覆盖充分性inadequate ≤ 30%deepseek-v4-flash
+ +
+ 最终判决: 三层全部 PASS → releasable ✓ | 任意一层 FAIL → blocked ✗ +
+ +

3. Issue 工作流

+ +

3.1 轮询

+
python scripts/agent_poller.py --action list --labels test-code
+python scripts/agent_poller.py --action list --labels acceptance-failure
+ +

3.2 test-code Issue 闭环

+
+
1. 领取
comment
+
+
2. 开发
tests/acceptance/
+
+
3. 本地验证
pytest
+
+
4. 提交
test/issue-N
+
+
5. PR + CI
+
+
6. merge
+
+
7. close
+
+ +

3.3 e2e 验证流程

+
    +
  1. 识别 dev-agent 修复完毕(关联 dev issue 已关闭)
  2. +
  3. git pull origin main
  4. +
  5. python scripts/run_pipeline.py --parsed <path> --test
  6. +
  7. 分析三层报告
  8. +
  9. 全部 PASS → 关闭 test-code issue
  10. +
  11. 仍有 FAIL → 重开 dev issue + 更新 test-code issue
  12. +
+ +

4. Issue 生命周期规则

+ +
+

关闭规则

+
    +
  • QE 测试通过 → 关闭 test-code issue
  • +
  • QE 测试失败 + 新问题 → 开 dev issue (agent-task),test-code 保持 open
  • +
  • QE 测试失败 + dev issue 已存在 → test-code 保持 open
  • +
  • 绝不在问题未修复时关闭 test-code issue
  • +
+
+ +
+

重开规则

+
    +
  • Dev issue 被关但 QE 重验仍失败 → 重开 dev issue
  • +
  • 必须加 ## REOPEN by [qe-agent: qa-01] 评论,包含:
      +
    1. 已修复项(肯定进展)
    2. +
    3. 仍存在的问题(具体数据 + 阈值对比)
    4. +
    5. 结论:为什么修复不完整
    6. +
  • +
  • 重开后同步更新关联 test-code issue
  • +
+
+ +

5. Agent 间通信协议

+ +
+

Issue 状态是唯一通信渠道。两个 agent 共用 pzhang_zywl Gitea 账号,通过签名区分:

+
    +
  • QE 评论末尾: [qe-agent: qa-01]
  • +
  • Dev 评论末尾: [da-01]
  • +
+

QE → Dev: 发现问题 → 开 dev issue (agent-task) / 重开已有 dev issue

+

Dev → QE: 修复完成 → 关闭 dev issue(自验证后)

+

QE 验收: 拉取 main → 重跑 e2e → 通过就关 test-code,不通过就重开 dev issue

+
+ +

6. 命令速查

+ + + + + + + + + + + + + +
操作命令
轮询 issueagent_poller.py --action list --labels test-code
查看 issueagent_poller.py --action get --issue <N>
评论agent_poller.py --action comment --issue <N> --body "..."
生命周期agent_poller.py --action lifecycle --issue <N>
创建 PRagent_poller.py --action create-pr --issue <N> --branch test/issue-<N>
查 PR CIagent_poller.py --action pr-status --pr <N>
合并 PRagent_poller.py --action merge-pr --pr <N>
跑管道python scripts/run_pipeline.py --parsed <path> --test
验收测试pytest tests/acceptance/ -v --run-acceptance
仅 Layer A+Bpytest tests/acceptance/ -v --run-acceptance -k "not test_layer_c"
+ +

7. 文件结构

+ +
+tests/acceptance/
+├── conftest.py              # Pytest 配置、fixtures、LLM client
+├── ir_schema.py             # IR schema 验证
+├── report.py                # 三层 JSON 报告
+└── test_main_health.py      # Layer A → B → C
+
+scripts/
+├── agent_poller.py          # Gitea API 工具
+├── run_pipeline.py          # 端到端管道运行器
+├── start_qe_agent.sh        # QE-Agent 启动脚本
+└── .env                     # Token 配置 (gitignored)
+
+agents/
+├── QE_AGENT.md              # QE-Agent 系统指令
+└── DEV_AGENT.md             # Dev-Agent 系统指令
+
+.gitea/workflows/
+├── ci.yml                   # CI (push/PR)
+└── acceptance.yml           # 手动触发验收
+
+ +

8. 本 Session 处理记录

+ + + + + + + + + + +
Issue内容结果
#10移除硬编码路径,适配 config.pyclosed
#12实现端到端验收测试流程closed
#14跑完整 e2e 测试closed
#15Dev: IR rules=[] (多次 reopen)closed
#18再跑 e2e 测试open
#21P0: 覆盖率不足 (多次 reopen)reopened
#22P1: trigger.operator 为空closed
+ +

QE-Agent [qe-agent: qa-01] — document_analyzer project

+ + + diff --git a/scripts/agent_poller.py b/scripts/agent_poller.py index 2fa479e..cf2cf05 100644 --- a/scripts/agent_poller.py +++ b/scripts/agent_poller.py @@ -2,9 +2,10 @@ Usage: python scripts/agent_poller.py --action list - python scripts/agent_poller.py --action list --labels test-dev + python scripts/agent_poller.py --action list --labels test-code python scripts/agent_poller.py --action get --issue 1 python scripts/agent_poller.py --action comment --issue 1 --body "Working on this" + python scripts/agent_poller.py --action create-issue --title "My issue" --labels test-code --body "..." python scripts/agent_poller.py --action create-pr --issue 1 --branch test/issue-1 python scripts/agent_poller.py --action pr-status --pr 4 python scripts/agent_poller.py --action merge-pr --pr 4 @@ -98,6 +99,27 @@ def close_issue(num, body=None): return i +def create_issue(title, body=None, labels=None): + """Create a new Gitea issue. + + Labels convention (per project rules): + - Product/feature issues → product-code + - Test code issues → test-code + """ + payload = {"title": title} + if body: + payload["body"] = body + AGENT_SIG + if labels: + payload["labels"] = [l.strip() for l in labels.split(",") if l.strip()] + i = _req("POST", "/issues", payload) + issue_labels = [l["name"] for l in i.get("labels", [])] + print(f"Issue #{i['number']} created: {i['title']}") + if issue_labels: + print(f"Labels: {', '.join(issue_labels)}") + print(f"URL: {i.get('html_url', i.get('url', ''))}") + return i + + # ── PR operations ──────────────────────────────────────────────────────────── def create_pr(issue_num, branch, body=None): @@ -212,12 +234,13 @@ def main(): parser = argparse.ArgumentParser(description="Dev agent Gitea helper") parser.add_argument("--action", required=True, choices=["list", "get", "comment", "close-issue", - "create-pr", "pr-status", "merge-pr", "lifecycle"]) + "create-issue", "create-pr", "pr-status", "merge-pr", "lifecycle"]) parser.add_argument("--issue", type=int) parser.add_argument("--pr", type=int) + parser.add_argument("--title", help="Issue title (for 'create-issue' action)") parser.add_argument("--branch") parser.add_argument("--body") - parser.add_argument("--labels", help="Comma-separated labels to filter issues (for 'list' action)") + parser.add_argument("--labels", help="Comma-separated labels (filter for 'list', assign for 'create-issue')") args = parser.parse_args() if not GITEA_TOKEN: @@ -243,6 +266,11 @@ def main(): print("--issue is required for 'close-issue' action", file=sys.stderr) sys.exit(1) close_issue(args.issue, args.body) + elif args.action == "create-issue": + if not args.title: + print("--title is required for 'create-issue' action", file=sys.stderr) + sys.exit(1) + create_issue(args.title, args.body, args.labels) elif args.action == "create-pr": if not args.issue or not args.branch: print("--issue and --branch are required for 'create-pr' action", file=sys.stderr) diff --git a/scripts/start_qe_agent.sh b/scripts/start_qe_agent.sh index b8abe44..78d70b2 100644 --- a/scripts/start_qe_agent.sh +++ b/scripts/start_qe_agent.sh @@ -18,9 +18,9 @@ launch_agent \ "agents/QE_AGENT.md" \ "QE-Agent" \ "执行一次 Issue 巡检(单次任务,不要用 /loop): -1. python scripts/agent_poller.py --action list --labels test-dev 检查 test-dev Issue +1. python scripts/agent_poller.py --action list --labels test-code 检查 test-code Issue 2. python scripts/agent_poller.py --action list --labels acceptance-failure 检查 acceptance-failure Issue -3. test-dev Issue:分析 → 开发验收测试到 tests/acceptance/ → pytest 本地验证 → commit('test:' 前缀, Closes #N) → push → create-pr → 等 CI → merge-pr -4. acceptance-failure Issue:分析失败原因 → 测试问题则修复测试 → 管道问题则开 test-dev issue 跟踪 +3. test-code Issue:分析 → 开发验收测试到 tests/acceptance/ → pytest 本地验证 → commit('test:' 前缀, Closes #N) → push → create-pr → 等 CI → merge-pr +4. acceptance-failure Issue:分析失败原因 → 测试问题则修复测试 → 管道问题则开 test-code issue 跟踪 5. 所有 Issue 处理完毕后报告汇总并退出。" \ - "现在开始工作。使用 /loop 10m 开启轮询:每 10 分钟检查 test-dev 和 acceptance-failure 标签 Issue,有则走完整闭环(分析→开发测试→pytest→push→PR→CI→merge),无则报告 main healthy。保持对话开放。" + "现在开始工作。使用 /loop 10m 开启轮询:每 10 分钟检查 test-code 和 acceptance-failure 标签 Issue,有则走完整闭环(分析→开发测试→pytest→push→PR→CI→merge),无则报告 main healthy。保持对话开放。"