SearXNG 是開源的元搜尋引擎,把 Google、Brave、DuckDuckGo 等 260 多個搜尋服務的結果彙整成一份、不追蹤使用者,自架後還能用 JSON API 免費當 AI Agent 的搜尋後端。
一句話講完價值:你付出的是自己的一台機器,換回來的是「不被人格化追蹤的搜尋結果」加上「一組打不完的搜尋 API」。對自架族群與在做 AI Agent 的人來說,第二個好處通常比第一個更實用。
為什麼要自架搜尋
| 痛點 | 現況 | 自架 SearXNG 後 |
|---|---|---|
| 廣告與追蹤 | Google/Bing 的結果頁塞滿追蹤與 AI 摘要 | 只回結果,沒有廣告位、不建 profile |
| 搜尋 API 費用 | Google Custom Search 每 1,000 次要收費,免費額度只有每天 100 次 | 自己的機器,愛打幾次打幾次 |
| 多引擎比價 | 想同時看 Google+Brave+DDG,得開三個分頁 | 一次查詢並行打多引擎,結果去重排序後合成一份 |
| AI Agent 需要搜尋 | Agent 要「查一下再說」,卻沒有合法便宜的搜尋來源 | GET /search?q=...&format=json 就是一個端點 |
| 鎖定單一供應商 | 換搜尋引擎等於改程式 | 引擎清單在 settings.yml,隨時增減 |
第三、四點是 2026 年新增的需求。現在幾乎每個 Agent 框架都會問你「用哪個搜尋 provider」,付費 API 一個月動輒幾十美元;SearXNG 讓你用一台 1 GB 的 VPS 換掉這筆支出。
一表看懂
| 項目 | 內容 |
|---|---|
| 專案 | searxng/searxng(Python,AGPL-3.0) |
| 社群規模 | GitHub 38,961 星、3,543 forks(2026-10-28 以 API 查詢) |
| 活躍度 | 當日仍有推送(2026-10-28 09:59 UTC) |
| 搜尋來源 | 官方自述「最多彙整 261 個搜尋服務」,預設設定檔內的引擎名稱定義 268 個(含同引擎的多語系變體) |
| 輸出格式 | html、json、csv、rss(後三者要在 settings.yml 手動開啟) |
| 分類 | general、images、videos、news、science、it、map、music、files |
| 部署方式 | Docker compose(官方推薦)、Docker run、bare metal |
| 資源實測 | 查詢服務約 126 MiB、快取用的 Valkey 約 6 MiB |
| 授權重點 | AGPL-3.0,修改後提供網路服務也要開源 |
它是怎麼運作的
SearXNG 自己不做索引。它是「代理型搜尋」:
| 步驟 | 發生什麼事 |
|---|---|
| 1 | 你送出一個查詢(瀏覽器或 API) |
| 2 | 依分類把查詢並行送給多個引擎(Google、Brave、DuckDuckGo、Docker Hub、GitHub…) |
| 3 | 各引擎回來後,把重複的 URL 合併、依分數排序 |
| 4 | 統一回傳一份結果,並附上每個結果「來自哪些引擎」 |
這個設計的副作用要記住:結果品質永遠不會超過來源引擎。它是聚合器,不是索引器;某個引擎被 CAPTCHA 擋掉時,那一路的結果就會缺。
安裝:官方 compose 三步
先用官方推薦的 compose 方式,三步就好。以下指令取自官方文件(docs.searxng.org/admin/installation-docker.html):
# 1) 建立目錄並下載官方 compose 樣板
mkdir -p ./searxng/core-config/
cd ./searxng/
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
# 2) 建立 .env(要改 port 就改這裡)
cp -i .env.example .env
nano .env
# 3) 起服務
docker compose up -d
官方 compose 內容長這樣(2026-10 版):
name: searxng
services:
core:
container_name: searxng-core
image: docker.io/searxng/searxng:${SEARXNG_VERSION:-latest}
restart: always
ports:
- ${SEARXNG_HOST:+${SEARXNG_HOST}:}${SEARXNG_PORT:-8080}:${SEARXNG_PORT:-8080}
env_file: ./.env
volumes:
- ./core-config/:/etc/searxng/:Z
- core-data:/var/cache/searxng/
valkey:
container_name: searxng-valkey
image: docker.io/valkey/valkey:9-alpine
command: valkey-server --save 300 1 --save 60 1000 --loglevel warning
restart: always
volumes:
core-data:
valkey-data:
第一個要注意的細節:這版 compose 的 port 對應是 ${SEARXNG_PORT}:${SEARXNG_PORT},host 與 container 用同一個值。舊教學常見的「左邊 8080、右邊 8080 固定」已經改了——你在 .env 設 SEARXNG_PORT=8888,兩邊會一起變成 8888,不會出現「對外 8888、內部 8080」的情況。
第二個細節:core-config/ 是空的也沒關係。容器第一次啟動時會自己生成一份最小 settings.yml,裡面已經填好一組隨機 secret_key 和 image_proxy: true:
use_default_settings: true
server:
secret_key: "EAHqnFamh9rM73SAr4R96nrH6mquUCx" # 自動生成,不要外流
image_proxy: true
實測啟動約 25 秒後 docker compose ps 就會看到兩個容器:
NAME IMAGE STATUS PORTS
searxng-core docker.io/searxng/searxng:latest Up 25 seconds 0.0.0.0:8888->8888/tcp
searxng-valkey docker.io/valkey/valkey:9-alpine Up 25 seconds 6379/tcp
打開 http://你的IP:8888 就能用了。到這裡為止,跟多數教學一樣順。
最多人卡住的一步:JSON API 直接 403
接下來要拿 API 給程式用。照文件打:
curl 'http://127.0.0.1:8888/search?q=searxng&format=json'
你會拿到 403 Forbidden,而且是 HTML 錯誤頁,不是 JSON。這不是裝壞了,是設計如此:可用格式由 settings.yml 的 search.formats 決定,預設只有 html。
實測結果:
| 請求 | 結果 |
|---|---|
format=json(預設設定) | 403 |
format=rss(預設設定) | 403 |
| 不帶 format(HTML 頁面) | 200,約 124 KB |
修法是把 core-config/settings.yml 改成這樣(保留容器自動生成的 secret_key):
# Read the documentation before extending the defaults:
# https://docs.searxng.org/admin/settings/
use_default_settings: true
general:
instance_name: "My SearXNG"
server:
secret_key: "把容器生成的那組貼回來"
base_url: "https://search.example.com/" # 有反向代理就要填對
limiter: false
public_instance: false
image_proxy: false
search:
safe_search: 0
formats:
- html
- json
改完重啟容器(docker compose restart core)再打一次,就會拿到 JSON:
{
"query": "searxng",
"results": [ { "url": "...", "title": "...", "content": "...", "engine": "google cse", "engines": ["google cse", "brave"], "score": 4.0, "category": "general", "publishedDate": null } ],
"answers": [],
"corrections": [],
"infoboxes": [],
"suggestions": [],
"unresponsive_engines": []
}
實測:中英文查詢的延遲與筆數
用上面這份設定(只有 html+json),在區網內打同一台機器:
| 查詢 | 參數 | 結果筆數 | 耗時 |
|---|---|---|---|
hugo static site generator | general | 36 | 1.09 s |
台灣 電動車 補助 | language=zh-TW | 39 | 0.98 s |
docker compose 教學 | language=zh-TW | 42 | 0.75 s |
postgres | categories=it | 112 | 2.10 s |
幾個觀察:
- 中文查詢沒問題,
language=zh-TW也能帶出中文結果(第一筆就是中文站)。 categories=it特別肥:會同時打 GitHub、Docker Hub、Stack Overflow、MDN、Hoogle、AskUbuntu 等,一次回來 112 筆,但因為打得多,時間也最久(2.1 秒)。number_of_results是null。SearXNG 不做總數估算,你只能算len(results)。任何「全網有 N 筆」的宣稱都不要做。
給 AI Agent 用:30 行 Python 就能接
不需要 SDK。標準 HTTP 介面,任何語言都能打。下面這支是實測跑過的版本:
import json, urllib.parse, urllib.request
BASE = "http://127.0.0.1:8888"
def search(q, categories="general", lang="zh-TW", pageno=1, timeout=25):
params = urllib.parse.urlencode({
"q": q,
"format": "json",
"categories": categories,
"language": lang,
"pageno": pageno,
})
req = urllib.request.Request(
BASE + "/search?" + params,
headers={"User-Agent": "my-agent/1.0"},
)
with urllib.request.urlopen(req, timeout=timeout) as r:
data = json.load(r)
return [
{
"title": x.get("title", ""),
"url": x.get("url", ""),
"snippet": (x.get("content") or "")[:160],
"engines": x.get("engines") or [x.get("engine")],
"score": round(x.get("score") or 0, 3),
}
for x in data.get("results", [])
]
if __name__ == "__main__":
for r in search("hugo 多語系 sitemap")[:3]:
print(r["title"], r["url"])
實測輸出(同一台機器):hugo 多語系 sitemap 回來 47 筆、0.83 秒;prometheus 告警規則(categories=it)回來 11 筆、0.67 秒。
寫 Agent 時最重要的一件事:SearXNG 的結果欄位很多(parsed_url、positions、priority、thumbnail、metadata…),全部塞進 context 只是浪費 token。務必像上面那樣只留 title、url、snippet 三欄,其他丟掉。
結果物件裡比較有用的欄位:
| 欄位 | 用途 |
|---|---|
url / title / content | 摘要與引用來源 |
engine / engines | 這個結果由哪些引擎命中(多引擎同時命中=可信度高) |
score | 排序分數,可當粗略的相關性指標 |
category | 屬於 general/it/news 哪一類 |
publishedDate | 新聞類才有值,其他多為 null |
unresponsive_engines | 這次哪些引擎掛掉(除錯用,別忽略) |
其他常用參數:pageno(換頁)、time_range=day|month|year(限時段,需引擎支援)、safesearch=0|1|2。POST 也支援,參數放 form data。
接到現有工具
因為它就是一個 HTTP 端點,接法比你想的簡單:
- 自寫 Agent/爬蟲:上面的 Python 客戶端就是最小可用版。
- AI 聊天平台(例如自架的 LibreChat、Open WebUI):多數支援「自訂搜尋後端」的概念,把
http://searxng:8080/search填進去即可;各家介面與參數差異大,實際欄位請照你用的版本設定,本文未逐一實測。 - n8n/排程腳本:一個 HTTP Request 節點,URL 帶
&format=json,取results[]。
對外開放前一定要做的四件事
只用在自己機器上,裝完就能用。但要給家人、團隊或 Agent 從公網打,就得處理:
- 開 limiter+Valkey:
server.limiter: true會限制請求頻率、擋部分機器人;它需要 Valkey,而官方 compose 已經幫你準備好了。對外開放卻不開 limiter,等於開一台免費代理給人刷。 - 設定
base_url:放在 nginx/Traefik/Caddy 後面時,base_url必須是你實際的網域(含https://),否則頁面內連結與搜尋表單會指回 localhost。 public_instance: true只在真的要公開時打開:它會啟用針對公開站的額外防護(例如 limiter 的 link_token)。只給自己用就別開。image_proxy想清楚:開著可以避免瀏覽器直接連外部圖床(少洩漏足跡),但會吃記憶體與流量。小機器建議關。
另外,如果你是拿 SearXNG 當「公開服務」而非自用,AGPL-3.0 的意思是:你修改了它的程式碼並透過網路提供服務,就必須把改過的原始碼釋出。只改 settings.yml 與部署設定不算修改程式碼。
五個真實限制
- 引擎會被抓、會掉:Google、Brave 對資料中心 IP 常有 CAPTCHA 或 429。實測中每次查詢都有 0~1 個引擎被標為 unresponsive,這是常態不是故障。自架時把機器放在乾淨 IP、或只留兩三個穩定引擎,結果反而更穩。
- 結果品質取決於來源:它不是索引器,無法給你「Google 沒有的東西」。想要更精準,得自己在
settings.yml調引擎權重或關掉愛亂回傳的引擎。 - 沒有版本號 release:SearXNG 走 rolling release(
master分支持續推送),沒有 GitHub Releases。要固定版本請用 image tag(例如searxng/searxng:2026.10.17-xxxx),不要永遠latest。 - JSON 沒有總數:
number_of_results一律null,做「搜到 N 筆」的 UI 要自己算。 - 公開實例多半關掉 JSON:這也是為什麼你隨便找一台公共 SearXNG 來當 API 通常會 403。要 API 就自己架。
誰適合、誰不需要
| 你是誰 | 建議 |
|---|---|
| 正在做 AI Agent/RAG,需要便宜的搜尋來源 | 非常適合,這是目前最省錢的合法路徑之一 |
| 在意搜尋被追蹤、又不滿意單一引擎結果 | 適合,順手就裝好了 |
| 只有一台 1 GB VPS、想多一個服務 | 適合,實測記憶體約 130 MiB |
| 需要大量即時新聞、在意「最新」排序 | 不適合,新聞類要另外接(categories=news 的品質看引擎) |
| 想做商業搜尋產品 | 先讀 AGPL,並確認你要接的引擎各自的服務條款 |
站內延伸閱讀
- Docker Compose 完整教學 2026:compose.yaml 到 AI models
- Traefik 完整教學 2026:Docker Labels 自動路由與自動 HTTPS
- LibreChat 完整教學 2026:自架 AI 聊天平台,整合 OpenAI/Claude/Gemini/Ollama
- CrowdSec 完整教學 2026:開源 IDS/IPS+WAF,把掃描器擋在門外
本文無商業合作、無聯盟連結。星數與活躍度以 GitHub API 於 2026-10-28 查詢為準;部署步驟、403 行為、API 回應欄位與延遲數字,皆在本機以官方 compose 樣板實際部署驗證。
