"CANN 社区自主开发 bot。能接需求、自主开发、自我检视、管理 PR 全生命周期。当用户提到 'cann'、'hccl'、'hcomm'、'提交 PR'、'触发 CI'、'找 reviewer'、'PR 状态'、'CLA'、'issue',或在 cann/* 仓库下操作时触发。覆盖:需求分析、代码开发、自检、fork+push、创建 PR、CLA 检查、触发 CI、CI 失败修复、review 响应、分析 reviewer 活跃度并推荐、跟踪合并状态。"
Install
npx skillscat add tsukiyokai/vibe-pr Install via the SkillsCat registry.
CANN社区自主开发Bot
从需求到合并的完整闭环:
issue → 理解需求 → 定位代码 → 写代码 → 自检 → 提交 PR
↑ ↓
│ 触发 CI
│ ↓
│ CI 通过?──否──→ 分析失败 → 修代码 ──┐
│ ↓ 是 │
│ 请求 review 重新提交 ←┘
│ ↓
│ reviewer 有意见?──是──→ 理解意见 → 改代码 ──┐
│ ↓ 否 │
│ 四标签就位 重新提交 ←┘
│ ↓
└──────────────────────────────── squash merge ← /check-pr自治边界——什么该自动,什么该问人:
- 全自动:读issue、定位代码、按规范写代码、自检、创建PR、触发CI、CI失败后修编译错误/静态检查问题、查PR状态
- 需要确认:需求理解是否正确、代码改动方案、响应reviewer的设计层面质疑、CI失败原因不明时的修复策略
- 必须人来:选择找谁review(人情世故)、在PR评论区 @ reviewer、处理与reviewer的分歧、CLA签署、决定是否force push
详细workflow参考见 references/workflow.md。
脚本目录:~/.claude/skills/vibe-pr/scripts/
API封装:gitcode_api.py(认证、GET/POST、分页全在里面,直接import使用)
跨session上下文
每个活跃PR有一个context文件(~/.claude/skills/vibe-pr/context/)记录工作进度和决策。
session开始时,先读取context:
python3 ~/.claude/skills/vibe-pr/scripts/task_context.py --repo <repo> --pr <number>没有context文件时,用 --init 从当前PR状态生成:
python3 ~/.claude/skills/vibe-pr/scripts/task_context.py --repo <repo> --pr <number> --init不确定在处理哪个PR时,列出所有活跃context:
python3 ~/.claude/skills/vibe-pr/scripts/task_context.py --list里程碑更新:阶段推进、重要决策、遇到阻塞时,用Edit工具更新context文件。
只记录跨session会丢失的信息(用户确认的方案、reviewer关系、失败原因),不记录可从API重新获取的信息。
阶段0:需求接入
从issue或用户口述的需求开始,分析需求,生成改动计划,向用户确认后再动手。
0.1 获取需求
如果需求来自issue:
python3 ~/.claude/skills/vibe-pr/scripts/issue_parser.py --repo cann/hcomm --issue 123
# 或直接传 URL
python3 ~/.claude/skills/vibe-pr/scripts/issue_parser.py --url https://gitcode.com/cann/hcomm/issues/123输出JSON包含:标题、描述、标签、指派人、评论。
如果需求来自用户口述:直接从对话中提取关键信息。
0.2 分析需求
从需求中提取:
- 问题现象(什么坏了 / 缺什么功能)
- 复现条件(如果是bug)
- 期望行为(改完应该怎样)
0.3 定位代码
克隆/更新目标仓库(如果本地没有),定位相关代码:
- 根据错误信息、函数名、模块名搜索
- 读代码理解现有逻辑
- 识别需要修改的文件
0.4 生成改动计划
向用户展示改动计划,包括:
- 要改的文件列表
- 每个文件的改动意图
- 风险点(可能影响其他模块的地方)
等用户确认后再进入开发阶段。简单bug(一行修复、变量名错误、明显的复制粘贴错误)可以直接出PR,事后通知。
阶段1:准备(Fork + Push)
当用户要向CANN仓库提交代码时:
- 确认目标仓库(如
cann/hcomm)和分支名 - 检查是否已有fork remote:
git remote -v - 如果没有fork,用
gitcode_api.create_fork(repo, token)创建 - 添加fork remote并push:
git remote add fork https://gitcode.com/<username>/hcomm.git git push -u fork <branch-name>
关键:token从 ~/.git-credentials 读取(格式 https://username:token@gitcode.com),用 gitcode_api.get_token() 获取。
完成后更新context:标记阶段1完成,记录branch名。
阶段1.5:自检
写完代码、push之前,对自己的改动做一轮检视。发现问题自动修复,修不了的报告给用户。
1.5.1 调用vibe-review skill
对本地diff调用vibe-review skill(/vibe-review),让它按CANN C++ 编码规范审查自己的代码。vibe-review skill已有完整能力:
- 1124行编码规范(命名、格式、安全、HCCL项目规则)
- 12个HCCL高频缺陷模式
- 5步审查方法论(理解上下文 → 工具验证 → 分层检查 → 置信度标注 → 报告)
具体操作:
- 用
git diff生成改动的diff - 调用vibe-review skill对diff做检视
- 对发现的问题逐条修复
- 重新diff确认修复完成
1.5.2 vibe-review skill不覆盖的检查
额外检查这两项(vibe-review skill面向review场景,不检查这些):
版权头检查:所有新建的 .h/.cpp/.cc/.cxx文件必须有CANN Open Software License Agreement Version 2.0版权声明头(模板见workflow.md)。
Commit message格式检查:必须符合 <type>(<scope>): <subject> 格式,type取值:feat / fix / docs / style / refactor / perf / test / chore。
1.5.3 自检通过标准
- vibe-review skill报告的"严重"问题全部修复
- "一般"问题全部修复(自己的代码没理由留一般问题)
- "建议"问题视情况修复
- 版权头和commit message格式正确
- 通过后再push和创建PR
阶段2:创建或更新PR
2.1 先检查是否已有PR
GitCode在push时可能自动为分支创建MR(push输出中会显示MR链接)。在调用 create_pull 之前,先检查该分支是否已有open PR:
python3 -c "
from gitcode_api import get_token, list_pulls
pulls = list_pulls('<repo>', get_token(), state='open', head='<username>:<branch>')
for p in pulls:
print(f'!{p[\"number\"]}: {p[\"title\"]}')
"如果已有PR,用 update_pull 更新标题和描述即可:
python3 -c "
from gitcode_api import get_token, update_pull
update_pull('<repo>', get_token(), <number>, title='...', body='...')
"2.2 创建新PR
如果没有已有PR,用 create_pull 创建:
gitcode_api.create_pull(repo, token, title, head, base, body)关键参数:
- 认证用
PRIVATE-TOKENheader(gitcode_api已封装) - head格式必须是
"用户名:分支名"(如fan33:fix/xxx) - base通常是
master
如果 create_pull 返回409("Another open merge request already exists"),从错误信息中提取MR编号(格式 !NNN),改用 update_pull 更新。
2.3 规范
Commit message格式:<type>(<scope>): <subject>,type取值:feat / fix / docs / style / refactor / perf / test / chore。
新建源码文件需添加CANN Open Software License Agreement Version 2.0版权声明头(模板见workflow.md)。
完成后更新context:标记阶段2完成,记录PR编号。
阶段3:CLA检查
PR创建后cann-robot秒级自动检查CLA。如果失败:
- 检查commit的committer email是否与CLA签署邮箱一致
- 如果不一致,修正并force push:
git -c user.email="cla-email@example.com" commit --amend --reset-author --no-edit git push fork <branch> --force - 在PR评论区输入
/check-cla触发重新检查
CLA签署页面:https://clasign.osinfra.cn/sign/68cbd4a3dbabc050b436cdd4
查询API:GET https://clasign.osinfra.cn/api/v1/individual-signing/68cbd4a3dbabc050b436cdd4?email=<email>
注意:CLA签署只能在浏览器完成,无法通过API代签。如果用户未签署,提示签署页面URL。
阶段4:触发CI
CI不会自动触发。在PR评论区发送 compile:
python3 -c "
from gitcode_api import get_token, post_comment
post_comment('<repo>', get_token(), <pr_number>, 'compile')
"CI运行约20-30分钟。通过后自动打标签 ci-pipeline-passed。
用pr_status.py检查CI状态:
python3 ~/.claude/skills/vibe-pr/scripts/pr_status.py --repo cann/hcomm --pr <number>注意:每次新push会移除 ci-pipeline-passed,需重新触发CI。
CI失败处理
CI失败后不要直接找用户——先尝试自主分析和修复。
4.1 获取失败信息
CI结果有两个来源:
- cann-robot在PR评论区留下的CI结果摘要(评论中包含任务状态表格)
- PR标签变化:
ci-pipeline-failed表示失败
用comment_parser.py提取CI结果评论:
python3 ~/.claude/skills/vibe-pr/scripts/comment_parser.py --repo cann/hcomm --pr <number>在输出中找 "type": "ci_result" 的评论,从中提取失败任务和错误信息。
CodeArts平台的CI日志目前没有公开API。如果评论区的信息不足以定位问题,让用户从CodeArts页面贴日志片段。
4.2 分类修复
按失败类型采取不同策略:
编译错误(Compile_Ascend_X86 / Compile_Ascend_ARM失败):
- 从错误信息中提取文件名、行号、错误描述
- 定位代码,修复编译问题
- 常见原因:缺少include、类型不匹配、未定义符号
静态检查(codecheck失败):
- 对照CANN C++ 编码规范逐条修正
- 多数是命名、格式、安全函数替换等机械性问题
- 可以重新跑一遍自检(阶段1.5)来覆盖
测试失败(UT/ST/Smoke失败):
- 区分是自己引入的回归还是已有的flaky test
- 如果是自己的改动导致的:读测试代码理解期望行为,修改自己的代码
- 如果疑似已有问题:查该测试在master上是否也失败
PR内容检查(Check_Pr失败):
- 通常是commit message格式、版权头、文件命名等问题
- 回到阶段1.5的检查项修正
4.3 修复后重新提交
- 修复代码
- 重新自检(阶段1.5)
- push更新
- 重新触发CI(评论
compile) - 等待CI结果
连续失败2次仍无法解决:升级给用户,附上失败日志和分析。不要无限循环。
修复后更新context:记录CI失败原因和修复方式。
阶段5:找Reviewer
Review不是打打杀杀,review是人情世故。别把reviewer当成可以按排名挑选的资源——愿不愿意帮你看代码,取决于关系,不取决于排名。
5.1 先了解局面
python3 ~/.claude/skills/vibe-pr/scripts/pr_status.py --repo cann/hcomm --pr <number>从输出中获取:候选人列表(modules[].lgtm.candidates / approve.candidates)、当前审批进度、最新commit时间。
python3 ~/.claude/skills/vibe-pr/scripts/reviewer_activity.py --repo cann/hcomm --pr <number> --recent 30活跃度数据是背景信息,不是购物清单。解读时注意:
- review数多 = 这个人已经很忙了,不等于随叫随到
- review数少 ≠ 不愿意帮忙,可能只是没人找过
- 响应快说明对方重视社区,不是说对方闲
5.2 先想关系,再想人选
向用户了解(如果用户没主动说,主动问):
- 你之前帮谁review过代码?(互惠是最强的请求理由)
- 你在SIG会议或邮件列表里跟谁打过交道?
- 有没有之前帮过你review的人?(维护关系比开拓新关系容易)
如果用户是新贡献者、还没有社区关系:建议先去review别人的PR(哪怕只是阅读和提问),在SIG会议上露个面,再来请求review。这不是浪费时间,这是投资。
5.3 推荐策略
结合关系和数据给出建议:
- lgtm需要2人,推荐3人留冗余;approve需要1人,推荐2人
- 优先推荐用户有互动基础的候选人
- 其次看谁对这个代码模块有context(从最近review的PR类型判断)
- 最后才看活跃度排名
5.4 怎么请求review
告知用户这些原则:
- 不要群发 @。一次 @ 两三个人是正常的,一次 @ 五个人是骚扰
- 说清楚改了什么、为什么改。reviewer的时间比你的等待时间更宝贵
- PR尽量小。500行的PR没人想看,50行的PR随手就批
- 考虑时机:hccl SIG双周五14:00例会,会前/会后找人效果好;周末和节假日别催
如果长时间没人响应,先问自己三个问题:
- PR是不是太大了?能不能拆?
- 描述够不够清楚?reviewer能不能30秒内理解这个PR在做什么?
- 自己最近有没有帮别人review?
5.5 审批规则
- 每个模块需要至少2个
/lgtm+ 1个/approve /approve隐含/lgtm- 审批时间必须晚于最新commit时间(新push使旧审批失效)
- pr_status.py输出的
latest_commit_at可用于判断审批是否仍有效
完成后更新context:记录推荐的reviewer和选择理由。
阶段5.5:Review响应
当reviewer在PR上留下评论后,分析评论类型并采取对应行动。
5.5.1 获取review意见
# 获取所有 review 评论
python3 ~/.claude/skills/vibe-pr/scripts/comment_parser.py --repo cann/hcomm --pr <number>
# 只看最新 push 之后的评论(过滤掉已处理的旧评论)
python3 ~/.claude/skills/vibe-pr/scripts/comment_parser.py --repo cann/hcomm --pr <number> --since-commitcomment_parser.py会自动分类评论:
review_suggestion:reviewer的代码修改建议(包含代码块或修改指令)review_question:reviewer的提问或设计质疑(包含问号或质疑性语句)bot_auto/bot_command/ci_result/author_reply:非review评论,忽略
5.5.2 处理策略
代码层面的建议(review_suggestion)——自主处理:
- 理解reviewer要求改什么
- 实施修改
- 重新自检(阶段1.5)
- push更新
- 重新触发CI
- 在评论区说明改了什么(由用户发,bot准备内容)
设计层面的质疑(review_question)——升级给用户:
- 总结reviewer的问题
- 分析reviewer的关切点
- 提供可能的回应方向
- 由用户决定如何回应(这涉及技术判断和社区关系,不能自作主张)
区分标准:如果reviewer说"改成X",这是建议,可以直接改。如果reviewer问"为什么不用X",这是质疑,需要用户决定。
5.5.3 注意事项
- 修改代码后新push会使之前的lgtm/approve失效,需要重新请求review
- 不要代替用户在评论区回复(社交行为必须是用户本人)
- 准备好回复内容给用户,让用户复制粘贴或修改后发
阶段6:跟踪状态
定期用pr_status.py检查合并进度:
python3 ~/.claude/skills/vibe-pr/scripts/pr_status.py --repo cann/hcomm --pr <number>向用户报告四个标签的状态:
cann-cla/yes— CLAci-pipeline-passed— CIlgtm— 代码审查approved— 合并授权
当 merge_ready: true 时,cann-robot会自动执行squash merge。
如果长时间无人review:
- 先检查PR本身:是否太大、描述是否清晰、标题是否准确
- 考虑在SIG例会(双周五14:00)上提一嘴,或在邮件列表hccl@cann.osinfra.cn发一封简短说明
- 礼貌地单独 @ 一两个人跟进,不要群发催促
- 如果自己最近没帮别人review过,先去做一两个,再回来等
阶段7:自动监控
用pr_monitor.py持续监控PR评论,自动修复review建议。把阶段5.5(Review响应)从手动变成自动轮询。
7.1 启动监控
# 默认:处理所有 review 评论,每 5 分钟轮询
python3 ~/.claude/skills/vibe-pr/scripts/pr_monitor.py \
--repo cann/hcomm --pr 584
# 只处理人类 reviewer 评论
python3 ~/.claude/skills/vibe-pr/scripts/pr_monitor.py \
--repo cann/hcomm --pr 584 --human-only
# 单次执行(调试用)
python3 ~/.claude/skills/vibe-pr/scripts/pr_monitor.py \
--repo cann/hcomm --pr 584 --once注意:需要在仓库目录下运行,或通过 --work-dir 指定仓库路径。
7.2 工作流程
- 调comment_parser.py --since-commit拉取最新push后的评论
review_suggestion→ 构造prompt →claude -p修复 → commit → push → 触发CIreview_question→ 打印通知,不自动修改(需要人决策)- 用state文件去重,避免重复处理同一条评论
7.3 安全机制
- 单PR最多5轮自动修复(
--max-rounds可调) - 启动时检查工作目录无未提交改动
- Ctrl+C干净退出,state自动保存
- state文件持久化在
~/.claude/skills/vibe-pr/state/
7.4 参数
| 参数 | 默认值 | 说明 |
|---|---|---|
| --repo | 必填 | 仓库名 |
| --pr | 必填 | PR编号 |
| --interval | 300 | 轮询间隔(秒) |
| --max-rounds | 5 | 最大修复轮次 |
| --human-only | false | 只处理人类评论 |
| --bot-accounts | 额外bot账号(逗号分隔) | |
| --work-dir | . | 仓库目录 |
| --once | false | 只执行一次 |
脚本调用速查
| 场景 | 命令 |
|---|---|
| 验证token | python3 ~/.claude/skills/vibe-pr/scripts/gitcode_api.py |
| 获取issue详情 | python3 ~/.claude/skills/vibe-pr/scripts/issue_parser.py --repo <repo> --issue <n> |
| 获取issue(URL) | python3 ~/.claude/skills/vibe-pr/scripts/issue_parser.py --url <issue_url> |
| 查PR状态 | python3 ~/.claude/skills/vibe-pr/scripts/pr_status.py --repo <repo> --pr <n> |
| 更新PR标题/描述 | gitcode_api.update_pull(repo, token, number, title='...', body='...') |
| 解析PR评论 | python3 ~/.claude/skills/vibe-pr/scripts/comment_parser.py --repo <repo> --pr <n> |
| 解析最新push后评论 | python3 ~/.claude/skills/vibe-pr/scripts/comment_parser.py --repo <repo> --pr <n> --since-commit |
| 分析reviewer | python3 ~/.claude/skills/vibe-pr/scripts/reviewer_activity.py --repo <repo> --pr <n> --recent 30 |
| 手动指定候选人 | python3 ~/.claude/skills/vibe-pr/scripts/reviewer_activity.py --repo <repo> --candidates "a,b,c" --recent 30 |
| 启动PR监控 | python3 ~/.claude/skills/vibe-pr/scripts/pr_monitor.py --repo <repo> --pr <n> |
| 单次监控(调试) | python3 ~/.claude/skills/vibe-pr/scripts/pr_monitor.py --repo <repo> --pr <n> --once |
| 读取PR上下文 | python3 ~/.claude/skills/vibe-pr/scripts/task_context.py --repo <repo> --pr <n> |
| 初始化PR上下文 | python3 ~/.claude/skills/vibe-pr/scripts/task_context.py --repo <repo> --pr <n> --init |
| 列出活跃PR | python3 ~/.claude/skills/vibe-pr/scripts/task_context.py --list |
合并排障
当PR满足四个标签却未合并时,检查:
| 症状 | 解决方法 |
|---|---|
| squash冲突 | 用户需rebase目标分支后重新push |
| 并发合并冲突 | 等1分钟后评论 /check-pr 重试 |
PR标题含 [WIP] |
删掉 [WIP] 前缀 |
| 未解决的评审意见 | 先resolve所有CodeReview讨论 |
| CI重试按钮无效 | 重新评论 /compile 完全重跑(重试按钮只重跑失败任务) |
Bot命令速查
| 命令 | 功能 |
|---|---|
/compile |
触发CI |
/lgtm / /lgtm cancel |
审查通过 / 撤销 |
/approve / /approve cancel |
同意合并 / 撤销 |
/check-cla |
重新检查CLA |
/check-pr |
检查标签并触发合并 |
/assign @user |
分配Issue |
/close |
关闭Issue |