AI Agent 总把外部搜索交给第三方?Sifthound 用自托管 API 接回数据边界
AI Agent 一旦需要查网页,通常会把搜索、页面抽取和抓取交给托管 API。接入很快,但团队也随之接受了第三方密钥、请求配额和数据边界。尤其是内部 Agent,搜索目标、抓取 URL 以及返回内容都可能成为外部服务的可见输入。
Sifthound 是一个 MIT 许可的开源 Python 服务,定位是可自托管的 Tavily 兼容搜索 API。它用 SearXNG 提供搜索,用 trafilatura 抽取页面内容,并通过 BM25 做相关性排序;已有 Tavily 客户端或 LangChain 集成,只需改变 API 基地址,就能把调用转到自己的服务器。
先看它解决什么问题
| 需求 | 传统托管搜索 | Sifthound |
|---|---|---|
| 搜索凭据 | 依赖供应商 API Key | 搜索本身不需要搜索 API Key |
| 数据边界 | 请求发往第三方 | 服务和结果由自己部署 |
| Agent 接入 | 需要适配供应商 API | 兼容 /search、/extract、/crawl、/map |
| MCP 使用 | 另配连接器 | 提供 HTTP 与 stdio MCP 服务 |
| 安全控制 | 依赖供应商策略 | 可配置 API Key、主机白名单和 SSRF 防护 |
这并不意味着 Sifthound 能完全复刻托管服务:它没有 Tavily 的 /research,相关性分数来自 BM25 而不是神经重排,也不负责 JavaScript 渲染页面。它更适合希望掌握基础设施、而不是追求“开箱即用托管体验”的团队。
三步跑起来
项目 README 提供了 Docker Compose、单容器和 pip 三种路径。最省事的方式是启动包含 SearXNG 的完整栈:
git clone https://github.com/khsarvar/sifthound && cd sifthound cp .env.example .env docker compose up
服务默认监听 8000 端口。最小搜索请求可以这样发出:
curl -s localhost:8000/search -H "Content-Type: application/json" \
-d '{"query":"latest python release","search_depth":"advanced"}'
如果只希望运行服务镜像,也可以使用 ghcr.io/khsarvar/sifthound;如果已有 SearXNG,则可安装 Python 包并设置 SEARXNG_URL。/extract、/crawl 和 /map 不依赖 SearXNG,但 /search 需要一个启用 JSON 输出的 SearXNG 实例。
兼容层的价值:不用重写 Agent
Sifthound 的实用价值不只是“又一个搜索服务”,而是把兼容层放在了 API 设计上。原有 Tavily 客户端可以把基地址改到本地:
from tavily import TavilyClient
client = TavilyClient(
api_key="local-key",
api_base_url="http://localhost:8000",
)
results = client.search(
"latest python release",
search_depth="advanced",
max_results=5,
)
pages = client.extract(
urls=["https://en.wikipedia.org/wiki/Okapi_BM25"]
)
LangChain 的 langchain-tavily 也可以采用同样的 api_base_url。这对已经把搜索封装在工具层的 Agent 很重要:迁移工作从“重写工具协议”变成“替换部署地址”,之后再根据实际结果调整排序和抓取策略。
MCP 场景:把搜索能力交给 Agent
Sifthound 暴露四个只读 MCP 工具:sifthound_search、sifthound_extract、sifthound_crawl 和 sifthound_map。远程客户端可以连接 HTTP 端点:
claude mcp add --transport http sifthound http://localhost:8000/mcp
也可以通过 stdio 在本机启动:
claude mcp add sifthound \ -e SEARXNG_URL=http://your-searxng:8080 \ -- uvx sifthound mcp
生产环境不要把密钥直接写进命令历史。设置 API_KEYS 后,使用环境变量或客户端的安全配置传递认证信息;如果把 MCP 暴露到非 localhost 地址,还要配置 MCP_ALLOWED_HOSTS,限制哪些主机名可以访问。
真正值得注意的是安全边界
搜索服务本身不等于安全服务。Sifthound 的 /extract 和 /crawl 会访问调用方提供的 URL,因此项目内置了 SSRF 防护:默认阻止私网、回环和链路本地地址,并在重定向以及实际连接时再次检查目标地址,降低 DNS rebinding 绕过的风险。
不过,部署者仍应设置 API_KEYS,在网络层限制出站访问,并谨慎启用 ALLOW_PRIVATE_NETWORKS。如果 Agent 能让用户输入任意 URL,建议额外设置抓取超时、并发数、最大响应体和爬取上限。安全检查只能减少风险,不能替代租户隔离和出口防火墙。
和托管服务怎么选
如果团队不想维护 SearXNG、抓取队列和升级流程,托管 Tavily 仍然更省心;如果需要 JavaScript 渲染或完整的网页抓取平台,Firecrawl 等方案更合适。Sifthound 的优势是 API 形状兼容、MIT 许可、可放在自己的网络里,并且把 MCP 接入也一并提供。
它适合三类场景:内部知识 Agent 需要可控的网页入口;开发环境希望不用共享供应商搜索 Key;已经使用 Tavily SDK、但想先在本地验证搜索和抽取流程的团队。先用 Docker Compose 跑通,再为 API Key、出站网络和抓取上限补齐生产配置,迁移成本会比较可控。
相关链接