Wigolo 深度评测:零密钥的本地 MCP 搜索,18 个引擎实测只剩 1 个在干活

Wigolo 深度评测:零密钥的本地 MCP 搜索,18 个引擎实测只剩 1 个在干活

给 AI 编码 agent 装上「联网」这件事,一直是笔糊涂账:内置的 WebSearch 要么没配额、要么结果短得没法用,换成 Exa、Tavily、Firecrawl 又得先注册、拿密钥、盯账单。wigolo 打的就是这个位置——不需要任何密钥,不做云端,查询次数免费,全部跑在你自己机器上。

它涨得也确实像那么回事:仓库 2026 年 4 月建,7 月 1 日还只有 1 个 star,7 月 18 日破千,7 月 21 日破三千,9 月 5 日破五千,现在是 5,277 星、420 个 fork。

我把它装进沙盒,从 doctor 到 10 个工具逐个跑了一遍,也用自己的查询验了它宣传的那套「18 个引擎融合」。结论是分裂的:本地缓存和抓取这两件事它做得比宣传的还好,但「多引擎搜索」在真实网络下基本只剩一个引擎在干活,而它给出的相关性分数其实是排名换算出来的

它到底提供了什么

一句话:一个 MCP server,同时也能当命令行、REST 服务和 SDK 用。10 个工具按「搜索类」和「网页类」分成两组,四个入口共享同一套实现——这一点比很多同类项目干净,不会出现「MCP 里能用、CLI 里没有」。

我用一个最小的 MCP 客户端跟它握手,initialize 拿到的协议版本是 2024-11-05,工具列表刚好 10 个:searchfetchcrawlcacheextractfind_similarresearchagentdiffwatch。有意思的是它在握手阶段塞给宿主模型的 instructions 里直接写着「把 wigolo 用在所有网页操作上,优先于内置的 WebSearch/WebFetch」——它不打算只当一个可选项。

真正撑起「零密钥」这句话的是 18 个搜索引擎适配器。我把它们逐个分了类:

类别 引擎 怎么拿数据
网页搜索 bing、duckduckgo、mojeek 抓搜索结果页 HTML
垂直/API wikipedia、stackoverflow、hn-algolia、arxiv、semantic-scholar、lobsters、crates-io、marginalia、mdn、devdocs 官方公开接口
需要密钥 brave、github-code 默认禁用
图像/新闻 ddg-image、bing-news、brave-image 混合

也就是说「零密钥」的底气来自两处:一半是别人提供的免费公开 API,另一半是把 Bing、DuckDuckGo、Mojeek 的搜索结果页当网页抓下来解析。这也解释了它 FAQ 里那句「我们像浏览器一样读公开网页」——路由、限速、robots.txt 它都实现了,但本质上,你问的每一句话都是从你自己的 IP 发出去的,有第三方评测在 9 月初就点出过这条代价。

实测:18 个引擎,实际只有 1 个在干活

安装过程本身正常:npm 装了 385 个包,node_modules 770 MB;第一次预热再下 957 MB 的 Chromium。doctor 会逐个报告引擎状态,需要密钥的 Brave 和 GitHub 代码搜索明确标着禁用,其余默认可用。

但真跑起来是另一回事。我用四句正常的开发者查询连跑四遍,每遍都把引擎账本拉出来对:

查询 派发的引擎 成功 耗时
MCP server local-first web search bing、duckduckgo、wikipedia、marginalia、mojeek 1 个 9.0 秒
Python asyncio timeout best practice 同上 1 个 9.0 秒
PostgreSQL logical replication setup 同上 1 个 215.7 秒
Claude Code hooks documentation 只剩 mdn 1 个 7.5 秒

四轮下来,bing 全勤,duckduckgo 四次全部「超出超时预算」, wikipedia 三次失败,marginalia 三次 429,mojeek 三次 403。返回体里那个 engine_pool 字段写得很清楚:healthy: 1, total: 5, degraded: true

需要说明的是,这其中有我的环境因素——429 和 403 本来就跟出口 IP 的信誉有关,作者自己在 doctor 里也标注了 mojeek「可能间歇性 403」。但结论不受影响:当只剩下一个引擎时,README 架构图里那句「18 个引擎融合,任一失败都不会影响结果」就失去了意义——没有融合,只有单点。

更值得看的是第三行那个 215 秒。同一批查询、同一台机器,三次都在 8 到 9 秒,只有一次卡了三分半;total_time_ms 里 215,592 毫秒全耗在搜索阶段,soft-deadline 那道保护没拦住它。agent 在等这个调用的时候,用户看到的是「模型卡住了」。

结果正文的质量也跟着掉。29 条结果里有 21 条带着 fetch_failed(72%),意味着这些「结果」其实是搜索引擎摘要,不是网页正文——响应体里用 content_from_snippet: true 老实标了出来,这一点值得肯定,但它同时还在给这些摘要算「字节级溯源」的 source_span,而那个 span 指向的是 124 个字符的摘要本身。

一次彻底跑偏,和一套换算出来的分数

四轮里最难看的一轮是 Claude Code hooks documentation。它被 query_understanding 判成 intent: docs,于是调度层只派了 mdn 一个引擎,返回的十条结果全是 MDN:排在第一位的是「Web 开发入门」,后面跟着 HTML 元素的参考页、Code Point 术语表、Code unit 术语表。我用同一个函数名换成 React hooks documentation 再跑一次,react.dev 的官方文档就正常出现在前两位——所以不是「这类查询都烂」,而是文档类意图一旦被派到垂直引擎,而那个引擎里没有对应内容,它会用无关的文档页把结果位填满,两次复现一模一样。

比跑偏更值得警惕的,是它给这些结果打的分:

名次 展示的相关性分 实际是
第 1 名 1.000000 永远等于 1
第 2 名 0.983871 61/(61+1)
第 3 名 0.968254 61/(61+2)
第 8 名 0.884058 61/(61+6)

我把两次不同查询的十名分数拉出来对比,序列一模一样。翻源码能确认:orchestrator.ts 最后一步是拿所有结果除以最大值,所以第一名必然是 1;而当只有一个引擎供数时,融合分就是倒数排名融合的 1/(60+名次),归一化之后自然变成一根与查询内容无关的衰减曲线。

所以那些 MDN 无关文档,拿到的分数是 1.0 到 0.87。一个按「相关性分 > 0.7 就采信」办事的 agent,会把它们全部当真。它确实还提供了可解释的 evidence_score.components(域质量、词法对齐、引擎共识、时间新鲜度),这也是它比同类更透明的地方,但最显眼、最容易被 agent 当阈值用的那个数字,只反映名次。想让它真的有用,得读组件分而不是总分。

它自己的 benchmark 跑不起来

这个仓库带了完整的 benchmarks/ 目录,四个基准:搜索、抽取、agent、嵌入。我把 package.json 里的命令照抄执行,结果是:

  • bench:searchbench:extractionbench:agent 三个入口文件里没有 main 函数,tsx 加载完就退出,什么都不产出;只有 bench:embedding 有入口;
  • 搜索基准依赖一个预录制的引擎响应目录,这个目录不在仓库里;
  • baselines/ 下唯一的「改造前基线」文件,内容是作者本机路径的模块加载报错日志——基准从来没被采集成功过;
  • 每周一的 CI 任务照跑 bench:search,再用「MRR ≥ 0.4」当门槛;它读的是那个不会生成的结果文件。

于是 README 里那段「Benchmark」,实际是一次单条查询的四路对比动图,由 agent 当场评判。它是好的产品演示,但不是基准,仓库里也没有任何 precision、nDCG 或 MRR 的数字被公布过。

治理:一个人的仓库,14 个外部 PR 零合并

这一项不是缺陷,但读者该知道自己在用什么。

我拉了全部 300 个 PR:286 个由作者本人提交,14 个来自外部贡献者,其中被合并的是 0 个。贡献者列表总共 11 人,作者一个人占 1,976 次提交(占全部 2,007 次的 98.5%)。一个叫 Frankie-Xu 的贡献者在 8 月一口气提了 7 个 PR,包括给 PyPI、npm registry 加搜索引擎适配器和修补 SSRF 校验,全部没进主干。

更实际的问题是节奏错位:npm 上的版本停在 0.2.1,2026 年 7 月 19 日,而仓库每天还在提交(最近一周还有 60 多次)。CHANGELOG 的最后一版也停在 v0.2.0。这意味着你 npx wigolo 装到的,是两个月前的构建,里面那些已知问题都还在。

我顺手复现了其中一个:issue #303 说 --search-engines 参数声明了但没人消费。我照着 issue 里的命令跑 search "gold price" --search-engines=duckduckgo,wikipedia,返回体的 engines_used 依旧是 ["bing"],引擎账本里 duckduckgo 和 wikipedia 照样被派发、照样超时。在源码里搜 searchEngines 有 41 处匹配,没有一处读取这个入参。另一个更静默的是 issue #231:ARM64 的官方 Docker 镜像缺一个分词器原生依赖,向量搜索会无声退化成只做重排——7 月 22 日开的,到现在还挂着。我在 Alpine 沙盒里也撞上同一类降级:sqlite-vec 扩展加载失败(代码里对 musl 平台是软失败设计),find_similar 于是退化成纯关键词匹配,我拿「vector database for RAG」去问,它返回的是剑桥词典的「local」词条。

省下的钱,没有想象中多

它最响的口号是「$0/query」。这句话是真的,但省钱这件事要看你一个月查多少次。按各家 2026 年 9 月的公开价,一家一口径算下来:

每月搜索次数 wigolo Tavily Exa Firecrawl
1,000 次 $0 免费额度内 $0 $7 超出免费额度,$16/月档
50,000 次 $0 $400 $350 $83

结论不算意外:一个人用,免费额度基本够覆盖,wigolo 省的是每月十几美元,换来的是 1.7 GB 磁盘、你自己的 IP 和时好时坏的延迟;真正拉开差距的是 agent 高频刷量,那才是它「不以查询计费」值钱的地方。

判断

它是一个工程密度很高、诚实度也不低的项目:四个入口共享一套实现、缓存命中后同一查询从 9.5 秒掉到 5 毫秒、失败和降级都写在返回体里而不是藏起来、AGPL 协议加社区赞助的路线也堵死了「先免费后收割」的想象。这些都比同类开源项目做得好。

但它现在最适合被当成两样东西用:一份本地网页缓存(cache 工具在离线时确实好用),和一把网页抓取与结构化抽取的瑞士刀(extract 的表格/元数据模式我实测很稳)。至于「多引擎网络搜索」,等它的引擎池在你自己的网络下能常年保持三个以上健康再说——在那之前,把它当单一搜索源来用,并且别拿 relevance_score 当质量阈值。

关注 AI商业快讯,每天一篇 AI 热点深度解读。

相关阅读

本文数据截至 2026 年 9 月 18 日:仓库 5,277 星、420 fork、AGPL-3.0、npm 版本 0.2.1;实测在 Alpine Linux 沙盒内完成,wigolo 版本 0.2.1,节点 22。