在这里插入图片描述

现在很多团队都在用云效做需求、任务、缺陷和迭代管理。对测试同学来说,提 Bug 本身并不复杂,但每天反复做起来,真正耗时间的往往不是“点提交”这个动作,而是下面这些细节:

  • 标题要写规范,最好能带上岗位、系统和异常点。
  • 复现步骤、实际结果、期望结果、环境信息不能漏。
  • 截图、日志、报告要上传成真实附件,不能把一大段 base64 塞进描述。
  • Bug 要关联到对应需求,否则后续验收和复盘容易断链。
  • 同标题同迭代不能重复提,避免开发同学收到多条重复缺陷。
  • 不同模块要自动指派给对应负责人,不能每次都靠人工记忆。

这边我根据平常的工作思路和习惯以及一些常规操作做了一版更贴近日常测试场景的封装:yunxiao-submit-bug

这篇文章就介绍一下这个 Skill 解决了什么问题、怎么使用,以及最近在专塑视界 App 测试中的实际效果。


一、为什么还要专门做一个云效提 Bug Skill?

云效本身提供了工作项管理能力,但真实落地时,测试提 Bug 并不是单一接口调用,而是一条小工作流:

在这里插入图片描述

如果直接让 AI 调接口,容易遇到几个问题:

  1. 字段 ID 不透明
    云效里的优先级、严重程度、版本、标签、迭代,很多时候不是页面上看到的中文,而是接口需要的真实 ID。

  2. 附件流程不只是“写进描述”
    图片应该作为云效真实附件上传,然后再把云效返回的图片 Markdown 嵌入描述。否则描述会变得很长,也不利于后续查看。

  3. 需求关联很容易漏
    测某个需求时,如果 Bug 没有关联需求,后续看需求验收、缺陷闭环、测试报告都会多一层人工核对。

  4. 重复缺陷很难靠人工稳定拦截
    同一个标题、同一个迭代,如果已经提过,再提一次就是无效噪音。

  5. 提交失败后容易“半成功”
    例如 Bug 创建成功了,但附件上传失败。这个时候如果重新提交,最怕重复建单。

所以我没有只做一个“创建 Bug 接口调用”,而是把它封装成一个更适合测试团队使用的 Skill。


二、这个 Skill 是什么?

yunxiao-submit-bug 只做一件事:稳定地往云效提 Bug。

它的核心脚本是:

云效 skills/yunxiao-submit-bug/scripts/submit_yunxiao_bug.py

目前主要覆盖 3 个动作:

动作 用途 解决的问题
inspect-fields 探查项目 Bug 类型和字段配置 不再猜字段 ID、选项 ID
submit --dry-run 预览最终请求体和关联项 正式提交前先检查标题、负责人、字段、附件、需求关联
submit 正式创建 Bug 并上传附件 创建缺陷、传截图、关联需求、返回链接

在这里插入图片描述

它支持的能力包括:

  • 字段探查:自动读取云效当前项目的 Bug 字段配置。
  • 本地配置映射:把中文模块、严重程度、负责人翻译成云效真实字段值。
  • dry-run 预检查:正式提交前先输出最终请求体、关联项、重复候选。
  • 标题规范化:支持自动组装 【岗位】-【系统】:标题正文
  • 自动指派:根据模块自动匹配负责人。
  • 附件上传:截图、日志、报告都按真实附件上传。
  • 图片嵌入:图片上传成功后,把云效返回的 Markdown 图片链接写回描述。
  • 需求关联:支持 requirement_id 或多个 related_workitems
  • 重复拦截:同标题同迭代默认阻止重复提单。
  • 失败恢复:Bug 已创建但附件失败时,可用 --resume-only 补传,不重复建单。

三、Skill 关系和文件清单

这套云效 Skill 当前核心目录如下:

云效 skills/yunxiao-submit-bug/
├── SKILL.md
├── 团队使用说明与上手手册.md
├── 项目快速开始.md
├── scripts/
│   └── submit_yunxiao_bug.py
└── templates/
    ├── project_config.template.json
    ├── project_config.zssj.example.json
    ├── bug_payload.template.json
    └── zssj.field_snapshot.sample.json

其中:

  • SKILL.md:给 AI 看的技能入口说明。
  • 团队使用说明与上手手册.md:给团队成员和配置维护人看的完整手册。
  • 专塑视界项目快速开始.md:结合项目的快速接入说明。
  • submit_yunxiao_bug.py:真正执行字段探查、dry-run、提交、附件上传、恢复补跑的脚本。
  • templates/:项目配置、Bug payload、字段快照样例。

在这里插入图片描述


四、使用前准备:不要把 Token 直接发给 AI

和其他研发工具一样,云效 Token 不建议直接粘贴到对话框里。更推荐通过环境变量或本机配置读取。

当前脚本读取 Token 的优先级是:

  1. 命令行参数 --token
  2. 环境变量 YUNXIAO_ACCESS_TOKEN
  3. ~/.claude.json 中的 yunxiao MCP 配置

推荐配置方式:

export YUNXIAO_ACCESS_TOKEN='你的云效token'
export YUNXIAO_ORGANIZATION_ID='你的组织ID'
export YUNXIAO_PROJECT_ID='你的项目ID'
export YUNXIAO_API_BASE_URL='https://openapi-rdc.aliyuncs.com'

这样做有两个好处:

  • 安全:隐私信息不直接进入 AI 对话。
  • 稳定:同一台机器配置一次,后续只需要关注 Bug 内容本身。

五、第一次接入:先探查字段,再写配置

云效不同项目的 Bug 字段可能不一样。第一次接入项目时,不建议凭经验硬填字段 ID,而是先跑字段探查。

mkdir -p ./.yunxiao

python3 '云效 skills/yunxiao-submit-bug/scripts/submit_yunxiao_bug.py' \
  --organization-id '组织ID' \
  --project-id '项目ID' \
  inspect-fields \
  --output ./.yunxiao/field_snapshot.json

这个输出主要用来确认:

  • 当前 Bug 工作项类型 ID
  • priorityseriousLevel 等必填字段
  • 模块、标签、版本、迭代的真实字段或真实选项 ID

然后复制配置模板:

cp '云效 skills/yunxiao-submit-bug/templates/project_config.template.json' \
  ./.yunxiao/project_config.json

配置里重点维护这些内容:

{
  "organization_id": "组织ID",
  "project_id": "项目ID",
  "workitem_type_id": "Bug工作项类型ID",
  "user_map": {
    "张三": "云效userId"
  },
  "module_assignee_map": {
    "报价": "报价模块负责人userId",
    "会员": "会员模块负责人userId"
  },
  "custom_fields": {
    "priority": {
      "field_id": "priority",
      "value_map": {
        "P1": "真实选项ID"
      }
    },
    "severity": {
      "field_id": "seriousLevel",
      "value_map": {
        "严重": "真实选项ID"
      }
    }
  }
}

在这里插入图片描述


六、日常提 Bug:payload 写清楚,剩下交给 Skill

日常提单时,测试同学不需要每次关注云效字段 ID。只需要把本次问题写成一个可读的 payload。

示例:

{
  "engineer_role": "安卓",
  "system_name": "报价系统",
  "subject": "报价详情页点击行情来源后闪退",
  "summary": "Android 端从报价详情进入行情来源弹窗时闪退",
  "steps": "1. 打开报价详情页\n2. 点击行情来源\n3. 观察页面表现",
  "actual_result": "应用直接退出到桌面",
  "expected_result": "正常弹出行情来源弹窗",
  "environment": "Android 14;华为 OCE-AL50;v4.24.1;测试环境",
  "module": "报价",
  "priority": "P1",
  "severity": "严重",
  "labels": ["Android"],
  "versions": ["v4.24.1"],
  "sprint": "v4.24.1",
  "requirement_id": "关联的需求工作项ID",
  "attachments": [
    "/absolute/path/to/screenshot.png",
    "/absolute/path/to/test-report.md"
  ]
}

如果传了 engineer_rolesystem_name,最终标题会自动变成:

【安卓】-【报价系统】:报价详情页点击行情来源后闪退

这比每次靠人工手动拼标题稳定很多。


七、提交前必须先 dry-run

正式提单前,我建议团队统一要求先跑 dry-run。

python3 '云效 skills/yunxiao-submit-bug/scripts/submit_yunxiao_bug.py' submit \
  --payload-file /tmp/yunxiao_bug_payload.json \
  --config-file ./.yunxiao/project_config.json \
  --dry-run

dry-run 会输出:

  • resolved_payload:AI 和配置解析后的最终业务信息。
  • request_body:实际要提交给云效的请求体。
  • request_relations:即将创建的需求或工作项关联。
  • duplicate_candidates:疑似重复标题候选。
  • idempotency_key:本次提交的幂等标识。

在这里插入图片描述

这个步骤非常关键。它把“提交后才发现字段错了”提前变成“提交前就能看出来”。


八、正式提交:创建 Bug、上传附件、关联需求一次完成

确认 dry-run 没问题后,再正式提交:

python3 '云效 skills/yunxiao-submit-bug/scripts/submit_yunxiao_bug.py' submit \
  --payload-file /tmp/yunxiao_bug_payload.json \
  --config-file ./.yunxiao/project_config.json

成功后会返回:

{
  "workitem_identifier": "ZSSJYF-2529",
  "workitem_url": "https://devops.aliyun.com/...",
  "attachments": [],
  "relations": [],
  "recovered": false,
  "duplicate_candidates": []
}

实际使用中,图片会先作为云效真实附件上传,然后再通过云效返回的 embedMarkdown 嵌入描述。

在这里插入图片描述


九、失败恢复:最怕半成功,这里专门做了 resume-only

真实接口调用里,最麻烦的不是“完全失败”,而是“半成功”:

  • Bug 已经创建成功。
  • 附件上传失败。
  • 或者关联需求失败。

如果这个时候重新跑普通提交,很可能重复创建一条 Bug。

所以这个 Skill 会把提交状态记录到:

./.yunxiao/submit_state.json

后续可以用恢复模式:

python3 '云效 skills/yunxiao-submit-bug/scripts/submit_yunxiao_bug.py' submit \
  --payload-file /tmp/yunxiao_bug_payload.json \
  --config-file ./.yunxiao/project_config.json \
  --resume-only

resume-only 只会复用已有 workitem 继续补附件、补关联,不会重复建单。

最近一次实际使用里,我也验证到了“关联已存在时跳过”的效果:恢复模式返回 skipped_already_related,说明它识别到了已有需求关联,不会重复创建关联记录。

在这里插入图片描述


十、最近我实际用在哪些场景?

这套 Skill 不是只停留在 Demo。我最近在专塑视界 App 的搜索排序优化验证中,已经连续用它处理过多类问题。

场景包括:

  1. 搜索排序规则验证
    例如供求搜索中同分兜底排序口径不清晰,需要把测试报告、样本数据和复现结论挂到云效工作项里,方便产品和算法一起确认。

  2. 行情筛选顺序异常
    例如 App 搜索后再筛选,筛选后的列表不是原搜索结果的有序子序列,需要附上筛选前后顺序对比和环境信息。

  3. 回归结果闭环
    某些问题修复后,需要把回归记录、关闭结果、重新打开结果同步到云效,避免测试证据散落在本地。

  4. 需求关联补齐
    验证某个需求时,Bug 自动关联到需求工作项,后续看需求验收时能直接看到相关缺陷。

在这里插入图片描述

实际效果可以概括成一句话:

测试同学只负责把“问题事实”说清楚,Skill 负责把“云效提单动作”做稳定。

在最近这些场景里,它已经验证通过的行为包括:

  • 能正常创建云效 Bug。
  • 能上传真实附件。
  • 图片能以云效返回的 Markdown 形式嵌入描述。
  • 能把 Bug 关联到需求工作项。
  • 已存在关联会自动跳过,不会重复报错。
  • 附件或关联补跑时不会重复创建 Bug。

十一、团队落地建议

如果团队里要推广这套 Skill,我建议固定 6 条规则:

  1. 提交前必须先跑 submit --dry-run
  2. 标题统一使用 【岗位】-【系统】:页面/功能 + 操作 + 异常结果
  3. 每条 Bug 至少附 1 张截图,复杂问题附测试报告或日志。
  4. 测需求时必须填 requirement_id,让 Bug 和需求形成闭环。
  5. 同标题同迭代默认不重复提交,确实需要重复提时再显式允许。
  6. project_config.json 由配置维护人统一维护,普通使用人只写 payload。

这样团队不会变成“每个人都有一套字段映射”,也不会因为接口字段变化导致大家各自踩坑。


十二、常见问题

1. 为什么不让 AI 直接在对话里收 Token?

不建议。Token、账号、密码这类敏感信息应该放在环境变量或本机配置里,让脚本读取,不要直接发进对话框。

2. dry-run 里负责人不对怎么办?

优先检查三处:

  • payload 是否显式写了 assignee
  • module_assignee_map 是否命中当前 module
  • user_map 是否把中文名映射成了真实云效 userId

3. 图片为什么不能直接塞 base64?

base64 会让描述变得非常长,也不利于云效页面查看。更好的方式是:先上传为真实附件,再把云效返回的图片 Markdown 嵌入描述。

4. 需求关联没有挂上怎么办?

先看 dry-run 里的 request_relations。如果这里已经为空,说明 payload 或配置没有正确传 requirement_id / related_workitems。如果这里正确但正式提交失败,再看当前项目是否允许该类型工作项建立 ASSOCIATED 关联。

5. resume-only 会不会重复创建 Bug?

不会。它会读取 .yunxiao/submit_state.json 里的已有 workitem 信息,只补附件和关联。


十三、最后

我做这个云效提 Bug Skill 的初衷,不是为了炫技,而是把测试工作里那些高频、重复、容易漏的动作沉淀下来。

以前提一个质量比较完整的 Bug,需要来回检查标题、字段、负责人、附件、需求关联、重复缺陷。现在更推荐的方式是:

准备事实材料 -> 写 payload -> dry-run 检查 -> 确认后 submit -> 云效自动成单

当这个流程稳定后,测试同学的注意力就能更多放在问题判断、复现路径、影响范围和验收结论上,而不是反复在云效页面里复制粘贴,并且结合一些app或者接口自动化效果会更加突出

让 AI 不只是“帮忙写点文字”,而是真的参与到日常测试交付链路里。

在这里插入图片描述

Logo

小龙虾开发者社区是 CSDN 旗下专注 OpenClaw 生态的官方阵地,聚焦技能开发、插件实践与部署教程,为开发者提供可直接落地的方案、工具与交流平台,助力高效构建与落地 AI 应用

更多推荐