wigolo搜索流水线深度剖析:18引擎并行扇出、RRF融合与ML重排
【免费下载链接】wigoloThe go-to web for your AI coding agent — local-first search, fetch, crawl & research over MCP. No API keys, no cloud, $0/query. Public beta.项目地址: https://gitcode.com/GitHub_Trending/wi/wigolo
wigolo 是一个本地优先(local-first)的 AI 智能体搜索工具,把「搜索、抓取、爬取、研究」打包成一条 MCP 流水线——无需 API Key、不依赖云端、每次查询$0。它的核心正是本文要逐层拆开的搜索流水线:一条查询进来,先做意图路由,再并行扇出给 18 个搜索引擎,用RRF 倒数排名融合成一份榜单,最后交给本地 ML 交叉编码器重排精修。下面从意图路由讲到降级恢复波次,帮你完整看懂这条流水线如何跑通,为什么单引擎挂了也几乎不影响结果。
一、为什么需要一条「本地优先」的搜索流水线
传统做法是把搜索丢给某个云 API——按次计费、要 Key、结果不透明。wigolo 反其道而行:它把最贵的部分(排序、嵌入、浏览器引擎)全部搬到你自己的硬件上运行,因此没有按次成本要回收,也就没有计量表(meter)。
这条流水线最打动人的两个工程决策,是贯穿全文的线索:
- 并行扇出:一次查询同时打给 18 个引擎,任何一个失败都「几乎不移动结果」。
- 可解释打分:每条结果都带透明的分数拆解,agent 永远知道自己站在什么证据上。
二、第一步:意图路由,把查询送进正确的垂直领域
查询到达后,第一件事不是搜索,而是先判断它属于哪个垂直领域(Vertical)。wigolo 内置 6 条赛道:general、news、code、docs、papers、images。
路由逻辑在 intent-router.ts 里,用几组正则快速判别:
- 出现
arxiv / doi / paper / citation→ 论文赛道 - 出现
github / commit / stackoverflow / TypeError→ 代码赛道 - 出现
how to / tutorial / mdn / documentation→ 文档赛道
判断完后,对应赛道才决定这一波到底派出哪几个引擎。这正是「18 引擎」能精准命中的前提:不是所有查询都去撞全部引擎,而是按领域挑出最对路的那一队。
三、并行扇出:18 个引擎同时出发
选定赛道后,orchestrator.ts 会调用runEnginesParallel,把查询并行打给队内每个引擎。以代码赛道为例,verticals/code.ts 一次性派出:
| 引擎 | 权重 | 质量档 | 角色 |
|---|---|---|---|
| GitHub Code | 1.2 | medium | 代码意图主力 |
| Stack Overflow | 1.0 | high | 高可信问答 |
| DuckDuckGo | 0.8 | medium | 通用网页广度 |
| MDN / crates.io | 0.3 | high | 次级信号(弱时降权) |
每个引擎都注册了权重(weight)与质量档(high / medium / low),它们会直接喂给后面的 RRF 融合。
3.1 每个引擎都被「熔断器 + 重试」包了一层
真正让扇出稳如老狗的,是 engine-base.ts 里的wrapWithRetryAndBreaker:
- 重试:单次调用失败会指数退避重试,避免把限流的引擎打爆。
- 熔断:连续失败 3 次就跳闸,进入冷却;429 限流走短窗口(最多 30s),403 禁用走长窗口(最多 180s)。
- 软截止(soft deadline):整波最多等3.5 秒,某个慢引擎被「放弃在飞行中」,绝不拖垮整体响应。
3.2 去重:跨引擎合并同一 URL
各引擎回来的结果在 dedup.ts 里做归一化 + 去重:同一 URL 只保留一份,合并出「它被哪几个引擎命中」——这个多引擎共识数正是后面 RRF 融合的关键原料。
四、RRF 融合:把多份榜单合成一份
这是流水线的灵魂。RRF(Reciprocal Rank Fusion,倒数排名融合)的规则极其简洁——对每条 URL,把它在每个榜单里的排名取倒数再相加:
score(url) = Σ weight / (k + rank) 其中 k = 60代码在 rrf.ts,而生产级的加权版本写在 orchestrator.ts 的 scoreOutcomes。它的妙处在于:
- 不依赖各引擎的分数刻度——Bing 给 0.9、DDG 给 87,量纲完全无所谓,只看「排第几名」。
- 多引擎共识自动加权——一个 URL 在 3 个榜单都靠前,分就滚雪球式地高。
- 鲁棒——任何一个引擎挂掉,其余榜单照样能融合出合理结果。
融合后还会叠一层多因子修正:域名质量、词汇对齐度(query 与标题/摘要的贴合度)、时效性加成、次级引擎降权、稀有词命中等,最终得到 一条可解释的 evidence_score(形如base=0.016, domain=0.82, lex=0.91, engines=3)。
五、ML 重排:用本地交叉编码器给结果精排
RRF 出的是粗排,真正的「精排」交给 rerank.ts。它默认走onnx模式,加载 transformers-rerank-provider.ts:
- 模型:
Xenova/ms-marco-MiniLM-L-6-v2(交叉编码器,Transformers.js 驱动)。 - 做法:把
(query, 文档)成对喂给 tokenizer,直接读 logits 作为重排分数——logit 越高越相关。 - 完全本地:模型缓存进 wigolo 数据目录,不上云、不收费。
重排后再串接三个确定性增强器:共识加成(多引擎命中的上浮)、权威加成(知名域名的上浮)、时效加成(带日期的新鲜结果上浮),最后按分排序并套上相关性阈值过滤。
提示:模型是懒加载的。如果重排报「model not downloaded」,跑一次
wigolo warmup预热即可。
六、降级恢复:引擎池塌了怎么办
这条流水线最「工程范」的地方,是它为崩溃而设计。当主波次派出去的引擎里,健康数量低于「派发出发数的一半」(poolHealthFloor)时,说明引擎池在突发压力下塌方了:
- 恢复波次:强制召回被「软禁用」的探针引擎(如 Mojeek)+ 刚跳闸的引擎,在同一个突发窗口内把池子救回来,而不是傻等完整冷却。
- 饥饿回填:某个垂直赛道融合后结果太少(< 3 条),就用通用赛道的引擎池按结果粒度 RRF 合并进来补召回。
- 赛道兜底:非通用赛道整体降级时,自动重试一次「general」赛道。
所有降级都会在输出里如实上报(engine_warnings、pool_degraded),agent 永远知道答案站在多硬的证据上。
七、上手体验:三步跑通这条流水线
整条流水线的入口是search工具。最省事的接入方式:
- 初始化本地引擎:
npx wigolo init(下载浏览器引擎与本地模型,跑一遍健康检查)。 - 接入你的 agent:加
--agents一条命令把常用编码 agent 接上。 - 发起查询:直接对 agent 说「用 wigolo 搜一下 …」,它会自动扇出 → 融合 → 重排 → 返回带透明分数的结果。
相关参考文档:搜索工具说明、安装指南、配置参考。
八、一句话总结
wigolo 的搜索流水线 =意图路由(选赛道)→18 引擎并行扇出(带熔断器保护)→RRF 倒数排名融合(多榜单合成一份)→本地 ML 交叉编码器重排(精修 + 可解释打分)→降级恢复波次(为崩溃而设计)。全程 $0/查询、结果可解释、任何单引擎失效都几乎不动摇最终榜单——这正是它作为「AI 编码智能体首选 web」的底气所在。
【免费下载链接】wigoloThe go-to web for your AI coding agent — local-first search, fetch, crawl & research over MCP. No API keys, no cloud, $0/query. Public beta.项目地址: https://gitcode.com/GitHub_Trending/wi/wigolo
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考