本文介绍如何使用 Docker Compose 部署 SearXNG,并将它接入 OpenClaw 的 web_search 工具,为大模型提供实时互联网搜索能力。

一、为什么需要 SearXNG

大模型本身并不能直接访问互联网。要回答新闻、实时价格、最新技术资料等问题,需要额外接入搜索服务。

OpenClaw 中的 web_search 工具就是负责搜索的 Agent Tool,但它不会自己维护搜索索引,而是调用一个外部 HTTP 搜索接口。

当前 Java 实现通过环境变量读取搜索服务地址:

OPENCLAW_SEARCH_ENDPOINT

SearXNG 正好提供了兼容的 JSON 搜索接口,因此可以作为 OpenClaw 的搜索后端。

整体调用链如下:

用户问题
    ↓
大模型决定调用 web_search
    ↓
OpenClaw WebSearchTool
    ↓
SearXNG /search 接口
    ↓
多个搜索源
    ↓
SearXNG 返回 JSON
    ↓
OpenClaw 整理搜索结果
    ↓
大模型生成最终答案

二、SearXNG 是什么

SearXNG 是一个开源的元搜索引擎。它通常不自己建立完整的网页索引,而是把查询转发到多个搜索源,再将结果统一汇总。

它具有以下特点:

  • 开源免费;
  • 支持自行部署;
  • 可以聚合多个搜索引擎;
  • 支持 HTML、JSON 等返回格式;
  • 不依赖某一个商业搜索 API;
  • 可以部署在本机、局域网或云服务器中。

需要注意,SearXNG 软件本身免费,但底层搜索源可能存在访问频率限制、验证码或网络限制。

三、项目中的 Docker 目录

当前工程已经规划了独立的 Docker 目录:

docker/
├── README.md
└── compose/
    └── searxng/
        ├── README.md
        ├── docker-compose.yml
        └── searxng/
            └── settings.yml

其中:

  • docker-compose.yml:SearXNG 容器启动配置;
  • searxng/settings.yml:SearXNG 服务配置;
  • openclaw-searxng-cache:Docker named volume,用于保存缓存;
  • README.md:启停和 API 调用说明。

当前没有额外的启动脚本,直接使用 Docker Compose 管理服务。

四、Docker Compose 配置

当前 Compose 使用官方镜像:

services:
  searxng:
    image: searxng/searxng:latest
    container_name: openclaw-searxng
    restart: unless-stopped
    ports:
      - "127.0.0.1:${SEARXNG_PORT:-8078}:8080"
    environment:
      SEARXNG_BASE_URL: http://${SEARXNG_HOSTNAME:-localhost}:${SEARXNG_PORT:-8078}/
    volumes:
      - ./searxng:/etc/searxng:rw
      - searxng-cache:/var/cache/searxng

volumes:
  searxng-cache:
    name: openclaw-searxng-cache

这里有一个容易混淆的地方:

宿主机端口:8078
容器内部端口:8080

因此浏览器访问宿主机的 8078,而容器内部的 SearXNG 仍然监听 8080。

当前端口只绑定到 127.0.0.1,不会直接暴露给局域网中的其他机器。

五、启动 SearXNG

进入 Compose 文件所在目录:

cd docker/compose/searxng

启动容器:

docker compose up -d

第一次启动时,Docker 会自动拉取:

searxng/searxng:latest

查看容器状态:

docker compose ps

查看实时日志:

docker compose logs -f searxng

如果容器状态为 running,并且没有持续报错,说明服务已经启动。

六、停止和维护服务

停止并删除容器,但保留缓存数据:

docker compose down

重新创建容器:

docker compose up -d --force-recreate

拉取最新镜像:

docker compose pull

删除容器和 named volume:

docker compose down -v

down -v 会删除 openclaw-searxng-cache,通常只在需要清理缓存或重新初始化时使用。

七、访问 SearXNG 页面

启动成功后,浏览器访问:

http://127.0.0.1:8078

如果可以打开 SearXNG 页面,说明端口映射和 Web 服务正常。

八、调用 JSON 搜索 API

SearXNG 的搜索接口是:

http://127.0.0.1:8078/search?q=Java&format=json

PowerShell 测试:

Invoke-WebRequest 'http://127.0.0.1:8078/search?q=Java&format=json' | Select-Object -ExpandProperty Content

Linux/macOS 测试:

curl "http://127.0.0.1:8078/search?q=Java&format=json"

正常情况下返回内容类似:

{
  "query": "Java",
  "results": [
    {
      "title": "Java News",
      "url": "https://example.com/java",
      "content": "Java search result summary"
    }
  ]
}

OpenClaw 当前重点使用 results 数组中的字段:

字段用途
title搜索结果标题
url搜索结果链接
content搜索结果摘要

九、OpenClaw 的 web_search 实现

当前代码位于 WebSearchTool.java。

工具执行时会读取:

String searchEndpoint = System.getenv("OPENCLAW_SEARCH_ENDPOINT");
String searchApiKey = System.getenv("OPENCLAW_SEARCH_API_KEY");

然后构造请求:

String encodedQuery = URLEncoder.encode(query, StandardCharsets.UTF_8);
String url = searchEndpoint
        + "?q=" + encodedQuery
        + "&format=json&pageno=1";

因此,OpenClaw 中应该只配置接口基础地址:

http://127.0.0.1:8078/search

不要把完整的 q 参数写入环境变量,因为 Java 代码还会自动追加查询参数。

十、配置 OpenClaw

当前 Java 代码通过 System.getenv() 读取环境变量,因此需要在启动 Java 服务的 PowerShell 中设置:

$env:OPENCLAW_SEARCH_ENDPOINT = 'http://127.0.0.1:8078/search'

然后重新启动 OpenClaw Java 服务。

如果 Java 服务已经启动,后设置环境变量不会影响已经运行的 JVM。

也可以在 Windows 用户环境变量中永久添加:

OPENCLAW_SEARCH_ENDPOINT=http://127.0.0.1:8078/search

十一、容器网络场景

如果 OpenClaw Java 运行在 Windows 宿主机,而 SearXNG 运行在 Docker 中,使用:

http://127.0.0.1:8078/search

如果 OpenClaw Java 也运行在同一个 Docker Compose 网络中,则使用容器服务名和容器端口:

http://searxng:8080/search

这是因为容器内部访问 127.0.0.1 时,指向的是当前容器自己,而不是另一个容器。

十二、OpenClaw 工具调用流程

当用户输入:

搜索今天的 Java 新闻,并总结前三条

大模型可能产生如下工具调用:

{
  "name": "web_search",
  "arguments": {
    "query": "今天的 Java 新闻",
    "max_results": 3
  }
}

随后 OpenClaw 执行:

AgentRunner
    → 根据工具名查找 web_search
    → WebSearchTool.execute()
    → 读取 OPENCLAW_SEARCH_ENDPOINT
    → 请求 SearXNG
    → 解析 results
    → 返回 ToolResult

返回结果会被追加到对话消息中,再发送给大模型。模型根据搜索结果生成最终回答。

十三、为什么之前会提示“Web search 工具未配置”

如果出现:

Web search is not configured

通常不是工具没有注册,而是 Java 进程没有读取到:

OPENCLAW_SEARCH_ENDPOINT

需要重点检查:

  1. 环境变量名称是否拼写正确;
  2. 是否在启动 Java 的同一个终端中设置;
  3. 设置环境变量后是否重启 Java 服务;
  4. SearXNG 是否已经启动;
  5. 8078 端口是否可以访问;
  6. /search?q=Java&format=json 是否能返回 JSON。

十四、常见问题排查

1. 端口被占用

检查端口:

Get-NetTCPConnection -LocalPort 8078 -State Listen

如果端口已占用,可以在 Compose 同级目录创建 .env:

SEARXNG_HOSTNAME=localhost
SEARXNG_PORT=8079

然后重新启动容器,并将 OpenClaw 地址改为:

http://127.0.0.1:8079/search

2. 页面能打开,但 JSON 没有结果

检查 URL 是否包含:

format=json

正确示例:

http://127.0.0.1:8078/search?q=Java&format=json

还要检查 SearXNG 的搜索源是否可用。

3. OpenClaw 仍然提示未配置

在启动 Java 服务的 PowerShell 中检查:

$env:OPENCLAW_SEARCH_ENDPOINT

如果没有输出地址,说明当前终端没有配置环境变量。

4. 搜索请求超时

当前 web_search 的 HTTP 连接和请求超时都是 15 秒。网络不稳定或底层搜索源响应缓慢时,可能返回搜索失败。

5. 不能直接使用模型 Provider 地址

下面这个地址是模型接口,不是搜索接口:

http://xxxxxxxxx:4000/v1

不能把它配置为 OPENCLAW_SEARCH_ENDPOINT。

十五、生产环境建议

开发环境可以使用:

searxng/searxng:latest

生产环境建议:

  • 固定经过验证的镜像版本或 digest;
  • 替换 settings.yml 中的默认 secret_key;
  • 限制 SearXNG 的网络访问范围;
  • 增加反向代理和鉴权;
  • 限制搜索请求频率;
  • 增加搜索结果缓存;
  • 监控搜索源错误率;
  • 不要将完整搜索参数和隐私内容写入日志。

十六、总结

SearXNG 在 OpenClaw 中扮演的是“外部搜索后端”的角色:

SearXNG:负责搜索互联网
OpenClaw:负责封装成 Agent Tool
大模型:负责决定何时搜索并理解搜索结果

当前本地部署的关键配置是:

镜像:searxng/searxng:latest
宿主机端口:8078
容器端口:8080
搜索接口:http://127.0.0.1:8078/search
OpenClaw 环境变量:OPENCLAW_SEARCH_ENDPOINT

当 SearXNG 正常启动,并且 OpenClaw Java 服务能够读取 OPENCLAW_SEARCH_ENDPOINT 后,模型就可以通过 web_search 获取实时互联网搜索结果。

更多推荐