
本地 AI Agent 缺一个搜索入口SearXNG 自托管跑通后用 cpolar 给团队验收检索效果本地 Agent 做到一半经常会卡在同一个地方模型会推理工具也接上了但一需要查外部资料就开始依赖别人的搜索接口。如果只是个人 Demo临时拿一个在线搜索服务凑合也能跑。可一旦要给团队验收问题就来了搜索结果从哪里来、响应快不快、哪些搜索源稳定、接口会不会把内网东西暴露出去这些都要提前讲清楚。这篇就只做一件事把 SearXNG 自托管起来先在本地验证搜索质量和响应速度再用 cpolar 开一个临时 HTTPS 入口让同事远程验收检索效果。验收完关掉入口不做长期公网开放。1 什么是 SearXNG这篇里它负责什么SearXNG 是一个自托管的元搜索服务。简单说它自己不生产搜索结果而是把多个搜索源的结果聚合到一个页面和 API 里。在本地 AI Agent 场景里它适合当“可控搜索入口”页面端同事能直接输入关键词看搜索结果是不是符合预期API 端Agent 原型能请求/search拿到 JSON 结果运维端搜索源、输出格式、安全参数都放在自己的配置里排查时不需要猜。划重点本文不写 Open WebUI、Dify、RAG 工作流也不把 SearXNG 包装成万能知识库。它的角色很明确就是团队验收前的自托管搜索服务。2 环境准备Docker、目录和端口先定好这里用 Docker Compose 部署端口固定为8080。SearXNG 官方容器模板里核心服务默认监听8080旁边还会带一个 Valkey 服务用来支撑限流等能力。准备一台已经安装 Docker 的机器Linux、macOS、NAS 上的 Docker 环境都能照着做。本文命令默认在一个干净目录里执行mkdir -p ~/searxng-demo/core-config cd ~/searxng-demo拉取官方 Compose 模板和环境变量示例curl -fsSL \ -O https://raw.githubusercontent.com/searxng/searxng/master/container/docker-compose.yml \ -O https://raw.githubusercontent.com/searxng/searxng/master/container/.env.example cp -i .env.example .env把.env改成只监听本机地址避免一启动就暴露到整个局域网cat .env EOF SEARXNG_VERSIONlatest SEARXNG_HOST127.0.0.1 SEARXNG_PORT8080 EOF这里别把SEARXNG_HOST写成0.0.0.0。我们后面会用 cpolar 做临时 HTTPS 入口本机阶段只让127.0.0.1:8080能访问边界更清楚。3 配置 SearXNG安全参数和输出格式先补齐SearXNG 的配置文件放在core-config/settings.yml容器内对应/etc/searxng/settings.yml。官方文档建议用use_default_settings: true继承默认配置再覆盖自己关心的部分。先生成一个随机密钥python3 - PY import secrets print(secrets.token_urlsafe(48)) PY复制输出结果写入下面的secret_key。不要直接照抄示例里的密钥团队验收环境也要换成自己的值。cat core-config/settings.yml EOF use_default_settings: true server: secret_key: 把这里替换成刚才生成的随机密钥 limiter: true public_instance: false image_proxy: false method: POST default_http_headers: X-Content-Type-Options: nosniff X-Download-Options: noopen X-Robots-Tag: noindex, nofollow Referrer-Policy: no-referrer search: safe_search: 1 formats: - html - json valkey: url: valkey://valkey:6379/0 engines: - name: bing disabled: false - name: wikipedia disabled: false EOF这份配置只开html和json两种输出。html给同事页面验收json给 Agent 原型联调。public_instance: false保持私有实例口径limiter: true配合 Valkey 做请求限制X-Robots-Tag: noindex, nofollow明确告诉搜索引擎不要索引这个临时入口。这里还有一个小提醒不要把core-config目录映射成文件下载目录也不要把 Docker 宿主机上的项目目录挂进 SearXNG。SearXNG 只需要自己的配置和缓存没必要接触你的代码仓库、日志目录和密钥文件。4 启动服务先在本机跑通页面配置写好后启动容器docker compose up -d查看状态docker compose ps正常会看到searxng-core和searxng-valkey都是Up端口映射里有127.0.0.1:8080-8080/tcp。如果core反复重启先看日志不要急着改搜索源docker compose logs -f core本机打开页面open http://127.0.0.1:8080Linux 服务器没有桌面时用这条命令确认 HTTP 状态curl -I http://127.0.0.1:8080返回HTTP/1.1 200 OK或者同等的 200 状态就说明页面服务已经起来。图里适合放 SearXNG 首页。看到搜索框就够了这一步不是为了看界面漂不漂亮而是确认容器、配置文件、端口映射这三件事已经连起来。5 本地验证搜索质量、响应速度、搜索源可用性团队验收前自己先跑一轮。别拿敏感项目名、客户名称、内网域名去搜统一用公开关键词。我建议准备三类测试词工具类SearXNG Docker、Valkey Redis difference技术类Python async retry backoff、Docker compose healthcheck中文类本地搜索 服务 Docker、自托管 搜索 引擎页面端先搜一次SearXNG Docker。结果页出来后点右上角的“首选项”或页面里的偏好设置入口检查启用的搜索源。这里不要一口气全开先保留少量稳定搜索源后面排错轻松很多。API 端用 JSON 验证curl -sG http://127.0.0.1:8080/search \ --data-urlencode qSearXNG Docker \ --data-urlencode formatjson \ | python3 -c import sys,json; djson.load(sys.stdin); print(results, len(d.get(results, []))); [print(i1, r.get(title, ), r.get(engines, [])) for i,r in enumerate(d.get(results, [])[:5])]这条命令会打印结果数量、前 5 条标题和来源引擎。results大于 0说明 JSON 输出可用标题和关键词相关说明搜索质量过关来源引擎列表里有内容后面排查搜索源时有依据。再测响应时间curl -o /dev/null -s -w status%{http_code} time%{time_total}s\n -G \ http://127.0.0.1:8080/search \ --data-urlencode qDocker compose healthcheck \ --data-urlencode formatjson验收时不用追求毫秒级速度重点看三件事HTTP 状态是200单次搜索时间在团队能接受的范围内同一个关键词重复搜索不会频繁报错。如果结果为空优先检查search.formats里有没有json。如果页面能搜、API 返回 403基本就是 JSON 格式没有启用。要是页面和 API 都没有结果再看docker compose logs -f core里面会写出具体搜索源的错误。6 用 cpolar 开临时 HTTPS 入口给团队验收本机验证没问题后再给同事一个临时入口。这里用 cpolar 的目的很单纯短时间把127.0.0.1:8080映射成 HTTPS 地址让团队远程打开页面验收检索效果。如果机器还没安装 cpolar按系统选择一条即可。Linuxcurl -L https://www.cpolar.com/static/downloads/install-release-cpolar.sh | sudo bashmacOSbrew tap probezy/core brew install cpolar安装后需要登录账号并绑定 authtoken。已经登录过的机器直接确认本地控制台能打开curl -s http://127.0.0.1:9200 || echo cpolar 服务未启动开临时 HTTP 隧道cpolar http 8080终端输出里会出现https://开头的公网地址。把这个地址发给团队只用于打开 SearXNG 页面测试约定关键词和响应速度。这张图适合放 cpolar 终端输出或本地 Web UI 的在线隧道页面。截图里保留 HTTPS 地址和本地端口对应关系即可不要把账号信息、token、其他隧道列表截进去。验收话术可以直接这样写这是 SearXNG 临时验收入口 https://你的临时地址 请只测试下面关键词 1. SearXNG Docker 2. Python async retry backoff 3. 本地搜索 服务 Docker 验收点 - 页面是否能打开 - 搜索结果是否相关 - 单次搜索等待时间是否能接受 - 搜索源是否有明显不可用报错7 验收边界哪些东西不能开放临时入口最怕“顺手多开一点”。这次只开放 SearXNG 页面不开放 Docker、SSH、NAS 文件目录、代码仓库和任何管理员配置文件。边界按下面几条执行不把core-config/settings.yml、.env、日志目录放到 Web 可访问路径不给同事发送 cpolar 本地控制台9200地址不在测试关键词里放客户名、内部项目代号、内网域名不把临时 HTTPS 地址贴到公开群、论坛和文章评论区验收结束立刻关闭 cpolar 进程。关闭方式很简单运行cpolar http 8080的终端里按Ctrl C。如果你用的是 cpolar Web UI 或后台隧道验收结束后到http://127.0.0.1:9200停止对应隧道。再把 SearXNG 也停掉cd ~/searxng-demo docker compose down如果团队后续要长期使用建议重新走正式部署固定域名、访问控制、反向代理、日志策略、搜索源策略都要单独评审。不要把这次临时验收入口直接当生产入口。8 总结到这里我们已经把 SearXNG 跑成了一个可验收的本地搜索服务Docker Compose 负责启动核心容器和 Valkeysettings.yml负责安全参数、JSON 输出和基础搜索源本地命令负责验证搜索质量、响应速度和搜索源返回情况cpolar 负责提供短时间 HTTPS 入口。关键步骤就三块先把 SearXNG 绑定在127.0.0.1:8080本机确认页面和 JSON API 都能用再用公开关键词测试结果相关性、响应时间和搜索源可用性验收阶段只用 cpolar 临时开放页面结束后关闭隧道和容器。我个人更推荐把这套流程当成“团队验收模板”而不是一次性部署脚本。搜索入口看起来只是 Agent 的一个小组件但它直接影响后续答案来源、可追溯性和安全边界。先把 SearXNG 这层验收清楚后面再接 Agent、工作流或知识库排错会省很多时间。