GitHub 研究
找到与用户话题或问题相关的每一个相关仓库和可提取组件:$ARGUMENTS(Claude Code 会填充此项;在其他 Agent 中为用户请求)
字面关键词搜索在细分话题上常常失败:开发者通常根据他们所操作的物体(网站、API、组织、库)来命名仓库,而不是根据概念。应搜索任何实现都必须包含的工件,从多个方向(代码、仓库、提交、议题、其他托管平台、网络)进行,验证每一个结果,并将候选仓库解构为可复用的组件,以融入我们的目标解决方案。
rotless 家族
本技能是 rotless 的一部分,也可以独立使用。当研究是为了另一个技能寻找先有技术时,调用者会指定一个文件及其格式(prior-art.md,由 rotless-skill-modernizer 定义):请按该格式将报告写入该文件。调用者包括:rotless-skill-creator(步骤 0,构建前)、rotless-skill-modernizer(fix 用于替换工具,refresh 用于更新整个格局)和 rotless-skill-refiner(学习到“更好方式”后,在采纳前会对照现有内容进行检查)。
工具箱
辅助脚本位于本技能的 scripts/ 文件夹中。将 S 一次性设置为该文件夹的绝对路径,从本技能的基本目录开始(即包含此 SKILL.md 的文件夹;当技能加载时,Claude Code 会打印“此技能的基本目录:…”)。始终通过 $S 调用辅助脚本(当前工作目录是用户的项目目录);使用 -h 查看所有标志;使用 python3,Windows 上使用 python。非 GitHub 的端点信息位于 references/sources.md(同一文件夹)。优先使用 POSIX shell(bash;Windows 上为 Git Bash)而非 PowerShell(在对 -、!、jq 进行引号处理时更方便)。sarkari/UPSC 示例仅用于说明。
| 工具 | 搜索内容 | 最佳用途 |
|---|---|---|
grepapp.py(如果安装了 grep MCP,则等同于 searchGitHub 工具) | 文件内容,约 100 万流行仓库,正则表达式,无需认证 | 硬编码域名、导入行、配置键 |
gh api -X GET search/code -f q='…' | 文件内容,GitHub 的旧版索引(更多仓库,不支持正则) | 第二个代码来源;path:/filename: 签名 |
ghsweep.py | 仓库名称/描述/README/主题,支持多个查询,去重 | 广泛搜索;总计数、常见主题、[噪音?] 标签 |
gh search commits … | 提交消息 | 名称/README 信息量少的仓库 |
gh search issues … --include-prs | 议题/PR 文本 | 仓库及其实际痛点(需要特定短语;通用词汇会被机器人议题淹没) |
ghverify.py | GraphQL 批量查询,每次 25 个仓库 | 检查仓库是否存在、重命名、实际活跃度、健康度、证据、警告标志 |
gh repo read-dir / read-file、gh api …/contents | 单个仓库的文件,无需克隆 | 确认真实代码 |
srcsweep.py | 并行搜索 21 个非 GitHub 来源:npm、crates、Packagist、Hex、NuGet、Maven、RubyGems、Hackage、Docker Hub、ArtifactHub、AUR、Open VSX、GitLab、Codeberg、MCP 注册表、skills.sh、Hugging Face(模型/数据集/空间/论文,包含论文链接的代码仓库)、Hacker News | 在 GitHub 之外查找先有技术;最后会生成一个已搜索/未触及来源的清单;--repos 选项将 GitHub 仓库通过管道传递给 ghverify.py - |
references/sources.md | 端点说明以及无搜索 API 的来源(PyPI、Homebrew、pkg.go.dev、Product Hunt、Reddit) | 手动跟进 |
重要的 gh 搜索规则(已验证;忽略它们会静默返回 [] 或错误结果)
- 引号:
gh search <kind> "two words"= 精确短语。如果使用 AND 逻辑,直接输入无引号的单词;OR也一样无引号。 - 对于非平凡的查询,请使用原始 API(完整语法 +
total_count):gh api -X GET search/{repositories|code|commits|issues} -f q='<query>' -f per_page=100 --cache 1h - 仓库搜索中所有单词必须匹配,因此每个查询保持 2–3 个单词,并通过变化措辞来扩大覆盖,而不是在一个查询中堆砌术语。如果一次搜索返回少于 5 个仓库,请缩短查询。
- 排除: 使用
NOT word排除单词;使用-qualifier:value排除限定符。-word会返回 0 结果。在gh search中,将排除项放在--之后。 - 通过 API 进行代码搜索 = 旧版引擎: 不支持正则表达式;支持
OR/NOT、path:、filename:、extension:、language:。仅搜索默认分支;会跳过大文件。如需正则表达式,请使用 grep.app。 - 每个查询结果上限 1000 条。 可通过以下方式分割大的结果集:
created:A..B、pushed:>DATE、星级区间stars:0..24、stars:25..99、stars:100..499(也能发现低可见度的宝藏)、language:。 - 速率限制: 搜索 30 次/分钟;代码搜索 10 次/分钟(
gh skill search共享此限制);GraphQL 5000 点/小时。查询限制:gh api rate_limit --jq '.resources | {search: .search.remaining, code: .code_search.remaining, graphql: .graphql.remaining}'。对重复调用使用--cache 1h;当代码搜索配额耗尽时,切换搜索方向而非等待。 - 隐私: 经过身份验证的搜索会返回账户可见的私有仓库。切勿报告它们:在 jq 中添加
select(.repository.private == false)(代码)/select(.private == false)(仓库)进行过滤;ghsweep.py会自动过滤。切勿将用户的私有/内部仓库名称放入搜索查询。 gh repo read-file/read-dir/gh discussion/gh skill需要较新版本的 gh(已测试 2.103)。如果版本较旧,请使用步骤 3 中的gh api回退方案,或建议执行winget upgrade GitHub.cli/brew upgrade gh。
步骤 0 — 简要说明(一个简短的段落,除非确实存在歧义,否则不进行来回沟通)
编写:目标 · 目标解决方案分解(模块化子问题:例如 认证/会话、爬虫/解析器、规范化/模式、存储、API/接口 — 用于识别可以从何处利用哪些组件) · 必备项 · 加分项 · 反模式(例如 薄封装、已废弃、需要付费 API、仅限 GPU) · 约束条件(语言、离线…:这些是达标/不达标的检查,而非搜索词) · 截止日期 为一个绝对日期(“近期” → pushed:>2025-10-24) · 投入程度:快速筛选(低成本、可逆的选择:约 10 个查询,取前 5 个结果)或全面方法(默认用于先有技术/构建还是购买/融合)。
如果请求是“X 的替代品/类似 X/X 的克隆”,请先定位到 X 的仓库,并以此为基础进行扩展(使用其主题、README、依赖项)。
先检查本地资源(免费,10 秒): 已安装的内容可能就能回答请求:你的 Agent 加载的技能文件夹(项目和用户级别:.agents/skills/、.claude/skills/、~/.codex/skills/…)、其 MCP 服务器列表(例如 claude mcp list)、gh extension list。在搜索世界之前先报告本地命中。
步骤 1 — 为话题建立指纹
编写 15–30 个具体的搜索词:
- 接触点 — 任何实现都必须访问的域名、URL、API 端点、主机名、RSS 路径、应用 ID。
- 代码签名 — 导入行、SDK 类/函数名称、环境变量、配置键、CSS 选择器、特征性常量。
- 从多个视角的词汇 — 构建者、最终用户、学术界、基础设施,以及可能最先解决该问题的邻近学科的视角;区域性/非英语术语、缩写、拼写错误。有歧义的单词需要搭配一个同伴术语(
agent+llm,而非单独的agent)。 - 形态 — 机器人、爬虫、API、CLI、库、扩展、MCP 服务器、Agent 技能、数据集、模型、GitHub Action;以及它们的文件签名(
.github/workflowscron、manifest.json、SKILL.md、.claude-plugin/marketplace.json)。Agent 技能和插件通常位于更大的仓库内部(一个拥有 80k★ 的 monorepo 中的skills/x/SKILL.md),仓库搜索无法发现:请使用代码搜索filename:SKILL.md "<其描述中的短语>"查找(噪音较大:可能有成千上万个结果,因此请使用 2 个区分度高的短语并浏览 2–3 页)以及 skills.sh(srcsweep.py --sources skills;语义搜索,对技能的名称效果优于其用途)。技能召回是最薄弱的环节:如果一个锚点技能始终无法浮现,请直接搜索其名称并在覆盖度说明中提及。 - 锚点 — 你期望任何良好答案都应包含的 3–10 个知名项目/产品。用于步骤 2 作为召回检查。
- 理想 README 段落 — 两个描述完美仓库的句子,用其作者可能采用的方式编写;从中挖掘搜索词。
步骤 2 — 在所有向量上进行搜索
并行运行向量。记录每个查询找到了哪些仓库(found_by:查询越多表示相关度越强)。
A. 代码搜索(信号最强)。 多个狭窄查询,每个接触点/签名一个:
S="<此技能的基本目录>/scripts" # 例如 S="$HOME/.agents/skills/rotless-github-research/scripts"(在 Claude Code 中为 ~/.claude/skills/…)
python "$S/grepapp.py" "sarkariresult.com" --repos-only
python "$S/grepapp.py" "(sarkariresult|freejobalert)\.com" --regex --lang Python --lang JavaScript --repos-only
python "$S/grepapp.py" "upsc.gov.in" --path .github/workflows/ --repos-only # 计划任务机器人
gh api -X GET search/code -f q='sarkariresult OR freejobalert language:python' -f per_page=100 \
--jq '"total \(.total_count)", (.items[] | select(.repository.private == false) | "\(.repository.full_name)\t\(.path)")'
grep.app 每个查询返回约 10 个文件,宽泛的正则表达式会导致 504 错误:应锚定一个罕见的字面量,添加 --lang/--path。去除噪音:被爬取的 URL 数据集、广告拦截列表、术语仅出现一次的 monorepo。
B. 仓库搜索(广度 + 格局大小)。
python "$S/ghsweep.py" --pushed ">2024-01-01" --order hits "sarkari OR naukri NOT resume" "freejobalert" "topic:government-jobs"
python "$S/ghsweep.py" --sort stars "topic:sarkari-result" # 描述中不包含通用关键词的旗舰项目
python "$S/ghsweep.py" --sort updated "sarkari scraper" # 被最佳匹配淹没的新近作品
python "$S/ghsweep.py" --must "scrap|crawl|alert|job" --exclude "resume|linkedin" "sarkari OR naukri" # 相关性过滤;同音异义词(“prior art” 指向专利)会充斥结果
gh api -X GET search/topics -f q=sarkari --jq '.items[].name' # 发现话题段
ghsweep.py 会打印总计数(该领域的拥挤程度)、最常见的话题(→ 下一个查询;也可以尝试成对的话题,由 ≥2 个顶级结果共享:topic:a topic:b)以及 [噪音?] 标签(tutorial/template/demo/dotfiles/awesome:降低优先级,但不要自动移除)。对于先有技术,移除 --pushed 以忽略年龄。
C. 提交搜索: gh search commits sarkariresult --limit 50 --json repository,commit --jq '.[] | "\(.repository.fullName)\t\(.commit.message | split("\n")[0])"'
D. 议题/PR 搜索: gh search issues "freejobalert" --include-prs --limit 50 --json repository,title,url(仅限特定短语)。
E. 从最佳结果滚雪球(前 3–5 个):
- 追踪被包装的依赖: 如果一个结果“封装于”、“构建于”或“使用”了 X,也研究 X:它往往是真正的市场主导者。这是最常见的过早停止点。
- Awesome 列表:
python "$S/ghsweep.py" --sort stars "awesome <kw> in:name";选取 ≥200★ 的awesome-*列表,提取其仓库链接(gh repo read-file README.md --repo o/awesome-x | grep -oE 'github\.com/[A-Za-z0-9_.-]+/[A-Za-z0-9_.-]+' | sort -u)并通过管道传递给ghverify.py -。出现在列表中是温和的质量信号。 - 相似仓库: 使用顶级结果的话题 + 语言 →
topic:a topic:b language:x,偏好相似的星级区间。 - README 中的“替代方案 / 类似项目 / 灵感来源 / 鸣谢”部分;特征性代码字符串 → grep.app(查找副本和移植版本);作者的其他仓库(
gh repo list <owner> --limit 100);带有自身工作的 Fork(gh api "repos/o/r/forks?per_page=100" --jq '.[] | select(.pushed_at > .created_at) | .full_name');库的依赖者页面,可使用你的网络抓取工具或curl访问 (github.com/o/r/network/dependents)。
F. 非 GitHub 来源: 一个命令,多个措辞(每个 1–3 个单词;同时搜索注册表和术语):
python "$S/srcsweep.py" "repository discovery" --limit 4 # 21 个来源,约 10 秒,最后输出已搜索/未触及的清单
python "$S/srcsweep.py" "sarkari" --repos | python "$S/ghverify.py" - # 从结果链接到的 GitHub 仓库,经过验证
然后对没有搜索 API 的来源(PyPI site:pypi.org、Homebrew、pkg.go.dev、Product Hunt、Reddit、博客、awesome <topic>)使用网络搜索。对于先有技术/竞争研究,还应列出值得注意的商业产品。非 GitHub 结果(GitLab、Codeberg、仅注册表)无法通过 ghverify.py 验证:请手动检查并标记证据为“已记录/元数据”。
停止条件和召回。 当新查询主要返回已知仓库时停止,但是,三个查询返回同一个仓库只是局部最小值,而非覆盖率。检查步骤 1 中的锚点:任何未被你的搜索发现的锚点都意味着词汇缺口:找出它使用了哪些词,并搜索这些词。零结果表示“此路径看不到它”,而非“它不存在”:在得出结论前,重新措辞或换一条路径一次。
步骤 3 — 验证与评估
每个候选仓库都通过 ghverify.py 进行验证(虚构名称会显示为“未找到”;已重命名的会显示当前名称):
python "$S/ghverify.py" owner/repo https://github.com/o2/r2 ... # 或:... | python "$S/ghverify.py" -
阅读其列:上次实质性提交(忽略 bump/chore/deps/merge/typo/docs)而非 pushedAt;议题解决率;已合并 PR;贡献者;组织/用户;每年发布次数;证据(测试、CI、清单、security.md;NONE = 仅 README,需严格验证);标志 !velocity(>100★/天:病毒式传播或购买,需了解上下文)、!lowfork(≥1000★,forks/stars < 0.005)、new(<14 天)、stale Ny(2+ 年无实质性提交:标记,但绝不降级:一个废弃的工具仍然证明了该想法曾被实现)、noise?。
然后对你将要报告的每个仓库确认真实代码(README 可能双向撒谎)。将证据固定到一个提交:
sha=$(gh api repos/o/r/commits/HEAD --jq .sha)
gh repo read-dir src --repo o/r --ref $sha # JSON:--json name,type --jq '.entries[]'
gh repo read-file path/to/main.py --repo o/r --ref $sha # 回退方案:gh api "repos/o/r/contents/PATH?ref=$sha" -H "Accept: application/vnd.github.raw"
gh api "repos/o/r/git/trees/$sha?recursive=1" --jq '"\(.tree|length) files", (.tree[:80][] | .path)'
引用永久链接 https://github.com/o/r/blob/<sha>/<path>#L10-L40,而非分支链接。
- 适应性与可提取性: 强 / 部分 / 弱 / 偏离目标
……