
自托管 AI 知识库与联网搜索全套方案SearXNG mcp-searxng Infinity R2R pgvector目标用 4 个开源组件 1 个 MCP 桥接服务在本地搭一套完全自托管的「向量知识库RAG 隐私联网搜索」基础设施供 Claude、OpenCode、Cursor 等 AI 客户端调用。一、方案总览1.1 组件与镜像组件镜像作用SearXNGsearxng/searxng:latest自托管元搜索引擎聚合 Google/Bing/DuckDuckGo 等结果不追踪用户mcp-searxngisokoliuk/mcp-searxng:latest或 npx 本地运行MCP 协议桥把 SearXNG 的搜索能力暴露给 AI 客户端Claude Desktop/Code、Cursor、OpenCode 等Infinitymichaelf34/infinity:0.0.77-cpu高吞吐 Embedding/Rerank 推理服务提供 OpenAI 兼容的/embeddings接口CPU 版无需显卡R2R (RAG to Riches)sciphiai/r2r:3.6.6-amd64生产级 RAG 服务文档解析、切片、向量化入库、混合检索、RAG APIpgvectorpgvector/pgvector:pg16内置 pgvector 扩展的 PostgreSQL 16作为向量数据库持久层1.2 架构图┌──────────────────────────────┐ │ AI 客户端Claude/OpenCode│ └──────┬───────────────┬───────┘ MCP 协议 │ │ HTTP API ▼ ▼ ┌─────────────────┐ ┌──────────────────┐ │ mcp-searxng │ │ R2R :7272 │◄── 你自己的应用 │ 搜索工具桥 │ │ RAG 服务 │ (/v1/retrieval 等) └────────┬────────┘ └───────┬──────────┘ │ HTTP JSON │ 调用 embedding ▼ ▼ ┌─────────────────┐ ┌──────────────────┐ │ SearXNG :8080 │ │ Infinity :7997 │ │ 元搜索 │ │ bge-m3 向量模型 │ └────────┬────────┘ └──────────────────┘ │ 抓取各搜索引擎 │ 向量读写 ▼ ▼ Google/Bing/... ┌──────────────────┐ │ pgvector (PG16) │ │ 5432 向量存储 │ └──────────────────┘两条能力线相互独立又互补联网搜索线客户端 → mcp-searxng → SearXNG → 各大搜索引擎。解决「模型不知道最新信息」的问题。私有知识线文档 → R2R → Infinity 向量化 → pgvector 存储 → 检索问答。解决「模型不知道你的私有资料」的问题。1.3 为什么选这套组合全部可自托管搜索记录不出内网Embedding 在本地 CPU 跑不依赖 OpenAI。版本都经过社区验证Infinity 0.0.77 与 R2R 3.6.x 是各自项目稳定期版本镜像多架构齐全。标准协议对接MCP 是 AI 工具生态事实标准Infinity 和 R2R 都讲 OpenAI 兼容 HTTP替换任何一个组件都不影响整体。二、环境准备要求说明Docker ≥ 24 Compose v2所有服务容器化部署内存 ≥ 8GBInfinity 加载 bge-m3 约占 2~3GBR2R 约占 1GB磁盘 ≥ 20GB含模型权重bge-m3 约 2GB、Postgres 数据可访问 HuggingFace首次启动拉取模型国内建议配HF_ENDPOINThttps://hf-mirror.com目录结构约定/opt/ai-stack/ ├── docker-compose.yml ├── .env # 密码、密钥等敏感配置 ├── searxng/ │ ├── settings.yml # SearXNG 主配置 │ └── limiter.toml ├── r2r/ │ └── r2r.toml # R2R 配置指向 infinity pgvector └── pgdata/ # PG 数据卷三、逐个部署3.1 pgvectorPostgreSQL 16 向量扩展pgvector/pgvector:pg16就是官方 PostgreSQL 16 镜像加了 pgvector 扩展用法与普通 PG 完全一致postgres: image: pgvector/pgvector:pg16 restart: unless-stopped environment: POSTGRES_USER: ${POSTGRES_USER:-r2r} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?set in .env} POSTGRES_DB: ${POSTGRES_DB:-r2r} volumes: - ./pgdata:/var/lib/postgresql/data healthcheck: test: [CMD-SHELL, pg_isready -U ${POSTGRES_USER:-r2r}] interval: 10s timeout: 5s retries: 5验证扩展可用R2R 会自动建表但可以手动确认扩展存在docker compose exec postgres psql -U r2r -c CREATE EXTENSION IF NOT EXISTS vector; docker compose exec postgres psql -U r2r -c SELECT extname, extversion FROM pg_extension WHERE extnamevector;注意pgvector 的索引HNSW/IVFFlat和查询参数由 R2R 自动管理一般不需要手工建表。向量维度必须与 Embedding 模型输出一致——本文用 bge-m31024 维中途换模型必须重建集合并重新入库。3.2 InfinityCPU 版 Embedding 服务选BAAI/bge-m3多语言中英效果好、1024 维、支持长文本8192 tokens是中文知识库的主力选择。compose 片段infinity: image: michaelf34/infinity:0.0.77-cpu restart: unless-stopped environment: HF_ENDPOINT: ${HF_ENDPOINT:-} # 国内镜像加速如 https://hf-mirror.com command: v2 --model-id BAAI/bge-m3 --served-model-name bge-m3 --port 7997 --batch-size 16 volumes: - ./infinity-cache:/app/.cache # 缓存模型权重重启不用重新下载 ports: - 127.0.0.1:7997:7997 # 只暴露给本机/容器网络验证OpenAI 兼容接口curl http://127.0.0.1:7997/embeddings \ -H Content-Type: application/json \ -d {model:bge-m3,input:[你好世界]} # 返回 JSON 中 data[0].embedding 应为长度 1024 的数组要点说明0.0.77版本起命令行入口为v2子命令所有参数也可用INFINITY_前缀环境变量代替如INFINITY_MODEL_IDBAAI/bge-m3;。-cpu镜像内置 ONNX/CPU 优化无 NVIDIA 显卡时的最佳选择有卡请换默认镜像并加--gpus all。还可以再挂一个 rerank 模型如--model-id BAAI/bge-reranker-base供 R2R 重排用按需增加。首次启动要下载约 2GB 权重耐心等待日志出现Uvicorn running再测接口。3.3 R2RRAG 编排服务R2R 负责最重的活文档摄取PDF/DOCX/HTML/MD、语义切块、调 Infinity 向量化、写入 pgvector、提供检索与 RAG 问答 API。r2r/r2r.toml关键配置把 embedding 指到本地 Infinity把存储指到本地 pgvector[completion] # 生成模型仍需要一个 LLM 提供方provider 用 litellm 时模型名要带 openai/ 前缀 provider litellm concurrent_request_limit 16 [completion.generation_config] model openai/gpt-4o-mini # 也可以指向任意 OpenAI 兼容的本地大模型 temperature 0.1 max_tokens_to_sample 1024 stream true [embedding] provider openai # 走 OpenAI 兼容协议 → 即本地 Infinity base_model bge-m3 # 对应 --served-model-name [database] provider pgvector配套环境变量写入.env或 compose 的environment# 让 R2R 的 openai/litellm 客户端打到本地 Infinity OPENAI_API_BASEhttp://infinity:7997/v1 OPENAI_API_KEYempty # Infinity 不校验占位即可 # pgvector 连接 POSTGRES_HOSTpostgres POSTGRES_PORT5432 POSTGRES_USERr2r POSTGRES_PASSWORDyour-strong-password POSTGRES_DBr2r提示不同小版本的 toml 字段名偶有调整以上结构以 R2R GitHub 仓库 v3.6.x 的示例配置为准冲突时以官方模板为准。compose 片段r2r: image: sciphiai/r2r:3.6.6-amd64 restart: unless-stopped depends_on: postgres: condition: service_healthy infinity: condition: service_started environment: OPENAI_API_BASE: http://infinity:7997/v1 OPENAI_API_KEY: empty POSTGRES_HOST: postgres POSTGRES_PORT: 5432 POSTGRES_USER: ${POSTGRES_USER:-r2r} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_DB: ${POSTGRES_DB:-r2r} volumes: - ./r2r/r2r.toml:/app/config/r2r.toml - ./r2r/data:/app/data ports: - 7272:7272 # R2R API常用操作# 上传文档建立知识库会自动切片→Infinity向量化→入pgvector curl -X POST http://127.0.0.1:7272/v1/documents \ -F file./manual.pdf # RAG 问答检索 LLM 生成 curl -X POST http://127.0.0.1:7272/v1/retrieval/rag \ -H Content-Type: application/json \ -d {query:设备保修政策是什么}排错速查现象原因与处理R2R 启动即退出pgvector 未就绪或密码不对看docker logs r2r入库报维度不匹配换过 Embedding 模型删掉对应 collection 重新入库入库很慢Infinity 首次下载模型中CPU 下 bge-m3 吞吐有限属正常可调大--batch-size3.4 SearXNG隐私元搜索SearXNG 必须开启 JSON 输出格式否则 mcp-searxng 拿不到数据最常见的坑。searxng/settings.yml最小可用配置use_default_settings: true server: secret_key: change-me-to-random-string # openssl rand -hex 32 生成 limiter: false # 仅本机/内网使用时可关 image_proxy: true search: safe_search: 0 formats: # ← 关键默认没有 json - html - json engines: - name: google disabled: false - name: bing disabled: false - name: duckduckgo disabled: falsecompose 片段SearXNG 官方推荐 Redis 做缓存redis: image: valkey/valkey:8-alpine restart: unless-stopped command: valkey-server --save 30 1 --loglevel warning searxng: image: searxng/searxng:latest restart: unless-stopped depends_on: - redis environment: SEARXNG_BASE_URL: http://127.0.0.1:8080/ volumes: - ./searxng/settings.yml:/etc/searxng/settings.yml:ro ports: - 8080:8080验证 JSON APIcurl http://127.0.0.1:8080/search?qdockersearxngformatjson # 返回 results 数组即成功返回 403 说明 formats 里没开 json3.5 mcp-searxng给 AI 客户端装上搜索mcp-searxng 不是 SearXNG 插件而是独立的 MCP ServerNode.js 进程唯一必填变量是SEARXNG_URL。它通常跑在客户端一侧STDIO 模式不必进 compose。Claude Code 注册用户级claude mcp add --scope user --env SEARXNG_URLhttp://127.0.0.1:8080 --transport stdio searxng -- npx -y mcp-searxngClaude Desktop / Cursor / OpenCode 等JSON 配置{ mcpServers: { searxng: { command: npx, args: [-y, mcp-searxng], env: { SEARXNG_URL: http://127.0.0.1:8080, SEARXNG_MAX_RESULTS: 10, SEARXNG_DEFAULT_LANGUAGE: zh-CN } } } }常用可选变量变量默认说明SEARXNG_URL必填SearXNG 地址支持分号分隔多实例做故障转移SEARXNG_FANOUTfalsetrue 时并行查询所有实例并合并去重SEARXNG_DEFAULT_LANGUAGEall默认搜索语言如 zh-CNSEARXNG_MAX_RESULTS10返回结果条数上限SEARXNG_TIMEOUT_MS10000单次搜索超时配置完成后在客户端里说一句搜一下 xxx能看到工具调用 SearXNG 即接入成功。四、完整 docker-compose.yml汇总services: postgres: image: pgvector/pgvector:pg16 restart: unless-stopped environment: POSTGRES_USER: ${POSTGRES_USER:-r2r} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:?set in .env} POSTGRES_DB: ${POSTGRES_DB:-r2r} volumes: - ./pgdata:/var/lib/postgresql/data healthcheck: test: [CMD-SHELL, pg_isready -U ${POSTGRES_USER:-r2r}] interval: 10s timeout: 5s retries: 5 infinity: image: michaelf34/infinity:0.0.77-cpu restart: unless-stopped environment: HF_ENDPOINT: ${HF_ENDPOINT:-} command: v2 --model-id BAAI/bge-m3 --served-model-name bge-m3 --port 7997 --batch-size 16 volumes: - ./infinity-cache:/app/.cache ports: - 127.0.0.1:7997:7997 r2r: image: sciphiai/r2r:3.6.6-amd64 restart: unless-stopped depends_on: postgres: condition: service_healthy environment: OPENAI_API_BASE: http://infinity:7997/v1 OPENAI_API_KEY: empty POSTGRES_HOST: postgres POSTGRES_PORT: 5432 POSTGRES_USER: ${POSTGRES_USER:-r2r} POSTGRES_PASSWORD: ${POSTGRES_PASSWORD} POSTGRES_DB: ${POSTGRES_DB:-r2r} volumes: - ./r2r/r2r.toml:/app/config/r2r.toml - ./r2r/data:/app/data ports: - 7272:7272 redis: image: valkey/valkey:8-alpine restart: unless-stopped command: valkey-server --save 30 1 --loglevel warning searxng: image: searxng/searxng:latest restart: unless-stopped depends_on: - redis environment: SEARXNG_BASE_URL: http://127.0.0.1:8080/ volumes: - ./searxng/settings.yml:/etc/searxng/settings.yml:ro ports: - 8080:8080.env示例POSTGRES_USERr2r POSTGRES_PASSWORDplease-change-me POSTGRES_DBr2r HF_ENDPOINThttps://hf-mirror.com一键启停docker compose up -d docker compose ps # 全部 healthy/running 即就绪 docker compose logs -f infinity # 观察模型加载五、验收清单#验证项命令预期1pgvector 扩展psql -U r2r -c CREATE EXTENSION IF NOT EXISTS vector;无报错2Embedding 服务curl 127.0.0.1:7997/embeddings ...返回 1024 维向量3RAG 入库问答POST/v1/documents后 POST/v1/retrieval/rag能引用上传文档作答4搜索 JSON APIcurl .../search?qtestformatjson返回 results 数组5MCP 搜索AI 客户端内发起一次搜索工具调用成功返回网页摘要六、安全与运维建议不要把端口裸奔公网SearXNG/R2R/Infinity/PG 只绑127.0.0.1或走反向代理加认证mcp-searxng 若以 HTTP 模式对外务必设置MCP_HTTP_AUTH_TOKEN并启用 hardened 模式。密钥管理settings.yml的secret_key、.env里的数据库密码都要换掉示例值csdcn.env类凭据文件不要进 git。备份定期备份pgdata/目录或用pg_dump向量库重建成本高。升级策略Infinity 与 R2R 升级可能改变向量维度或表结构升级前备份升级后先跑第五节验收清单。