Skip to content

指南

基于 Tavily / Exa / SearXNG / Serper / SerpAPI / Brave Search 官方文档(2026 年)编写

速查

  • 选型核心问题:要 LLM 答案?要原始 SERP?要语义?要自部署?
  • Tavily 适合 RAG:include_answer + chunks_per_source
  • Exa 适合语义:type=neural 找到关键词不匹配的相关内容
  • Serper 适合 Google SERP:便宜($0.3/1k)、快(1-2s)
  • Brave 适合独立索引:不依赖 Google
  • SearXNG 适合自部署/隐私/大陆:开源免费
  • Agent 多步:每步用 tool 调用 search,结果回填 LLM
  • 性能:缓存 + 批量 + 选对 search_depth

选型决策树

需求?

├─ 要 LLM 生成的答案摘要?
│     └ ✅ Tavily(include_answer=true)

├─ 要语义搜索(关键词不命中也能找到)?
│     └ ✅ Exa(type=neural)

├─ 要原始 Google SERP(organic + knowledge graph)?
│     ├ 极致便宜 → Serper($0.3/1k)
│     └ 多引擎 + dashboard → SerpAPI

├─ 不依赖 Google / 要独立索引?
│     └ ✅ Brave Search API

├─ 大陆可达 / 隐私 / 自部署 / 免费?
│     └ ✅ SearXNG

└─ 学术研究 / 长文综合?
      └ Exa(type=deep)或 Tavily(advanced + max_results=20)

RAG 索引实战

Tavily 收集语料

python
from tavily import TavilyClient
tavily = TavilyClient(api_key="tvly-xxx")

def collect_corpus(topic: str, n: int = 20) -> list[dict]:
    response = tavily.search(
        query=topic,
        search_depth="advanced",      # 多片段
        max_results=n,
        chunks_per_source=3,           # 每个 URL 3 个片段
        include_answer=False,          # RAG 自己生成,不要 Tavily 答案
        include_raw_content=True,      # 含全文
    )
    return response["results"]

docs = collect_corpus("RAG architecture best practices")
# 每个 doc: { title, url, content, raw_content, score }

Exa 神经检索

python
from exa_py import Exa
exa = Exa(api_key="exa-xxx")

def semantic_search(query: str) -> list:
    response = exa.search_and_contents(
        query,
        type="neural",
        num_results=10,
        use_autoprompt=True,           # 自动加 prompt 优化
        text=True,
        highlights={"numSentences": 5},
    )
    return response.results

use_autoprompt=true 让 Exa 自动给 query 加引导词(如「This page is about...」),提升神经检索质量。

索引到向量库

python
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings
import chromadb

splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
embeddings = OpenAIEmbeddings()
client = chromadb.PersistentClient()
collection = client.get_or_create_collection("knowledge")

for doc in docs:
    chunks = splitter.split_text(doc["content"])
    vectors = embeddings.embed_documents(chunks)
    collection.add(
        documents=chunks,
        embeddings=vectors,
        metadatas=[{"url": doc["url"], "title": doc["title"]}] * len(chunks),
        ids=[f"{doc['url']}-{i}" for i in range(len(chunks))],
    )

Agent 多步搜索

python
from langchain_openai import ChatOpenAI
from langchain_core.tools import tool

llm = ChatOpenAI(model="gpt-5")

@tool
def tavily_search(query: str) -> str:
    """搜索网页获取最新信息"""
    r = tavily.search(query=query, include_answer=True, max_results=5)
    return r["answer"] + "\n\nSources:\n" + "\n".join(
        f"- {x['title']}: {x['url']}" for x in r["results"]
    )

@tool
def fetch_url(url: str) -> str:
    """抓取 URL 全文"""
    import httpx
    return httpx.get(url, timeout=30).text[:5000]

llm_with_tools = llm.bind_tools([tavily_search, fetch_url])

response = llm_with_tools.invoke(
    "统计 GitHub 上 TypeScript 仓库 star 数最多的前 3 个组织,附上链接"
)
# 模型会自动多步:搜索 → 抓取 → 比较 → 汇总

性能调优

缓存

python
import hashlib, redis
r = redis.Redis()

async def cached_search(query: str):
    key = f"search:{hashlib.sha256(query.encode()).hexdigest()}"
    cached = r.get(key)
    if cached:
        return json.loads(cached)

    result = tavily.search(query=query, ...)
    r.setex(key, 3600, json.dumps(result))  # 缓存 1 小时
    return result

search_depth 选择

场景推荐 depth
Chat 实时回答(用户在等)basicfast
RAG 索引(异步、要质量)advanced
学术研究advanced + max_results=20
简单事实查询basic

并发

python
import asyncio

async def batch_search(queries: list[str]):
    sem = asyncio.Semaphore(5)  # 限制并发 5
    async def one(q):
        async with sem:
            return await tavily_async_search(q)
    return await asyncio.gather(*[one(q) for q in queries])

SearXNG 进阶

配置 engines

yaml
# settings.yml
search:
  safe_search: 0
  autocomplete: ""
  default_lang: "zh-CN"
  formats:
    - html
    - json

engines:
  - name: google
    engine: google
    shortcut: g
    disabled: false
  - name: bing
    engine: bing
    shortcut: b
  - name: duckduckgo
    engine: duckduckgo
  - name: wikipedia
    engine: wikipedia
  - name: github
    engine: github

防爬

  • 用 limiter_plugins 限速
  • 配置 outgoing proxy
  • 定期更新(引擎 CSS 选择器变化)

生产部署

yaml
services:
  searxng:
    image: searxng/searxng:latest
    restart: always
    ports: ["8080:8080"]
    environment:
      - SEARXNG_BASE_URL=https://search.my.com/
      - UWSGI_WORKERS=4
    volumes:
      - ./searxng:/etc/searxng:rw
  # 加 Redis 缓存
  redis:
    image: redis:alpine
    command: redis-server --save 30 1 --loglevel warning

多 API 组合策略

python
class HybridSearch:
    def __init__(self):
        self.tavily = TavilyClient(...)
        self.exa = Exa(...)
        self.serper_key = "..."

    async def search(self, query: str):
        # 1. 语义搜索(Exa)—— 找概念相关
        semantic = self.exa.search(query, type="neural", num_results=5)

        # 2. 关键词(Serper)—— 找精确命中
        keyword = self.serper_search(query, num=5)

        # 3. 去重 + 重排
        seen = set()
        merged = []
        for r in semantic.results + keyword["organic"]:
            if r.url not in seen:
                seen.add(r.url)
                merged.append(r)

        return merged[:10]

常见陷阱

陷阱解决
Tavily answer 不准改 include_answer=advanced 或不用 answer 自己 LLM 生成
Exa neural 慢改 type=auto 或 fast
Serper 返回空gl/hl 配错,或 Google 该地区无结果
SearXNG 某引擎失败上游反爬,禁用该引擎或加代理
RAG 语料质量差用 Tavily advanced + 高 score 阈值过滤
成本爆炸加缓存 + 仅对热门 query 调用
数据延迟实时新闻用 topic=news,不依赖通用索引
中文搜索质量差Serper 配 hl=zh-CN / Tavily 配 region

价格速查(2026)

服务价格免费 tier
Tavilybasic 1 credit / advanced 2 credit1000 credits/月
Exa按 token + 请求数1000 searches/月
Serper$0.30/1k queries2500 次
SerpAPI$50/月起 5000 次100 次/月
Brave Search$0.003/查询 起2000 次/月
SearXNG免费(自部署)无限

版本里程碑

时间主要变化
2023Serper/SerpAPI 成熟;Tavily 发布(专为 LLM)
2024Exa 神经搜索;Brave Search API GA;SearXNG 稳定
2025Tavily finance topic;Exa deep/deep-reasoning;多模态搜索兴起
2026AI 搜索 API 成为 RAG/Agent 标配;Tavily/Exa 与 LangChain 深度集成