首页
/ LobeHub 如何用 Claude Code `/dedupe` 命令自动化 GitHub Issue 去重:从五步 Agent 工作流到 3 天自动关闭的完整实现

LobeHub 如何用 Claude Code `/dedupe` 命令自动化 GitHub Issue 去重:从五步 Agent 工作流到 3 天自动关闭的完整实现

2026-09-07 22:04:59作者:翟萌耘Ralph

开源仓库的 Issue 数量增长后,同一个 Bug 或需求往往会被不同用户以不同措辞重复提交,维护者需要耗费大量精力去识别与合并重复项。LobeHub 仓库(项目根目录即仓库根目录)将这一繁琐工作交给 Claude Code 以**可复用的 Slash Command(斜杠命令)**形式完成:仓库中的 .claude/commands/dedupe.md 定义了一条名为 /dedupe 的命令,由 GitHub Actions 在 Issue 创建时自动触发,通过多 Agent 并行检索、过滤与回帖,找出最可能的重复 Issue,并在给出反馈 3 天后自动关闭。读完本文,你将掌握这条命令的文件结构、五步执行流程、输出格式规范,以及它在 LobeHub 仓库中与 Actions Workflow、确定性预检脚本和自动关闭脚本协同工作的完整闭环。

一、命令文件解剖:Frontmatter 即权限边界

.claude/commands/dedupe.md 是一条标准的 Claude Code Slash Command 定义。所谓 Slash Command,是 Claude Code 中可通过 /命令名 直接触发的一段高度结构化的 Prompt 模板。文件开头的 YAML Frontmatter 定义了该命令的元数据:

---
allowed-tools: Bash(gh issue view:*), Bash(gh search:*), Bash(gh issue list:*), Bash(gh api:*), Bash(gh issue comment:*)
description: Find duplicate GitHub issues
---
  • allowed-tools(允许的工具白名单):这是整条命令最关键的安全约束。它把 Agent 可执行的工具严格限定为 gh 这一 GitHub 官方 CLI 的五个子命令(issue viewsearchissue listapiissue comment),每条都带有 * 通配符放行参数。除此之外的任何工具——文件编辑、浏览器、其他 MCP 服务器——都无法被调用。后文会看到,这正是它敢被部署到面向不可信用户的公开 Issue 工作流中的底气。
  • description(命令描述)Find duplicate GitHub issues,用于在 Agent 语境中描述命令用途,方便被正确调度。

正文第一句即点明命令目标:"Find up to 3 likely duplicate issues for a given GitHub issue."(为给定的 GitHub Issue 找出最多 3 个疑似重复项)。最多 3 个 是一个刻意设置的收敛上限,避免评论过长或引入噪音。

二、核心执行流程:一个编排者加 N 个并行检索者

命令正文以强指令口吻("follow these steps precisely",请精确按步骤执行)定义了五步流水线。它要求"先建立 todo list",让 Agent 在执行时对每步有显式的任务追踪:

第 1 步:前置资格检查(Preflight)

先由 Agent 确认目标 Issue 是否真的值得去重,命中以下任一情况则直接终止、不做任何处理

  • Issue 已关闭(closed);
  • Issue 本就不需要去重,例如:
    • 宽泛的产品反馈(没有具体解决方案);
    • 正面反馈(positive feedback);
    • 新的 MCP Marketplace 上架请求——这类请求由独立的 MCP Submission Handler 工作流负责,重复检测会与其产生冲突;
  • 此前已经在上面回复过重复评论(避免同一命令被重复触发时二次加评)。

这一步骤把"是否值得花钱/花时间跑大模型检索"的决策前置,属于典型的成本与噪音控制设计。

第 2 步:单 Agent 摘要(Issue Summarization)

派一个 Agent 读取目标 Issue 的完整内容,并返回一份摘要。这份摘要是第 3 步并行搜索的唯一输入源,它把原始 Issue 的冗长正文浓缩成可供多路检索的"语义锚点"。

第 3 步:5 路并行检索(Parallel Search)

基于第 2 步的摘要,同时启动 5 个并行 Agent 去 GitHub 上搜索重复 Issue,要求使用多样化的关键词与搜索思路。5 路并行的意义在于:

  • 覆盖标题、正文、复现步骤、报错信息等不同角度的表述差异;
  • 同一个问题常常被不同用户用完全不同的术语描述,单一检索词必然漏检;
  • 各 Agent 独立搜索后汇聚结果,再由下一步统一做交叉过滤。

注意第 1、2 步产生的结果(摘要与候选)会在第 4 步被"喂给"另一个 Agent——文档原句为 "feed the results from #1 and #2 into another agent",即上一步的产出是下一步的输入,形成 Agent 之间的数据交接链。

第 4 步:过滤误报(False-Positive Filtering)

把第 2 步摘要与第 3 步搜索候选一起交给另一个 Agent,由它剔除"看起来相关、实际并非重复"的误报。过滤后若无剩余候选则终止,不发布任何评论。这一步是质量闸门:宁可漏判,也不要把不相关的 Issue 指认为重复,避免骚扰真正的 Issue 作者。

第 5 步:回帖(Comment)

最终在目标 Issue 下回复最多 3 个(或 0 个,若已无可疑项)重复 Issue 链接,并附带自动关闭的说明(格式详见下一节)。

三、评论格式:机器可读的契约

命令对回帖格式做了"严格按此格式"(follow the following format precisely)的规定,以"发现 3 个疑似重复"为例:

Found 3 possible duplicate issues:

1. <link to issue>
2. <link to issue>
3. <link to issue>

This issue will be automatically closed as a duplicate in 3 days.

- If your issue is a duplicate, please close it and 👍 the existing issue instead
- To prevent auto-closure, add a comment or 👎 this comment

> 🤖 Generated with Claude Code

这段看似简单的文案其实承担了三个契约角色:

  1. 对人类读者:清楚列出疑似重复项、给出明确的 3 天自动关闭预告;
  2. 对 Issue 作者:给出两条显式操作路径——"确认重复就自行关闭并 👍 既有 Issue""认为误判就追加评论或 👎 本条评论",把异议机制写进了提示文本;
  3. 对下游自动化脚本auto-close-duplicates.ts 正是通过匹配评论中的 Foundpossible duplicate 关键字来识别"去重评论",通过正则抽取 #123 或 GitHub Issue URL 中的编号来确定目标重复 Issue,再检查评论是否存在 Issue 作者的 👎(-1)反应来判定是否被否决。这条格式是人与机器共同的接口协议

四、仓库落地全景:从 Action 触发到命令执行

只有命令文件并不能形成自动化。在 LobeHub 仓库中,.claude/commands/dedupe.md 只是整条流水线的"大脑",围绕它还有三层配套:

4.1 触发层:.github/workflows/claude-dedupe-issues.yml

该工作流在 Issue opened 事件和 手动 workflow_dispatch(可指定 issue_number)时触发,Job 名 claude-dedupe-issues,运行于 ubuntu-latest,超时 10 分钟,声明 issues: write 权限。其核心步骤链为:

  1. actions/checkout@v6 检出仓库;
  2. 复用仓库自带的 .github/actions/setup-env 准备环境;
  3. 执行确定性预检(见 4.2);
  4. 仅当预检输出 should_dedupe == 'true' 时,把 .claude/prompts/security-rules.md 复制到 /tmp/claude-prompts/
  5. 调用 anthropics/claude-code-action@v1,通过 --append-system-prompt 注入安全规则,并以 prompt: '/dedupe ${{ github.repository }}/issues/${{ github.event.issue.number || inputs.issue_number }}' 触发命令。

工作流中 ${{ github.repository }}/issues/<编号> 形式的参数即 dedupe.md 第 1 步中"given GitHub issue"的来源。仓库对使用 Slash Command 而非直接 Prompt 的原因给出了显式注释:"Security: Using slash command which has built-in restrictions / The /dedupe command only performs read operations and label additions"——即 slash command 自带 Frontmatter 级的工具限制,天然比自由 Prompt 更安全。

4.2 守卫层:确定性预检脚本 should-run-dedupe.ts

在昂贵的 Claude 执行之前,先跑一段零 AI 成本、完全确定性的过滤逻辑.github/scripts/should-run-dedupe.ts(Bun 脚本)。其导出的 shouldDedupeIssue() 按顺序判定:

  • Issue 非 open 状态 → 跳过(reason: Issue is not open);
  • 命中一组 MCP 相关标签 → 跳过(reason: 由 MCP submission workflow 处理)。标签集来自 .github/scripts/shared/mcp-labels.ts,包含 mcp-submission 及一系列 legacy 标签;
  • 调用 .github/scripts/shared/mcp-submission-classifier.tsclassify(),对标题正文做内容级分类,识别出"即便没打标签也能被认出是 MCP 上架请求"的文本 → 跳过;
  • 否则 → shouldDedupe: true(reason: Issue is eligible for duplicate detection)。

注意它的判定逻辑与 dedupe.md 第 1 步高度呼应——文档里的"MCP marketplace listing/submission request"与"已关闭"等豁免条件,正是由这道脚本在模型介入前就确定性拦截掉的。脚本会把 should_dedupereason 写入 GITHUB_OUTPUT,供工作流通过 steps.dedupe-preflight.outputs.should_dedupe 读取,从而用 if 条件决定是否继续。

4.3 收尾层:3 天后自动关闭 auto-close-duplicates.ts

.github/scripts/auto-close-duplicates.ts 是"3 days"承诺的执行者,由独立的定时工作流 .github/workflows/issue-auto-close-duplicates.yml 每天凌晨 2 点(cron 0 2 * * *)触发。脚本逐页拉取开放 Issue,对每条查找来自 Bot 用户、正文包含 Foundpossible duplicate 的评论,仅当:

  • 去重评论已存在超过 3 天;
  • 该评论之后再无任何新评论(即没有作者或其他人追加留言抗议);
  • 评论上没有 Issue 作者本人的 👎(-1)反应

……全部满足时,才通过 PATCH 接口关闭该 Issue(设置 state: closedstate_reason: duplicate、追加 duplicate 标签),并回帖说明"已自动关闭为 #编号 的重复项,若判断有误请重新打开"。这与去重评论中"add a comment or 👎 this comment to prevent auto-closure"的人机交互设计一一对应——作者一次 👎 就能中止自动关闭,形成了"AI 提议、作者可否决、静默期后执行"的保守闭环。

五、安全设计剖析:为什么可以信任公开 Issue 上的执行

将 LLM Agent 暴露给"任何陌生人都能提交内容"的公开 Issue,安全设计是核心考量。从 dedupe.md 及其周边配置可以提炼出四层防线:

  1. Frontmatter 工具白名单(命令层)allowed-tools 仅放行 gh 的 5 个只读/低危子命令,禁止文件编辑、网页抓取与其他 MCP 工具。命令正文的 Notes 也明确要求各子 Agent:"Do not use other tools, beyond gh"。
  2. 系统提示注入(运行层):工作流在触发前把 security-rules.md--append-system-prompt 注入,防止命令内容被 Issue 正文中的 Prompt Injection 劫持。
  3. 确定性前置闸门(流程层)should-run-dedupe.ts 用纯规则过滤,把明显无需去重(关闭、MCP 上架请求等)的 Issue 挡在 AI 执行之前,减少模型暴露面与 API 开销。
  4. 只写评论、不做破坏性操作(结果层)/dedupe 的输出仅是"回帖 + 可选的标签",真正的 Issue 关闭由独立脚本在满足静默期与作者未否决条件后才执行。

六、测试保障:用单测锁住工作流行为

该机制并非一次性脚本,仓库在 tests/github-scripts 下对其做了单测覆盖,保证后续演进不破坏契约:

  • tests/github-scripts/shouldRunDedupe.test.ts 覆盖 shouldDedupeIssue() 的判定矩阵:已关闭 Issue 跳过、带 mcp-submission/mcp:remote 标签的跳过、正文是本地或远程 MCP 上架请求的跳过、提到 @lobehub/market-cli 的"变体上架请求"也能被分类器识别跳过、普通开放 Issue 正常放行。
  • tests/github-scripts/claudeDedupeWorkflow.test.ts 直接解析 YAML 工作流文件与 TS 源码断言架构约束:预检脚本必须只依赖 mcp-submission-classifier不得依赖 auto-handle-mcp-submission(保持预检与 MCP 处理执行器的解耦);且预检步骤 id: dedupe-preflightrun 必须包含 bun run .github/scripts/should-run-dedupe.ts,Claude 步骤的 if 条件必须引用 steps.dedupe-preflight.outputs.should_dedupe == 'true',从而锁定"先确定性预检、后 Claude 执行"的顺序。

七、使用与约束总结

/dedupe 命令在 LobeHub 中通常不被人手执行,而是由 claude-dedupe-issues.yml 在每次新 Issue 打开时自动以 /dedupe <仓库>/issues/<编号> 形式触发。需要了解的关键使用约束包括:

  • 搜索一律走 gh CLI(issue list/search/api),不使用网页抓取;
  • 交互工具面最小化:不启用其他 MCP 服务器、不做文件编辑;
  • 结果上限 3 个,宁缺毋滥,过滤后为空则不回复;
  • 执行顺序不可乱:先资格检查,再单 Agent 摘要,再 5 路并行搜索,再独立过滤,最后回帖;
  • 回帖格式是机器契约,任何改版都必须同步更新 auto-close-duplicates.ts 的匹配逻辑;
  • 该命令只负责"找出并公告重复项",关闭动作由定时脚本在 3 天静默期后完成,且作者可通过评论或 👎 否决。

如果你正在维护自己的开源仓库并苦于 Issue 重复率过高,.claude/commands/dedupe.md 与其配套的 Workflow、预检脚本、自动关闭脚本共同构成了一套可直接借鉴的参考范式:用最少权限的 Slash Command 封装模型行为,用确定性脚本把守 AI 入口,用标准化的评论格式衔接下游自动化,再用带否决机制的静默关闭兜底——AI 参与维护流程的每个环节都被设计成可解释、可拦截、可撤回的。

登录后查看全文
热门项目推荐
相关项目推荐

项目优选

收起
kernelkernel
deepin linux kernel
C
33
18
ops-transformerops-transformer
本项目是CANN提供的transformer类大模型算子库,实现网络在NPU上加速计算。
C++
1.13 K
2.75 K
pytorchpytorch
作为 Ascend for PyTorch 社区的核心组件,TorchNPU 是昇腾专为 PyTorch 打造的深度学习适配插件,使 PyTorch 框架能够直接调用昇腾 NPU,为开发者提供昇腾 AI 处理器的超强算力。
Python
857
1.35 K
docsdocs
暂无描述
Markdown
897
5.8 K
kernelkernel
openEuler内核是openEuler操作系统的核心,既是系统性能与稳定性的基石,也是连接处理器、设备与服务的桥梁。
C
529
593
ops-nnops-nn
本项目是CANN提供的神经网络类计算算子库,实现网络在NPU上加速计算。
C++
915
1.83 K
jiuwenswarmjiuwenswarm
JiuwenSwarm 是一款基于openJiuwen开发的智能AI Agent,它能够将大语言模型的强大能力,通过你日常使用的各类通讯应用,直接延伸至你的指尖。
Python
3.58 K
1.01 K
ops-mathops-math
本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。
C++
1.35 K
1.46 K
cann-learning-hubcann-learning-hub
CANN 学习中心仓,支持在线互动运行、边学边练,提供教程、示例与优化方案,一站式助力昇腾开发者快速上手。
Jupyter Notebook
1.01 K
515
AscendNPU-IRAscendNPU-IR
AscendNPU-IR是基于MLIR(Multi-Level Intermediate Representation)构建的,面向昇腾亲和算子编译时使用的中间表示,提供昇腾完备表达能力,通过编译优化提升昇腾AI处理器计算效率,支持通过生态框架使能昇腾AI处理器与深度调优
C++
547
388