8 个仓库全部真实存在,但两个会误判 —— 附 8 项可复用检查清单
有人转来一份短视频榜单,8 个「GitHub 热门 Agent 项目」,带名次。
我最初的反应是怀疑它们是编的 —— 这类榜单的常见失败模式就是模型把仓库名拼得像真的,实际不存在。
于是逐个打 GitHub 官方 API。结果是:8 个全是真的。
怀疑落空了,但核实没白做。下面是这轮核实里真正学到的东西。
榜单第 8 名 android/skills,9,620 星、Apache-2.0、Kotlin、最后推送就在两天前。数据完全正常。
但克隆下来读 README 原文,第一段就写明:
Android skills are a dedicated repository of AI-optimized, modular instructions …
that follow the best practices and guidance on Android development.
它跟「给 agent 用的通用技能集合」是两回事,是 Android 平台开发专用的。
安装方式也不是 git clone,而要 android skills add <name> --project=.(需要 Android CLI)。
如果只看榜单标题「android/skills」+ 9,620 星,很容易以为它是一份通用的 skills 合集 —— 名字骗人,不是数据骗人。
做法:星数、许可、活跃度只能证明「项目真实且有人用」,证明不了它跟你的需求有关。相关性只有一个验证方式:读它的 README 第一段和安装方式。
榜单写 Comfy-Org/ComfyUI。我印象里 ComfyUI 是 comfyanonymous/ComfyUI。
两个都查了,星数完全相同(142,696) → 组织迁移/重定向,指向同一仓库。
这类情况在大项目上很常见(组织化、成立公司、改 org 名)。如果不查,很容易在归档里记录成两个不同的项目。
有一个项目的 tags 里明确挂着 ghostty。ghostty 是一个 Zig 写的终端模拟器。
看着像是「它内嵌了 ghostty」。实际查下去:那个项目是 Electron 客户端,终端用的是 xterm.js,
它和 ghostty 的关系只有一层 —— 启动时能导入 ghostty 的配色/字体/光标配置。
「内嵌终端内核」和「能导入主题」是两件完全不同的事,而 tag 把它们的区别抹掉了。
同样地,README 顶部的口号往往描述愿景而不是能力。
判断实做的唯一办法是看目录结构、依赖文件、以及关键模块的源码文件名。
做法:把 tag 和 README 口号当作「线索」,不当作「事实」。事实要落到代码结构上。
这份榜单里 8 个项目,有 5 个超过 4.5 万星,其中一个 38 万星。
38 万星是什么量级?那是 Linux、React 这个级别。而这个项目创建于半年前。
这不必然是假的(爆发式增长确实存在),但半年 38 万星值得单独看一眼 star 历史,
而不是直接把它当成熟度指标写进评估报告。
这次我派了 5 个并行子代理去查不同主题。结果 4 个在 600 秒超时。
一开始以为是它们笨。查下来是三层原因叠加:
| 原因 | 表现 |
|---|---|
| 未认证 API 配额只有 60 次/小时 | 5 个子代理共用同一个出口 IP,互相抢配额,很快 remaining: 0 |
| 某个域名解析到 IPv6 且不可达 | 请求全部挂起,不报错,一直等到超时 |
| 有命令没设超时 | 一个 curl 挂 180 秒,把整批拖死 |
第一条最反直觉:并行度越高,越容易集体撞配额。开 5 个不会变成 5 倍速度,
反而会变成「5 个一起饿死」。
做法:并行抓 API 时,要么控制并发数,要么根本不用 API —— 见下条。
API 打满 403 的那一刻,我以为这轮调研废了。后来发现两条不受配额限制的路:
① 改用 git 协议做稀疏克隆
git init repo && cd repo
git remote add origin https://github.com/OWNER/NAME.git
git fetch --depth 1 --filter=blob:none origin main
git sparse-checkout init --cone
git checkout main
--filter=blob:none 只拿目录树、按需取文件,一个 40 MB 的仓库几秒就下来,
完全不消耗 API 配额。这条对本机验证有效。
② 抓单个文件改用 contents 接口
api.github.com/repos/OWNER/NAME/contents/README.md 返回 base64,比 raw 域名可靠 ——
前提是配额还没满。
这条是这次最实用的一课。
4 个子代理被判定「超时失败」,看起来产出为零。但我翻了它们的工作记录,发现:
它们已经把仓库 clone 到本地了,只是卡在最后整理阶段。
于是我不再碰网络,直接从本地克隆里离线提取了 29 个仓库的事实表 ——
许可证读 LICENSE 文件、描述读 README 首个有效段落、时间读 git log -1。
一个 API 调用都没再花,把失败的调研抢救回来大半。
做法:子代理失败时先看它的工作痕迹,不要直接判死。很多"失败"是最后一公里挂了,
中间产物还在。
核实任何一份 AI 生成的仓库清单,按这个顺序走:
| # | 检查 | 怎么做 | 能排除什么 |
|---|---|---|---|
| 1 | 仓库是否真实存在 | api.github.com/repos/OWNER/NAME,非 200 即假 |
编造的仓库名 |
| 2 | 是否同一个仓库 | 比 star 数是否完全相同 | org 迁移导致的重复计数 |
| 3 | 它到底是干什么的 | 读 README 第一段 + 安装方式,不看标题 | 名字骗人、平台专用冒充通用 |
| 4 | tag 是否名副其实 | 查 tag 提到的关键依赖是否真在依赖清单里 | 蹭关键词 |
| 5 | 成熟度 | 创建时间 vs star 数 vs 最后推送 | 把新项目当老牌项目 |
| 6 | 是否已停更/日落 | README 顶部有无 sunsetting 声明;pushed_at 距今多久 |
把死项目写进方案 |
| 7 | 许可证 | 读 LICENSE 原文,不看转述 |
BSD-2/3、AGPL 这类会咬人的差别 |
| 8 | 宣传 vs 实做 | 看目录结构和关键模块文件名 | 口号式 README |
核实一份 AI 榜单,最省事的做法是查它是否真实存在;最有价值的做法是查它是否名副其实。
这次 8 个全都真实存在,但其中至少两个(一个平台专用、一个 tag 蹭词)如果只看星数就会误判。
而误判的代价不是"多读了一篇 README",是把不相干的工具写进技术方案,然后在实施阶段才发现。
本文所有数字均为本人实测(GitHub 官方 API + 本地克隆离线核对)。
涉及具体项目内部部署的信息已剔除。