news 2026/10/14 4:34:04

SearXNG+Jina Reader:给AI Agent搭建零成本搜索链路的部署实战

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SearXNG+Jina Reader:给AI Agent搭建零成本搜索链路的部署实战

前阵子在给自己维护的智能体项目(OpenClaw)配联网搜索能力时,认真研究过一条完全不走商业付费的路线:用开源的 SearXNG 做元搜索入口,再用 Jina Reader 把网页正文转成干净文本,最后喂给智能体去总结。这个组合很适合那种“偶尔查资料、不想为每次搜索都掏 API 费用”的个人 Agent 场景,也适合小团队先把搜索链路跑起来再说。

先说结论:这套方案跑起来之后,OpenClaw 既能自己搜到最新的网页,又能把网页正文读成 LLM 好处理的 Markdown,全程不产生按次计费的搜索成本。整个部署只需要一台 1 核 2G 的云服务器,装好 Docker,剩下的就是配置和联调。我在这条链路上踩过不少坑,包括 SearXNG 的 JSON 接口返回 403、Jina Reader 超时、容器里连不上宿主机等等,下面会把每一步怎么做、为什么这样做、出问题了怎么排,一次讲透。

1. 为什么是 SearXNG + Jina Reader:免费方案不等于将就

1.1 搜索入口选型:自建元搜索是唯一的高性价比路径

给智能体接入联网能力,摆在面前的无非三条路:直接调商业搜索 API、自建爬虫、自建元搜索。

商业搜索 API 确实省事,但它的成本模型和 Agent 场景天然冲突。Agent 的搜索特点是请求量不稳定,可能一天几次,也可能一个任务连续触发十几条查询。商业 API 大多按千次请求计费,还有 QPS 限制,一旦跑长任务,费用和限流两个问题会同时冒出来。更难受的是,Agent 经常需要反复尝试不同的查询词,每试一次都是钱。

自建爬虫则是另一个极端。搜索引擎返回的只是链接列表,你要拿正文就自己去抓目标网站。现在的网站反爬手段一个比一个狠,登录墙、JS 渲染、验证码都是家常便饭,一个通用爬虫维护成本能拖垮整个项目。

SearXNG 属于第三条路:它是一个自托管元搜索引擎,自身不建索引,而是把 Google、Bing、DuckDuckGo、百度等上游搜索引擎的结果聚合起来。它把搜索请求的复杂性和反爬压力集中在自己这一层,对下游应用暴露一个干净接口。更重要的是,它没有按量计费的概念,跑在同一个人服务器上就是一次性的部署成本。

我用 Docker 方式部署,是因为搜索服务对运行环境比较敏感,涉及的依赖不少,Docker 可以一次性解决环境问题。另外云服务器上通常还要跑 OpenClaw 主程序和其他辅助服务,容器隔离能避免端口冲突和依赖打架。

1.2 内容读取选型:为什么需要 Jina Reader 这一层

搜索只负责“找到”,不负责“读懂”。SearXNG 返回的是 URL 列表、标题、摘要这些元信息,但 Agent 要回答“这篇文章到底说了什么”,必须拿到完整正文。

这时候如果自己写正文抽取工具,等于把之前想避开的爬虫难题又捡回来了。不同的网站有不同的 DOM 结构,正文容器从<article>到<div id="content">五花八门,还夹杂着导航、广告、推荐位这些噪音。

Jina Reader 做的就是这件事:给它一个 URL,它返回经过清洗的、接近 Readability 效果的 Markdown 文本。它把 URL 转成 LLM-friendly 内容,省掉了下载网页、抽取正文、清洗 HTML 的一整套脏活。这个过程对 Agent 来说非常关键——LLM 处理干净文本的效果,和处理一堆<script>标签加导航链接的效果,完全不是一个量级。

Jina Reader 官方提供托管 API,注册后有一定免费额度,用起来直接发请求就行。如果搜索频率极高或者不想依赖外部服务,也可以考虑自部署 Reader 的替代实现,只是多费点维护精力。这个小差别后面细说。

1.3 整条链路的实际工作过程

把两个服务串起来以后,OpenClaw 的联网查询大致走这样的流程:

  1. OpenClaw 生成搜索词,例如“最近云计算领域有哪些新技术发布”。
  2. OpenClaw 把这个词以 JSON 格式请求发给 SearXNG。
  3. SearXNG 聚合多个上游搜索引擎,返回一堆带标题、URL、摘要的结果。
  4. OpenClaw 根据任务需要,挑选其中最相关的几个 URL。
  5. OpenClaw 把选中的 URL 发给 Jina Reader,拿到网页正文的 Markdown。
  6. 最后将正文内容连同问题一起交给 LLM,由它完成归纳和回答。

这个链路的好处是每一层都解耦了:SearXNG 管“找”,Jina Reader 管“读”,OpenClaw 管“想”。任何一层都能单独替换,出问题时排查边界清晰。

2. 部署前的准备工作:一台小服务器就够

2.1 服务器配置与 Docker 环境

这套方案并不吃硬件,SearXNG 本身是 Python 项目,内存占用大头在运行中的上游引擎连接和缓存上,1 核 2G 内存完全跑得动。我实际测试时,SearXNG 容器空闲状态占用大约 300-400MB,峰值也不会超过 800MB。剩下的内存给 OpenClaw 进程完全够用。

如果你用的是国内主流公有云厂商的按量付费实例,建议直接开一台 1 核 2G 的 Linux 机器,系统选 Ubuntu 22.04 或 Debian 12 都行。数据盘不用单独挂,默认系统盘就足够,因为 SearXNG 和 OpenClaw 都不是重存储应用。

装 Docker 那一步没什么特殊门道,直接用官方安装脚本:

curl -fsSL https://get.docker.com | sh systemctl enable --now docker docker compose version

看到Docker Compose version输出就说明环境就绪。注意千万别图省事跳过 Compose 的安装,后面所有服务的编排都靠它。

2.2 安全组与端口规划

这里分享一个很重要但容易踩坑的点:SearXNG 不需要暴露到公网。

搜索服务是给 OpenClaw 内部调用的,对外没有服务对象。安全组只需要放行 SSH 端口,以及你访问 OpenClaw 控制台可能用到的端口。SearXNG 默认监听 8080,Jina Reader 走的又是外部 API,理论上这些都不用暴露到公网。

这样做的好处是避免搜索引擎接口被外面扫到。SearXNG 一旦部署成公网可访问状态,就会被各种爬虫脚本利用来刷搜索结果,轻则耗光你的服务器带宽,重则上游引擎把你的出口 IP 封掉。

所以我的建议是:在云厂商控制台的安全组中,只保留 SSH 端口,其他端口一律不放行。SearXNG 地址用http://localhost:8080即可,OpenClaw 如果也宿主机上跑,直接访问 localhost 就能连通。

如果你确实需要远程查看 SearXNG 的搜索界面,可以用 SSH 隧道:

ssh -L 8080:localhost:8080 user@your-server

这样本机浏览器访问http://localhost:8080就是服务器上的 SearXNG,而公网照样访问不到。这个用法比开放安全组安全得多。

3. SearXNG 部署与调优:核心就在 settings.yml

3.1 用 Docker Compose 拉起实例

SearXNG 官方提供了独立的 Docker 镜像,配合 Compose 文件管理最清晰。下面是我在用的最小化 Compose 配置:

version: "3.8" services: searxng: image: searxng/searxng:latest container_name: searxng restart: unless-stopped ports: - "127.0.0.1:8080:8080" volumes: - ./searxng-data:/etc/searxng environment: - SEARXNG_BASE_URL=http://localhost:8080/ cap_drop: - ALL cap_add: - CHOWN - SETGID - SETUID

这里有一个细节需要注意:端口映射写的是127.0.0.1:8080:8080,而不仅是8080:8080。映射到本地回环地址可以让 Docker 只在本机访问该端口,外部网络根本连接不到。这是比安全组更底层的一层防护。

启动命令:

mkdir -p searxng-data docker compose up -d

首次启动时容器会生成默认的settings.yml到searxng-data目录。如果拉镜像比较慢,记得在 Docker daemon 配置里加一下国内可用的镜像加速地址,不然可能等好几分钟。

3.2 修改 settings.yml:让外部调用正常工作

SearXNG 默认配置主要面向 Web 界面,要让 OpenClaw 能通过 JSON 格式调用,必须改三处:生成密钥、打开 JSON 格式、调整默认搜索格式。

先处理secret_key。这是它内部签名和 Cookie 加密的基础密钥,默认配置里是一段占位符,不换掉的话服务在外部访问时会出现异常。生成方式很简单:

openssl rand -hex 32

建议把它写进环境变量,不直接放进 settings.yml。我通常会在 Compose 文件里加一行:

environment: - SEARXNG_SECRET=xxxxx

接着编辑searxng-data/settings.yml,重点修改这两块:

use_default_settings: true server: secret_key: ${SEARXNG_SECRET} bind_address: "0.0.0.0" limiter: false search: formats: - html - json

formats里加上json是 OpenClaw 能拿到结构化搜索结果的关键。搜索请求会变成类似这样的调用:

curl "http://localhost:8080/search?q=test&format=json"

返回格式大致是:

{ "results": [ { "url": "https://example.com/article", "title": "示例文章标题", "content": "摘要文本" } ] }

limiter: false是把内置限速关掉。这个限速原本是防 Web 界面被滥用,但在纯内部调用场景下,它会在你连续请求时直接拒绝服务,让人误以为是上游引擎封了 IP。我在调式阶段就被这个开关坑过,OpenClaw 连续跑三个任务就报 429,后来发现是 SearXNG 自己限的流。自己用就关掉,无妨。

3.3 引擎层面的取舍:别默认全开

SearXNG 默认会启用十几个引擎,包括 Google、Bing、DuckDuckGo、Wikipedia、GitHub 等。全部启用的问题在于:

  • 每个引擎都需要时间去响应,总响应时间等于最慢的引擎决定。
  • 某些引擎对自动化请求比较敏感,频繁调用容易被临时封禁。
  • 结果数量多了之后,反而对 Agent 没意义——它只需要最相关的几条。

我的做法是只保留少数几个质优稳定的引擎。以下是针对通用搜索的推荐配置:

engines: - name: google disabled: false - name: bing disabled: false - name: duckduckgo disabled: false - name: wikipedia disabled: false - name: github disabled: false

把其余引擎全部设成disabled: true。这样搜索延迟会明显缩短,单次搜索基本在 2-3 秒内返回,而全引擎开启时经常要等 5-8 秒,OpenClaw 的体验差距非常大。

但要注意一个现实问题:不同地域、不同 IP 的服务器,访问上游引擎的成功率差异很大。比如有些人服务器请求 Google 会频繁遇到验证码,DuckDuckGo 反而稳定。这没有统一答案,需要你在部署后用 curl 逐个测试,保留实际可用的引擎。

另外一个实用的点:在引擎具体配置里可以单独设置weight来调节它的结果优先级。比如你希望 Bing 的结果排在前面,就给它weight: 2.0,默认是 1.0。元搜索的原理是聚合排序,调 weight 比调代码里的排序逻辑简单得多。

3.4 搜索接口验证与稳定测试

配置修改完成后,重启容器再跑一遍验证:

docker compose restart curl "http://localhost:8080/search?q=linux&format=json"

能正常拿到 JSON 就说明核心链路通了。这时候还可以做一个小压力实验,连续发 20 个请求,观察是否出现超时或空结果。这能帮你在接 OpenClaw 之前,提前暴露引擎稳定性问题。

我实际遇到过的情况是:前 10 个请求一切正常,第 11 个开始 Google 返回空结果,DuckDuckGo 也开始断续失败。后来确认是出口 IP 被上游引擎临时限流,缓解办法是给 SearXNG 加一层简单的缓存。SearXNG 原生支持 Redis 缓存,启用后相同查询词的二次请求会直接命中缓存,大幅减少对上引擎的调用:

redis: url: "redis://localhost:6379/0"

对应的 Compose 文件里加一个 Redis 服务即可。缓存时间我习惯设在 5 分钟,够让 Agent 在长任务中重复查询时不打重请求。

4. 接入 Jina Reader 与 OpenClaw 配置:串起搜索到阅读的完整链路

4.1 Jina Reader 的两种接入方式

Jina Reader 最常见的用法是直接用官方托管服务。把目标 URL 替换掉固定域名前缀,就能拿 Markdown:

curl "https://r.jina.ai/https://example.com/article"

返回内容就是清洗过后的正文。对于个人使用频率来说,注册账号拿到的免费额度通常够用,而且它不需要你自己维护任何代码。

不过免费额度对高频任务并不友好。比如 OpenClaw 在分析多个链接时,可能一分钟内发十几个读取请求,免费层很容易触发限流。这时候有两个替代思路:

一种是在 OpenClaw 的调度层做限速,把请求间隔拉长到 2-3 秒。另一种更彻底,是自部署一个开源的 Reader 服务。开源社区有几种实现,核心都是用 Playwright 或类似工具渲染页面后抽取正文,配合 Jina 的 URL 格式做等价替换。

我的建议是:先用官方托管 API 把链路调通,后续如果遇到限流,再考虑自部署。不要一上来就自部署,因为浏览器渲染方案的资源消耗远高于 SearXNG,需要额外权衡内存。

4.2 在 OpenClaw 中配置搜索与阅读工具

OpenClaw 这类 Agent 框架的核心思路是给模型注册工具,然后在自然语言交互中按需调用。搜索和阅读就是两个标准工具。

配置上大同小异,关键是定义好工具的入口 URL 和返回参数。下面是一个通用化的配置示例思路:

tools: - name: web_search type: http endpoint: "http://localhost:8080/search" method: GET params: q: "{query}" format: "json" response: "从 results 中取 url、title、content" - name: web_read type: http endpoint: "https://r.jina.ai/{url}" method: GET response: "返回的 Markdown 视为正文内容"

这里最关键的是别把format=json漏掉。如果漏了,OpenClaw 拿到的是 HTML 页面,模型没法直接解析,还得自己写抽取规则,等于走回头路。

不同框架的工具注册方式可能差别很大,但你只需要关注一个本质:Agent 向搜索服务发请求、拿 structured response、再把 URL 交给 Reader 服务。无论配置语法怎么变,这条数据流是固定的。

4.3 联调验证:从搜索词到总结回答

配置完成后,做一次端到端测试。给 OpenClaw 发一句话:“搜索一下 Docker 和 Kubernetes 的区别,把网页内容读出来,总结三个关键点。”

接下来观察的链路行为应该是:

  1. OpenClaw 生成搜索词“Docker vs Kubernetes”。
  2. 调用 SearXNG 接口返回结果列表。
  3. OpenClaw 自动挑选 2-3 个链接。
  4. 对这些链接逐个调用 Jina Reader 拿正文。
  5. 模型汇总输出最终答案。

在这个测试里,最容易出问题的环节是第 4 步。Jina Reader 对某些网页会返回 403,或者等待时间过长导致 Agent 超时。我的经验是,在 OpenClaw 的阅读工具配置里设置一个略高于默认值的超时时间,比如 30 秒。因为 Reader 服务本身需要先下载页面再抽取正文,耗时比普通 API 长,超时设太短会让 Agent 误判为失败。

如果等待时间确实经常超长,可以考虑把官方 API 换成配套的自部署方案,内部网络调用延迟会低很多。不过这要看具体场景,不是必须的优化。

5. 常见问题与排查技巧实录

5.1 SearXNG 返回 403 / 404

403 最常见的原因是secret_key没有设置好。多数情况下是环境变量没传进容器,或者 settings.yml 里引用变量失败。排查顺序:

docker exec searxng env | grep SECRET docker exec searxng cat /etc/searxng/settings.yml | grep secret_key

如果容器内环境变量存在、settings.yml 里也有值,再看是不是上游搜索引擎回源时拒绝了请求。可以通过直接请求引擎地址做对照测试。

404 的场景一般在 JSON 接口上,表现为curl返回纯 HTML 而不是 JSON。这种情况检查 settings.yml 的search.formats是否真的包含了json,改完记得重启容器。

5.2 Jina Reader 超时或 429

官方托管 Reader 对短时间大量请求会进行限流,表现为连续多个 429。这个问题的根源不是配置,而是调用频率。

最直接的缓解措施是在 OpenClaw 工具层加一个请求间隔,把并发调整为串行,每次请求间隔 2 秒以上。如果对网页批量读取的需求很高,自部署 Reader 才是根本解。但要注意,自部署 Reader 的内存占用比 SearXNG 高,1G 内存的服务器可能会紧张,建议至少 2G 起步。

另外 Reader 对某些目标网站返回 403,跟目标站的反爬策略有关,不是你配置问题。换个网站或换一种请求头(后面附带 UA 字符串)可能就能解决。

5.3 OpenClaw 连不上 SearXNG

如果你把 SearXNG 跑在 Docker 里,OpenClaw 也跑在 Docker 里,不能直接用localhost:8080。因为两个容器各自有独立的网络命名空间,localhost指向的是自己。解决办法有两种:

  • 在同一个 Compose 网络里用服务名searxng:8080。
  • 或者在 OpenClaw 容器里用宿主机 IPhost.docker.internal:8080。

实际部署时,如果 OpenClaw 是直跑在宿主机上的进程,用localhost:8080就行。如果你把全部服务都容器化,就统一走 Compose 网络。这一点很容易忽略,现象就是 OpenClaw 报 connection refused 或 timeout。

建议在 OpenClaw 容器里先手动执行一次:

curl http://searxng:8080/search?q=test&format=json

能通再谈别的。

5.4 上游引擎被封禁

SearXNG 的 IP 如果被某个上游引擎临时封禁,表现为这个引擎的结果突然全部消失,或者请求这个引擎时响应时间显著变长。

解决优先级:

  1. 降低对该引擎的调用频率,把并发设低。
  2. 给 SearXNG 启用 Redis 缓存,减少真实请求。
  3. 在引擎列表里临时禁用这个引擎,靠其他引擎顶上。
  4. 如果频繁被多个引擎封禁,考虑换一个出口 IP。

这里提醒一句,不要在服务器上对上游搜索引擎做大规模并发抓取,这既会连累你的 SearXNG 稳定运行,也会给其他使用者带来麻烦。合理使用、低频调用才是长期方案。

5.5 内存与性能问题

SearXNG 容器在某些场景下内存会缓慢增长,尤其启用大量引擎时。我发现的问题集中在长时间运行后,容器内存比刚启动时高了近一倍。这跟引擎连接池不释放有关。

最简单的处理是给容器加一个内存上限:

deploy: resources: limits: memory: 512M

总体思路是控制引擎数量和并发数,内存问题就会自然缓解。真到了内存不足的程度,用docker compose restart searxng一次性释放连接池也就够了。

6. 一点经验与后续扩展

这条链路跑顺以后,我最大的体会是:SearXNG 的配置项非常多,但真正决定成败的只有几个——secret_key、formats、引擎开关和限流设置。把这几项处理干净,部署成功率就很高了。别一开始就调花哨的功能,先把最小闭环跑通,再逐步加引擎、加缓存、加自定义排序。

如果你后续想进一步扩展能力,有几个方向可以试着走:给 SearXNG 做语义缓存,把常见问题的搜索结果存到向量数据库里,OpenClaw 再次遇到类似问题时直接命中缓存,减少对外请求;或者对 Reader 的结果做本地快照,把常用页面的正文保存起来,形成一个轻量知识库。

这套免费体系的好处在于它没有单次调用的计费压力,也就给了你足够的空间去实验和优化。说到底,搜索能力对 Agent 而言只是基础设施,稳定、无顾虑地持续运行,比任何花哨的进阶功能都重要。希望这篇记录能帮你少走点弯路。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/14 4:33:59

把AI答疑变成个人知识库:从一次性问答到持续学习系统的设计实践

你有没有过这种体验&#xff1a;对着 AI 问完一个复杂问题&#xff0c;花了十几分钟反复追问才把思路理顺&#xff0c;得到一段非常满意的解答&#xff0c;然后关掉聊天窗口。两周后遇到类似问题&#xff0c;你发现自己还是得重新组织语言、重新提问、重新等它生成——你明明“…

作者头像 李华
网站建设 2026/10/14 4:33:50

PostgreSQL链接全指南:连接配置、连接池与JOIN调优

1. 写在前面&#xff1a;什么场景下你会被"PostgreSQL链接"卡住做后端开发和数据库运维的同学&#xff0c;几乎每天都在跟 PostgreSQL 的"链接"打交道。但很多同行对它的理解停留在"能连上、能查出数据就行"&#xff0c;真到了排查故障或者做性能…

作者头像 李华
网站建设 2026/10/14 4:33:24

自研轻量级API接口设计器:从JSON Schema到Mock数据的工程实践

做接口设计这件事&#xff0c;我们团队曾经被两个问题反复折磨&#xff1a;一是接口文档几百行写下来&#xff0c;前后端看的根本不是一个版本&#xff0c;联调时全靠人肉对字段&#xff1b;二是新同事上线&#xff0c;光梳理老项目的接口就花了一周&#xff0c;问一圈没人能说…

作者头像 李华
网站建设 2026/10/14 4:33:19

SQL Server维护计划实现管家婆单机版数据库自动备份

用了多年管家婆&#xff0c;最怕听到的一句话就是&#xff1a;“账套打不开了&#xff0c;能帮我看下吗&#xff1f;”尤其是单机版&#xff0c;所有数据都存放在本地电脑的SQL Server数据库里&#xff0c;硬盘一旦坏、系统一旦中毒重装、误删了数据文件夹&#xff0c;没有备份…

作者头像 李华
网站建设 2026/10/14 4:33:08

格雷厄姆企业价值计算法:三种估值公式与安全边际实操指南

聊到企业价值计算&#xff0c;很多人的第一反应是DCF模型里那一大摞假设表&#xff0c;我入行时却在格雷厄姆的方法上开了窍。本杰明格雷厄姆的企业价值计算方法&#xff0c;核心就是三套相对粗糙但特别抗干扰的算式&#xff1a;用每股收益和增长预期算合理价值&#xff0c;用每…

作者头像 李华
网站建设 2026/10/14 4:33:02

Power Pivot同比环比总算错?日期维度表才是时间智能的基石

做数据分析的人&#xff0c;十个里有九个在 Excel Power Pivot 里写过同比环比&#xff0c;写完之后又有大半被结果搞到怀疑人生。公式明明能跑&#xff0c;销售额合计也没问题&#xff0c;可同比环比一出来&#xff0c;要么是空值&#xff0c;要么是翻了好几倍的离谱数字&…

作者头像 李华