Stars 不是采用:我如何监控开源 MCP 的增长与搜索质量
开源 MCP 项目如何同时监控 GitHub、npm、克隆、搜索质量与内容发现?这篇实践记录解释为什么这些信号必须分开,并保留每条链路的失败状态。
本文索引08
Stars、npm 下载、仓库克隆、搜索排名和真实查询描述的是不同阶段。把它们加成一条“增长曲线”,反而会隐藏最重要的信息:哪一层真的工作,哪一层只是暂时拿不到数据。
2026 年 8 月 3 日,Agent Search MCP 的周报出现了一个很典型的状态:npm 周下载量和 GitHub clone 数据都能读取,GitHub stars 却返回了 ?。五天后,另一条每日质量探针正常结束,没有输出任何告警。
如果监控只保留一盏总灯,这两次运行都很容易被误读。? 可能被当成 0,静默可能被当成“任务没跑”,而一颗增长的 star 又可能被写成一个新增用户。
我后来把监控拆成两条管线:一条观察项目如何被发现,另一条检查搜索产品是否还能完成最小任务。它们共享时间戳和版本信息,但不共享结论。
先拆开五种看起来相似的数字
开源项目常见的数字至少属于五层:
| 信号 | 能说明什么 | 不能说明什么 |
|---|---|---|
| GitHub stars / forks | 仓库受到关注,或有人准备继续研究 | 已安装、已部署、持续使用 |
| npm 下载 | 包文件被注册表请求 | 独立用户数、成功安装、生产使用 |
| GitHub clones | 仓库在给定窗口内被克隆 | 克隆者身份、是否跑通、是否留存 |
| GSC query / page | 真实 Google 搜索产生了曝光或点击 | 其他搜索引擎排名、项目采用 |
| 主动排名检查 | 固定条件下目标页面是否可见 | 真实用户是否搜索过这个词 |
这些数据可以串成调查顺序,却不能直接串成转化漏斗。比如 npm 的 CI 安装、缓存失效和版本更新都可能制造重复下载;clone 也可能来自自动化。即使 GitHub、npm 和搜索数据同时上升,也只能提出“值得继续检查”的假设。
因此,周报中每个字段都保留自己的来源、时间窗和错误状态。缺失值写成 unknown,而不是补 0;暂时无法访问的目录接口也不自动解释为“没有收录”。
增长采集器只负责报告事实
增长采集器每周读取三类数据:GitHub 仓库与近 14 天 clone、npm 的周下载,以及能够公开访问的生态目录。它输出结构化 JSON,再由报告层写成人能读的摘要。
这个分层解决了一个实际问题:采集脚本不应该为了让报告“完整”而猜数字。核心逻辑更接近下面这样:
snapshot = {
"github": read_github_repo_and_clones(),
"npm": read_npm_weekly_downloads(),
"directories": read_public_directory_status(),
}
for source, result in snapshot.items():
if result.failed:
snapshot[source] = {"status": "unknown", "reason": result.error_class}8 月 3 日那次运行里,GitHub CLI 路径超时,采集器把 stars 留成未知;人工只读复核可以看到仓库页面,但这个补充事实不能倒写成“原采集器成功”。否则下一次同类故障会被报表掩盖。
这也改变了我看周报的方式。它不是成绩单,而是一张排障地图:哪条分发链路有数据、哪条链路失明、下一步需要检查产品还是检查采集器。
质量探针与增长数据完全分开
增长不代表产品还能正常工作。Agent Search MCP 依赖多个上游来源;仓库可能继续获得关注,但某个语言路径已经超时,或所有来源都只返回空结果。
每日质量探针因此只做三个固定的小任务:英文时效查询、中文查询,以及英文技术查询。每次运行记录:
- 命令是否成功结束;
- 接受了多少条结果;
- 总耗时是否超过 30 秒;
- 哪条固定查询发生退化。
当前最低门槛只是“至少一条结果且不超过 30 秒”。这是一条存活探针,不是搜索质量排行榜,也不能证明相关性、引用支持或长期 SLA。更深入的判断仍要使用版本化查询集、完整 trace 和盲化评审;我在Agent Search 评估框架中单独整理了这些边界。
探针采用“成功静默、退化输出”的约定。cron 正常运行时不制造日报噪音;只要某个查询无结果、超时或命令失败,就把查询名、延迟和错误类别交给告警层。静默是否代表成功,则由 cron 的退出状态和运行记录确认,不能只看标准输出。
三种最容易写错的结论
1. unknown 不是 0
接口超时、认证失效或上游挑战页都可能让一个字段暂时不可读。0 是一个业务事实,unknown 是一个观测事实。二者必须使用不同类型和展示方式。
2. 搜索挑战页不是“没有排名”
主动查询 DuckDuckGo 时,自动请求可能命中 human challenge。这个结果只能说明本次检查被拦截,不能证明页面不在索引里。真实 GSC demand、固定引擎排名检查和 AI 引用观察也应该分开保存。
3. 注意力不是采用
截至 2026 年 8 月 8 日的只读 GitHub 快照,Agent Search MCP 有 91 stars、7 forks,最新稳定 release 是 v3.2.0。这些数字可以描述公开关注与分发状态,但没有安装遥测、用户账户或下游部署证据,所以我不会把它们写成 91 个用户。
同样,8 月 3 日周报中的 npm 下载和 clone 快照只能描述各自窗口内的请求与克隆活动。要谈采用,至少还需要可识别的下游集成、维护者反馈、复现记录或经同意采集的产品信号。
我现在保留的监控契约
这套实践最后收敛成五条简单规则:
- 每个数字保留来源、时间窗、版本和采集状态。
- 采集失败保持
unknown,不填 0,也不由报告层猜测。 - 增长、运行质量、真实搜索需求和主动排名分别存储。
- 成功静默只用于低噪音探针,必须同时保留退出状态和运行记录。
- 报告写“观察到了什么”,不从 stars、下载或 clone 推导用户数。
这套系统仍有明显限制:固定三条查询只能发现粗粒度退化;公开 API 会受认证、限流和网络影响;目录收录与排名检查也可能被挑战页阻断。它更像一层便宜、持续的早期预警,而不是完整的产品分析平台。
如果你正在给自己的搜索 Agent 或 MCP Server 加监控,可以先从两条独立 cron 开始:一条采集分发事实,一条运行少量中英文存活查询。不要急着做统一分数,先确保每个失败都能保持原来的含义。
想检查这里使用的开源样本,可以查看 Agent Search MCP 的代码、release 和评估材料,或先阅读它作为免费 Tavily 替代路径时的适用边界。