RTK 的 Issue 分诊工作流:基于 Claude Code Skill 与 gh CLI 的三阶段自动化 Issue 治理方案
本文以 RTK 仓库中 .claude 目录下的 issue-triage Skill 文档为核心,完整拆解其"审计 → 深度分析 → 受控执行"的三阶段 Issue 分诊工作流:从并行拉取 GitHub 元数据、六维度分析(分类、PR 交叉引用、Jaccard 查重、风险分级、陈旧度、行动建议),到带强制人工验证的评论/打标/关单动作。读完本文,你可以掌握如何为一套基于 gh CLI 的开源项目搭建可复用的 Issue 治理流程,并理解 RTK 项目中该 Skill 与 pr-triage、repo-recap、rtk-triage 等兄弟 Skill 的编排关系。
Skill 定位:它解决什么问题,何时触发
issue-triage 是 RTK 仓库随仓库分发的一个 Claude Code Skill(定义文件为 SKILL.md),其 front matter 声明了 allowed-tools: Bash / Read / Grep、effort: medium,以及 triage, issues, github, categorize, duplicates, risk 等标签。它与同目录下的 repo-recap Skill 职责互补,原文档给出了明确的使用对照:
| Skill | 用途 | 输出 |
|---|---|---|
/issue-triage |
分类、分析、评论 Issue | 行动表格 + 深度分析 + 已发布的评论 |
/repo-recap |
面向团队的仓库总览 | Markdown 摘要(PR + Issues + 发布) |
触发方式分两类:
- 手动触发:
/issue-triage、/issue-triage all、/issue-triage 42 57(指定 Issue 编号聚焦分析); - 主动触发:当未分诊的开放 Issue 超过 10 条,或检测到某条 Issue 超过 30 天无活动时。
参数约定上:传 all 表示对所有 Issue 做深度分析;传编号列表(如 "42 57")表示只分析这些 Issue;传 en/fr 控制语言;不传参数时默认仅执行审计(法语输出)。
语言策略
- 参数为
en或english时,表格与摘要用英文输出; - 参数为
fr、french或不传参数时,默认法语; - 关键约束:无论哪种语言模式,Phase 3 发布的 GitHub 评论永远使用英文——因为读者是国际化的 Issue 提交者,而非项目维护团队。
前置条件:先验证环境,再开始干活
工作流启动前必须通过两项检查,任一失败立即停止并向用户说明缺什么:
git rev-parse --is-inside-work-tree
gh auth status
前者确认当前处于 Git 工作树内(Skill 依赖 gh 从当前仓库推导 owner/repo),后者确认 gh CLI 已认证。这是整个 Skill 数据层的基础——后续所有 Issue/PR 元数据都来自 gh 命令而非直接调用 GitHub REST API。
Phase 1 — 审计(Audit):每次运行必做
1.1 数据收集:五条并行 gh 命令
审计阶段的核心是一次性拉齐所有决策所需的原始数据。原文档要求以下命令并行执行:
# 仓库身份
gh repo view --json nameWithOwner -q .nameWithOwner
# 开放 Issues(完整元数据)
gh issue list --state open --limit 100 \
--json number,title,author,createdAt,updatedAt,labels,assignees,body,comments
# 开放 PRs(用于交叉引用)
gh pr list --state open --limit 50 --json number,title,body
# 近期已关闭 Issues(用于查重)
gh issue list --state closed --limit 20 \
--json number,title,labels,closedAt
# 协作者列表(用于保护维护者的 Issue)
gh api "repos/{owner}/{repo}/collaborators" --jq '.[].login'
两个容易踩坑的细节被原文档明确点出:
-
协作者接口降级:
gh api .../collaborators可能因权限不足返回 403/404,此时降级为"最近合并 PR 的作者"近似协作者集合:gh pr list --state merged --limit 10 --json author --jq '.[].author.login' | sort -u若仍然无法确定,则通过
AskUserQuestion向用户提问,而不是猜测。 -
JSON 中
author是对象而非字符串(形如{login: "..."}),处理时必须取.author.login。这一点在仓库内 repo-recap 与 pr-triage 的文档中被反复强调,说明它是ghJSON 输出的常见解析陷阱。
1.2 六维度分析
拿到数据后,Skill 从六个正交维度对每条开放 Issue 做标注:
维度 1:分类。优先使用已有 label;无 label 时按标题/正文关键词推断:
- Bug:
crash、error、fail、broken、regression、wrong、unexpected - Feature:
add、implement、support、new、feat: - Enhancement:
improve、optimize、better、enhance、refactor - Question/Support:
how、why、help、unclear、docs、documentation - Duplicate Candidate:见维度 3
维度 2:PR 交叉引用。扫描每条开放 PR 的 body,用大小写不敏感的正则匹配 fixes #N、closes #N、resolves #N,构建 issue_number -> [PR numbers] 映射。若 Issue 关联的 PR 已经合并,则推荐关闭该 Issue(PR merged → close)。
维度 3:重复检测。这是六维度中算法含量最高的一个:
- 先对标题做归一化:转小写,去掉
bug:、feat:、[bug]、[feature]等前缀; - 对标题分词计算 Jaccard 相似度,两两 Issue 之间 score 超过 60% 即判定为"重复候选";
- 若两 Issue 的正文关键词重叠度超过 50%,作为强化信号;
- 查重范围包含最近 20 条已关闭 Issue(避免重复报告已被修复的问题);
- 注意这只是候选:误报留到 Phase 2 用深度分析确认或排除,审计阶段不得直接基于嫌疑采取动作。
维度 4:风险分级。按关键词把 Issue 分成三档:
- 红色(Critical):
CVE、vulnerability、injection、auth bypass、security、exploit、unsafe、credentials、leak、RCE、XSS - 黄色(Warning):
breaking change、migration、deprecation、remove API、breaking、incompatible - 绿色:其余全部
维度 5:陈旧度(Staleness)。以 updatedAt 距当前天数为依据:超过 30 天无活动标记为 Stale,超过 90 天标记为 Very Stale。
维度 6:行动建议。综合前五个维度,为每条 Issue 给出一个(或多个)行动标签:
Accept & Prioritize:定义清晰、可复现、在范围内;Label needed:缺少 label;Comment needed:信息不足、正文不完整;Linked to PR:有开放 PR 引用了它;Duplicate candidate:发现重复候选(须注明具体#N);Close candidate:陈旧且无近期活动,或明显超出范围——但作者若是协作者则永不自动给此建议;PR merged → close:关联 PR 已合并但 Issue 仍开放。
1.3 输出:五张表格 + 汇总
审计结果以固定版式的 Markdown 呈现(原文档输出模板,法语语境下字段名如下,英文模式对应翻译):
## 开放 Issues({count})
### 严重项(风险红色)
| # | 标题 | 作者 | 年龄 | Labels | 行动 |
### 关联 PR 的 Issues
| # | 标题 | 作者 | 关联 PR | PR 状态 | 行动 |
### 活跃 Issues
| # | 标题 | 作者 | 分类 | 年龄 | Labels | 行动 |
### 重复候选
| # | 标题 | 疑似重复自 | 相似度 | 行动 |
### 陈旧 Issues
| # | 标题 | 作者 | 最近活动 | 行动 |
### 汇总
- 总计:{N} 条开放 Issues
- 严重项:{N}(安全或 breaking 风险)
- 关联 PR:{N}
- 重复候选:{N}
- 陈旧(>30 天):{N} | 非常陈旧(>90 天):{N}
- 无 label:{N}
- Quick wins(可立即关闭或打标的):{列表}
两条输出细节约束:开放 Issue 数为 0 时只输出"Aucune issue ouverte."并终止;表格中"年龄"= 距 createdAt 的天数(格式 {N}j),超过 30 天的加粗显示,让维护者一眼定位积压热点。
1.4 自动复制到剪贴板
表格展示后,Skill 会把完整分诊表写入系统剪贴板,方便直接粘贴给团队。原文档给出了跨平台实现(依次探测 pbcopy → xclip → wl-copy,都不存在时降级为 cat 直接打印):
# 跨平台剪贴板
clip() {
if command -v pbcopy &>/dev/null; then pbcopy
elif command -v xclip &>/dev/null; then xclip -selection clipboard
elif command -v wl-copy &>/dev/null; then wl-copy
else cat
fi
}
clip <<'EOF'
{完整分诊表格}
EOF
执行后向用户确认"Tableau copié dans le presse-papier."(法语)/ "Triage table copied to clipboard."(英语)。
Phase 2 — 深度分析(Deep Analysis):opt-in 阶段
审计默认结束于 Phase 1,深度分析必须显式选择范围后才执行。
2.1 范围选择逻辑
- 参数为
"all"→ 分析全部开放 Issue; - 参数为编号列表(如
"42 57")→ 只分析指定 Issue; - 无参数 → 通过
AskUserQuestion弹出多选列表让用户挑。
原文档定义的询问选项为:
问题: "你想深度分析哪些 Issues?" 多选: true
- "全部({N} 条)" —— 用并行 agent 分析所有 Issue
- "仅严重项" —— 聚焦 {M} 条红/黄风险 Issue
- "重复候选" —— 确认或排除 {K} 条已检出重复
- "仅陈旧项" —— 对 {J} 条陈旧 Issue 做关/留决策
- "跳过" —— 到此结束,只做审计
选"跳过"则整个工作流终止于审计报告。
2.2 子代理执行:每条 Issue 一个并行 Agent
对每条被选中的 Issue,Skill 通过 Task tool 并行派生一个 general-purpose 子代理(model: sonnet),提示词中携带该 Issue 的全部上下文——元数据(创建/更新时间、labels)、正文、最近 5 条评论、关联 PR、重复候选对象、风险颜色——并要求返回一份七段式结构化报告:
- Scope Assessment:这条 Issue 到底在要求什么?定义是否清晰?
- Missing Information:推进处理还缺什么(复现步骤、版本、环境等)?
- Risk & Impact:有安全风险吗?会破坏兼容性吗?谁受影响?
- Effort Estimate:工作量分档 XS(<1h) / S(1–4h) / M(1–2d) / L(3–5d) / XL(>1 周)
- Priority:P0(关键,立即处理)/ P1(高,本迭代)/ P2(中,进 backlog)/ P3(低,待定)
- Recommended Action:六选一——Accept & Prioritize / Request More Info / Mark Duplicate (#N) / Close (Stale) / Close (Out of Scope) / Link to Existing PR
- Draft Comment:基于 templates/issue-comment.md 中的对应模板起草一条英文 GitHub 评论,要求具体、有用、建设性。
一个规模控制细节:Issue 评论超过 50 条时,只取最近 5 条喂给子代理(而非截断全文),控制上下文体积。所有子代理报告汇总后,向用户展示一份聚合摘要。
Phase 3 — 执行动作:强制验证后落地
3.1 三类动作及其 gh 命令
- 评论:
gh issue comment {num} --body-file - - 打标:
gh issue edit {num} --add-label "{label}"(若 label 已存在则跳过) - 关单:
gh issue close {num} --reason "not planned"(绝不允许未经验证就关单)
3.2 草稿生成的四条硬规则
对每条被深度分析过的 Issue,按 issue-comment.md 模板生成"评论 + 标签 + 关单(如适用)"动作草稿,规则如下:
- 评论语言必须是英文(国际化读者);
- 语气专业、建设性、就事论事;
- 永不重复打标已有该 label 的 Issue;
- 永不为协作者提名的 Issue 提议关单;
- 任何
gh issue comment之前,必须先完整展示草稿。
展示格式为:
---
### 草稿 — Issue #{num}:{标题}
**提议动作**:{评论 | Label: "bug" | 关单}
**评论内容**:
{完整评论}
---
随后通过 AskUserQuestion(多选)请求验证:选项为"全部({N} 个动作)"+ 每条 Issue 一个单独选项 + "不做任何动作"。用户未验证的动作一律不执行。
3.3 执行顺序与确认
对每个被验证的动作,严格按 评论 → 打标 → 关单 的顺序执行,保证即便中途失败,评论里也已经留下了处理痕迹:
# 评论
gh issue comment {num} --body-file - <<'COMMENT_EOF'
{评论内容}
COMMENT_EOF
# 打标(如适用)
gh issue edit {num} --add-label "{label}"
# 关单(如适用)
gh issue close {num} --reason "not planned"
每个动作完成后向用户回显确认(如"Commentaire posté sur issue #{num}: {title}");若用户选了"不做任何动作",则输出"Aucune action exécutée. Workflow terminé."收尾。
边界情况处理表
原文档对 10 类边界情况给出了明确的兜底行为,这也是该 Skill 可以直接投产而非停留在 demo 层面的关键:
| 情况 | 行为 |
|---|---|
| 0 条开放 Issue | 输出"Aucune issue ouverte."并终止 |
| Issue 无正文 | 仅按标题分类,建议 Comment needed |
| 评论超过 50 条 | 只取最近 5 条 |
| 重复检测误报 | 由 Phase 2 确认/排除——绝不在仅凭嫌疑时行动 |
| label 已存在 | 不重复打标,提示"label 已应用" |
| Issue 来自协作者 | 永不给自动 close candidate |
| GitHub API 限流 | 调低 --limit 并通知用户 |
| 已合并 PR 关联着开放 Issue | 建议关闭该 Issue |
| 超过 90 天无活动 | Very Stale——提议以友好语气关闭 |
| Phase 2 确认重复 | 发评论 + 以原 Issue 为准关闭本条 |
设计要点与实现细节
原文档末尾的 Notes 部分浓缩了几条值得借鉴的工程设计原则:
- 仓库身份永远动态推导:owner/repo 一律来自
gh repo view,绝不硬编码——这让同一份 Skill 可以搬到任意仓库使用; ghCLI 优先:除协作者列表(RESTrepos/{owner}/{repo}/collaborators)外,不直接curlGitHub API,统一走gh以复用其认证与分页;updatedAt可能为 null:此时回退用createdAt计算陈旧度;- 人机权责边界:任何发帖、关单都必须先经用户在对话中显式验证,草稿必须先于人眼后于 API 调用;
- Jaccard 精确定义:相似度 = |交集词数| / |并集词数|,且需剔除停用词(a, the, is, in, of, for, to, with, on, at, by)——这解释了为什么两个都含 "the" 的短标题不会虚高得分。
从源码结构看,这些约束与仓库内其他 triage 类 Skill 形成了一致的设计语言:pr-triage 对 PR 采用同样的"审计 → 深度审阅 → 受控评论"三段式;repo-recap 侧重面向分享的只读总览(含相同的 author.login 解析注意与剪贴板函数);而 rtk-triage 则是更上层的编排器,把 issue-triage 与 pr-triage 并行执行后做交叉分析(双重覆盖、安全空洞、无 PR 覆盖的 P0、内部冲突),结果存档到 claudedocs/RTK-YYYY-MM-DD.md。可以推断,issue-triage 在这套体系中既是可独立使用的原子 Skill,也是编排器可组合的组件。
评论模板层:与 RTK 项目特性绑定的深度
Phase 3 的草稿并非自由发挥,而是严格落在 issue-comment.md 定义的四套模板内:
- Template 1 — 确认 + 补充信息:Issue 有效但缺复现步骤/版本/环境;评论含 Category、Priority、Effort 三行元数据 + Assessment + Missing Information + Next Steps;
- Template 2 — 重复:指明与
#{original_number}重叠之处,并给"若你的场景有重要差异可重新打开并补充上下文"的出口; - Template 3 — 关闭(无活动):适用于 90 天以上无响应,说明关闭原因并保留重开路径;
- Template 4 — 关闭(超出范围):适用于与 RTK 设计目标不符的请求,必须给出具体理由和替代方案。
模板文件的 Formatting Rules 部分把行文规范量化了:
- 语气:专业、建设性、事实导向;挑战的是 Issue 范围,而非提交者本人;
- 长度:每条评论 100–250 词——够有用,又不浪费读者时间;
- 具体性:必须点名具体的命令、文件或行为,模糊评论是浪费所有人时间;
- 禁用最高级:不写 "great issue"、"excellent report" 之类的客套;
- Priority 与 Effort 标签体系:P0(安全漏洞/数据丢失/核心功能损坏)、P1(本迭代可行动的大 bug)、P2(进 backlog)、P3(低优);工作量 XS(<1h)/S(1–4h)/M(1–2d)/L(3–5d)/XL(>1 周)。
更有意思的是模板尾部列出的 RTK 项目专属上下文——这正是"通用分诊框架 + 项目知识注入"分离设计的体现:
- Bug 报告时,把
rtk --version作为第一个诊断步骤写入"缺失信息"; - 已知问题模块时直接引用源码路径(如
src/git.rs、src/vitest_cmd.rs这类 src/ 下的过滤器实现); - 涉及新增命令的特性请求,链接到 CLAUDE.md 中指向的过滤器开发清单(src/cmds/README.md 的 "Adding a new command filter" 章节);
- 拒绝异步/重依赖类请求时,注明 RTK 的性能约束。这一点有仓库事实支撑:README.md 明确写道 RTK 是"Single Rust binary, 100+ supported commands, <10ms overhead",即单 Rust 二进制、100+ 命令、<10ms 开销——模板中"零异步依赖以维持 <10ms 启动时间"的拒绝理由正是引用这一设计约束。
适用前提与限制
使用或移植该 Skill 前需明确几项前提:
- 运行环境:Skill 本身是 Claude Code 侧的提示词工程(依赖
AskUserQuestion、Task tool 等 Claude Code 能力),而非 RTK Rust 二进制的一部分;RTK 项目本体见 src/main.rs 与 docs/contributing/ARCHITECTURE.md。 - 工具依赖:
git与已认证的ghCLI 缺一不可,且需当前工作目录位于目标仓库内; - 权限假设:协作者列表接口需要相应权限,无权限时依赖"最近合并 PR 作者"的近似降级;
- 语言约定:审计输出可法语/英语,但对外的 GitHub 评论被硬编码为英文;
- 数据边界:
gh issue list --limit 100意味着单次审计最多覆盖前 100 条开放 Issue,超大规模 backlog 需要调参分批处理(限流时原文档的策略恰是调低--limit)。
总体而言,这份文档展示的不是某个功能,而是一套可迁移的方法论:用只读的并行 gh 查询构建事实层,用六维度规则引擎生成可解释的审计结论,用并行子代理完成逐条深度研判,再用"草稿先行 + 显式验证"守住所有写操作的边界。对任何希望让 AI 助手参与 Issue 治理的 Rust(或任意语言)开源项目,这套结构与 issue-comment.md 的模板分层都值得直接参考。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0622
Hy4-previewHy4 preview 是由腾讯混元团队研发的新一代混合专家(MoE)旗舰模型。模型总参数量 770B,每个 token 激活 49B,主干共包含78层,第一层采用标准 FFN,其余 77 层均为 MoE 结构,每层包含 256 个路由专家与 1 个共享专家,每个 token 激活 top-8 路由专家及共享专家。主干之外原生内置 1 层 MTP(总参数量 10B,激活 0.7B)以支持投机解码。Python00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
GLM-5.3-FlashGLM-5.3-Flash (320B-A18B),是GLM-5系列的首个原生多模态模型。320B总参数,能力超过GLM-5.2Jinja00
Spark-X2.5-4BSpark-X2.5-4B 旨在让强大的 AI 更实用、更高效、更易获得。在广泛日常任务中表现强劲,涵盖对话、写作、翻译、推理、编码、工具调用以及智能体工作流,并在同等规模的开源模型中取得领先成绩。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00