Vane|接入外部 SearXNG 实例,为 AI 问答构建检索底座
【免费下载链接】VaneVane is an AI-powered answering engine.项目地址: https://gitcode.com/GitHub_Trending/pe/Vane
Vane 里提了个问题,答案却没有任何来源引用,或者搜索步骤卡了 10 秒后直接报错——这类现象基本都不是模型的问题,而是它依赖的 SearXNG 实例没有配置到位。Vane 是一个 AI 驱动的问答引擎,它的检索层不直接对接任何上游搜索引擎,所有 web/学术/社区搜索都收口到一个 SearXNG 实例的 JSON API 上。地址配错、JSON 输出没开、超时被打断,三件事决定了搜索结果能否进入回答生成的上下文。
接入 SearXNG 实例并开启 JSON 输出
SearXNG 是一个开源元搜索引擎,把 Google、Bing、Wikipedia 等多个上游源聚合为单一查询接口;Vane 的 researcher agent 只跟这个接口说话。两者的分工如下:
| 维度 | 未配置 SearXNG | 配置完成后 |
|---|---|---|
sources: ["web"]等检索源 | 请求直接失败或无结果 | 经 SearXNG 聚合多引擎返回结果 |
| 上游引擎的增删 | 无法影响 | 通过 SearXNG 侧配置即可调整 |
| 部署依赖 | 仅 Vane 服务 | Vane + 一个可达的 SearXNG 实例 |
仓库在 searxng/ 目录下只提供了 SearXNG 的配置模板,服务本身需要独立部署。拿到可访问的实例后,有两处必须确认。
第一步,确认 SearXNG 允许 JSON 输出。Vane 的请求固定携带format=json参数,实例没放行这个格式时请求会被直接拒绝:
# searxng/settings.yml search: formats: - html - json第二步,把实例地址写进 Vane 的配置。设置面板的 Search 分区里有一个 SearXNG URL 字段(占位提示为http://localhost:4000),也可以通过环境变量SEARXNG_API_URL注入:
SEARXNG_API_URL=http://localhost:4000 yarn dev配好后不经过 Vane,直接验证 SearXNG 自身:
curl 'http://localhost:4000/search?q=test&format=json'返回 JSON 而不是 HTML 或 403,说明检索底座就绪。
拆解 URL 来源、超时与请求参数
URL 的读取逻辑在 src/lib/config/index.ts 和 src/lib/config/serverRegistry.ts 里,实际跑起来之后会发现环境变量并不是"最终来源"。设计意图上,data/config.json是唯一持久化的配置源,SEARXNG_API_URL只在config.json中该字段为空时填充一次初始值(initializeFromEnv中有!this.currentConfig.search[f.key]的判断)。怎么改:在设置面板里改 SearXNG URL 后,值会写回config.json。改了之后的行为变化:此后重启时环境变量不再被读取,面板里的值长期生效;想切回环境变量控制,必须先把面板里清空。
超时行为集中在 src/lib/searxng.ts 的searchSearxng:每次请求挂一个AbortController,10 秒未返回即 abort 并抛出SearXNG search timed out。设计意图是让慢引擎不至于拖死整个研究会话。怎么改:这个值是写死的,不能通过配置调整;真正能改的是 SearXNG 侧启用的上游引擎数量和实例缓存策略——上游引擎越多、无缓存冷启动时,单次/search越容易逼近 10 秒。改了之后的行为变化:上游引擎收敛后,同一查询的 P95 延迟下降,超时异常消失。
请求参数的透传也在同一函数里:categories、engines、language、pageno四个选项会被序列化进 query string,数组用逗号连接。也就是说 Vane 目前把"用哪些引擎、搜哪类内容"的决定权留给了调用方参数,而 researcher agent 在 src/lib/agents/search/researcher/actions/search/webSearch.ts 中生成的是纯关键词查询,不传engines限制——引擎选择完全由你的 SearXNG 实例配置决定。
端到端验证一次带引用的检索
配置无误后,用 docs/API/SEARCH.md 定义的/api/search端点做一次完整链路验证。该端点接收查询、检索源和模型参数,内部由 API Search Agent 执行"检索→排序→生成"全流程:
curl -X POST http://localhost:3000/api/search \ -H 'Content-Type: application/json' \ -d '{ "chatModel": {"providerId": "<provider-uuid>", "key": "gpt-4o-mini"}, "embeddingModel": {"providerId": "<provider-uuid>", "key": "text-embedding-3-large"}, "sources": ["web"], "query": "What is Kimi K2?", "optimizationMode": "balanced", "stream": false }'其中providerId是 UUID,需先GET /api/providers获取;optimizationMode影响的是 researcher 调用web_search的轮次(speed只许调一次,quality要求至少 5-6 轮),不改变单次 SearXNG 请求的内容。预期响应为:
{ "message": "Kimi K2 is a state-of-the-art LLM ... [1][3]", "sources": [ { "content": "Vane is an open-source AI-powered search ...", "metadata": {"title": "What is Vane ...", "url": "https://..."} } ] }message里的[1][3]是引用标记,下标对应sources数组的位次——能稳定产出带下标的回答和可追溯的来源列表,才算整条 SearXNG 链路验证通过。
排查超时、拒绝与空结果
- 现象:curl 直接请求
/search?format=json返回 403 或 400。根因:settings.yml的search.formats未包含json,SearXNG 拒绝该输出格式。动作:按前文补上json并重启实例,再复测。 - 现象:Vane 日志报
SearXNG search timed out。根因:searchSearxng内 10 秒的AbortController触发,通常是上游引擎过多或实例冷启动。动作:收敛 SearXNG 侧启用的引擎数量,确认实例预热后复测;这是代码内写死的上限,改 Vane 配置无法绕过。 - 现象:偶发 429,同一实例浏览器里正常。根因:仓库模板 searxng/limiter.toml 开启了
botdetection.ip_limit且link_token = true,服务端客户端不携带 link token,被限流器判定为机器人。动作:在 limiter 配置中放宽对服务器出口 IP 的规则或关闭 link_token 要求。 - 现象:改了
SEARXNG_API_URL重启后仍指向旧实例。根因:config.json里已有面板写入的值,环境变量只在字段为空时填充。动作:以设置面板里的 SearXNG URL 为准,或清空面板值让环境变量重新生效。
深入源码与 API
下一步可以按两条线展开:读 docs/architecture/WORKING.md 理解检索结果如何进入 embedding 排序和回答生成的完整流水线,或从 src/lib/agents/search/ 的 researcher actions 入手,看web_search、academic_search、social_search如何按sources参数动态启用。现在就可以动手:把 SearXNG 实例地址填入设置面板的 Search 分区,用前文的 curl 命令打一次/api/search,确认响应里出现带下标的message和对应sources。
【免费下载链接】VaneVane is an AI-powered answering engine.项目地址: https://gitcode.com/GitHub_Trending/pe/Vane
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考