Ctrl K
ComunidadGuías…

README.zh-CN.md

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
<div align="center">

# Agent Web Search

<!-- mcp-name: io.github.JerryLiu369/agent-web-search -->

**为 AI Agent 而生的原生联网搜索层 — 将模型原生 Grounding 与 Agent 专属搜索 API 统一于中立契约之下。**

[English](https://github.com/JerryLiu369/agent-web-search/blob/main/README.md) | **简体中文**

[![Python 3.10+](https://img.shields.io/badge/Python-3.10%2B-3776AB?logo=python&logoColor=white)](https://www.python.org/)
[![PyPI](https://img.shields.io/pypi/v/agent-web-search-mcp.svg)](https://pypi.org/project/agent-web-search-mcp/)
[![CI](https://github.com/JerryLiu369/agent-web-search/actions/workflows/ci.yml/badge.svg)](https://github.com/JerryLiu369/agent-web-search/actions/workflows/ci.yml)
[![MCP 2.x](https://img.shields.io/badge/MCP-2.x-6C47FF)](https://modelcontextprotocol.io/)
[![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)](https://github.com/JerryLiu369/agent-web-search/blob/main/LICENSE)

<p><strong>一键部署远程 MCP</strong></p>

<p>
  <a href="https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2FJerryLiu369%2Fagent-web-search&amp;env=AGENT_WEB_SEARCH_AUTH_TOKEN"><img alt="Deploy with Vercel" src="https://vercel.com/button" height="34"></a>
  <a href="https://railway.com/new/template?template=https%3A%2F%2Fgithub.com%2FJerryLiu369%2Fagent-web-search&amp;envs=AGENT_WEB_SEARCH_AUTH_TOKEN"><img alt="Deploy on Railway" src="https://railway.com/button.svg" height="34"></a>
  <a href="https://render.com/deploy?repo=https://github.com/JerryLiu369/agent-web-search"><img alt="Deploy to Render" src="https://render.com/images/deploy-to-render-button.svg" height="34"></a>
  <a href="https://zeabur.com/templates/8MQZG0?referralCode=JerryLiu369"><img alt="Deploy on Zeabur" src="https://zeabur.com/button.svg" height="34"></a>
</p>

支持 **Codex CLI**、**Claude Code**、**OpenCode**、**Hermes**、**DeepSeek Harness (DSH)**、普通命令行脚本、Python 应用和远程 Streamable HTTP MCP 客户端。

[快速上手](#安装与快速上手) · [给 Agent 使用](#给-agent-使用) · [搜索服务](#搜索服务) · [配置](#配置)
<br>
[统一接口](#统一请求与响应) · [其他接口](#其他接口) · [故障排查](#故障排查) · [常见问题](#常见问题) · [架构](https://github.com/JerryLiu369/agent-web-search/blob/main/ARCHITECTURE.md) · [开发](#开发)

</div>

---

Agent Web Search(PyPI 包名 `agent-web-search-mcp`)是一个开源、MIT 许可的
AI Agent 联网搜索 MCP 服务器、CLI 和 Python 库。它为 Agent 提供三种接入同一个
搜索核心的方式:原生 MCP 工具、原生插件(Hermes、DeepSeek Harness),或者由标准 Agent Skill 教会 Agent 调用 CLI。

> **如果你是 AI Agent:** 用 `pipx install agent-web-search-mcp` 安装(或用
> `uvx --from agent-web-search-mcp agent-web-search "<问题>"` 免安装直接体验),
> 然后阅读 [`skills/agent-web-search/SKILL.md`](https://github.com/JerryLiu369/agent-web-search/blob/main/skills/agent-web-search/SKILL.md) ——
> 它只教 CLI 形态(走 MCP 请看[形态一](#option-1-mcp)),[`llms.txt`](https://github.com/JerryLiu369/agent-web-search/blob/main/llms.txt)
> 是机器可读的文档索引。

它不是 Google、Bing、百度那种传统搜索引擎聚合器。传统聚合器通常把一个
关键词请求分发给多个搜索引擎,再合并搜索结果页;Agent Web Search 聚合的是
专门面向 Agent 的搜索能力:模型原生联网搜索、面向 Agent 的搜索 API,以及
适合直接放入上下文的高信号来源。它们接受自然语言问题,返回模型回答、引用
或结构化证据,Agent 可以直接使用。当前 Provider 集合中,只有 DDGS 属于
传统搜索后端。

```text
          Natural-language question
                      |
                      v
                 SearchEngine
          +-----------+-----------+
          |           |           |
          v           v           v
        DDGS        Model       Agent
                  grounding     APIs
                 (Responses,   (Exa,
                  ARK, Grok,    Parallel,
                  Gemini...)    Tavily...)
```

## 安装与快速上手

三步约一分钟:免安装先体验,装一次永久用,再接你的 Agent。
**环境要求:** Python 3.10+。默认启用的 Provider 组合(**DDGS、Exa、Parallel**)**完全免 API Key**,开箱即用。

### 免安装即刻体验

使用 `uvx` 体验即时搜索,不修改本地任何环境和 PATH:

```bash
# 直接用免 Key 默认源发起自然语言搜索
uvx --from agent-web-search-mcp agent-web-search "OpenAI Codex CLI 最新版本有哪些变化?"

# 查看 MCP 服务器运行参数
uvx agent-web-search-mcp --help
```

### 一键安装

推荐使用 `pipx` 隔离安装到全局环境(只需一次):

```bash
# 推荐:全局隔离安装
pipx install agent-web-search-mcp

# 或安装到当前 Python 环境
python -m pip install agent-web-search-mcp
```

### 验证运行

```bash
# 1. 验证 CLI 并进行真实搜索
agent-web-search --version
agent-web-search "OpenAI Codex CLI 最新版本有哪些变化?"

# 2. 验证 MCP 服务器命令
agent-web-search-mcp --help
```

> **两个命令分工明确:**
> - `agent-web-search`:面向终端交互、Shell 脚本与 Agent Skill 的直接搜索命令行工具。
> - `agent-web-search-mcp`:面向 MCP 客户端的 Stdio 与 Streamable HTTP MCP 服务器。

### 选择接入形态

| 接入形态 | 适用环境 / 客户端 | 一键接入命令 |
| :--- | :--- | :--- |
| **CLI + Skill** *(推荐)* | 具备终端命令执行能力的 Agent(Claude Code、Codex、OpenCode、Hermes) | `npx skills add JerryLiu369/agent-web-search --skill agent-web-search`([详细说明](#agent-skill)) |
| **MCP (Stdio)** | Codex CLI、Claude Code、Cursor、Cline、Roo Code | `codex mcp add agent-web-search -- agent-web-search-mcp`([详细说明](#option-1-mcp)) |
| **DSH 原生插件** | DeepSeek Harness(桌面端与网页端) | `dsh plugin --profile desktop add github:JerryLiu369/agent-web-search`([详细说明](#deepseek-harness-原生插件)) |
| **Hermes 原生插件** | Hermes Agent | `hermes plugins install JerryLiu369/agent-web-search`([详细说明](#hermes-原生插件)) |

> [!TIP]
> **为什么对有终端能力的 Agent 推荐 CLI + Skill:** 如果你的 Agent 自身具备 Bash/命令行执行能力(如 Claude Code、Codex CLI、OpenCode 或 Hermes),CLI + Skill 是心智负担最小、最可靠的形态:无需配置繁杂的 MCP JSON 文件,没有后台常驻进程挂死或清理问题,单次命令即返回结构化高信噪比的 JSON 证据。

## 为什么选择 Agent Web Search

传统搜索聚合(Google/Bing/百度封装、抓取 SERP)把关键词查询发给传统搜索引擎再合并结果页。Agent Web Search 聚合的是**为 Agent 构建的搜索能力**:一次工具调用返回结构化、可直接引用的证据——或通过模型原生 grounding 提供商返回带明确引用的综合回答。[实测基准](https://github.com/JerryLiu369/agent-web-search/blob/main/docs/benchmark-2026-09-06.md)显示了实际差异:在一个要求官方来源的中文自然语言查询上,传统 SERP 后端前 5 条结果没有任何政府域名,而 grounding 提供商返回了海关总署数据并附可用引用链接。

- **从设计上就是 Agent-native。** 主要输入是完整的自然语言问题,而不是把关键词简单分发给 Google、Bing 或百度。
- **模型原生搜索后端。** ARK、Gemini、Grok、DeepSeek、Messages、智谱 Chat Search 和 Codex Alpha 可以把联网检索、模型综合回答与明确引用结合起来。
- **Agent 搜索提供商。** Exa、Parallel、Brave、Perplexity、Tavily、You.com 和智谱 Web Search 提供面向 Agent 的搜索 API,输出结构化、适合引用或适合放入上下文的证据。
- **统一的 Provider-neutral 契约。** 所有后端都通过同一个 MCP 工具、CLI、Python API 和统一的 `results` 返回;模型后端还可以返回 `answer`。
- **Provider 相互独立。** 选中的 Provider 会并发执行,一个 Provider 失败不会丢弃其他 Provider 的成功结果。
- **保留一个简单的 DDGS 后端。** DDGS 是唯一的传统搜索后端,不需要 API Key;Exa 和 Parallel 默认也可以免 Key 使用。
- **无遥测、不共享密钥。** Provider Key 只存在于运行环境变量中,项目不提供共享 API Key 服务。

## 搜索服务

下面按搜索能力类型划分 Provider。DDGS 是唯一的传统搜索后端;其余 Provider
分别属于模型原生搜索或面向 Agent 的搜索服务。

> **默认免费、无需 Key:** DDGS、Exa 和 Parallel 都可以不配置 API Key
> 直接使用。Exa 和 Parallel 只有在提供付费 API Key 后才会切换到付费接口,
> 否则自动使用免费 MCP。

### 传统搜索后端

| Provider | 官网 | 搜索后端 | API Key | 默认启用 |
| --- | --- | --- | --- | :---: |
| **DDGS** | [DuckDuckGo](https://duckduckgo.com) | 传统 DuckDuckGo 搜索 | **免费 · 无需 Key** | 是 |

### 大模型提供商

这类 Provider 使用模型原生联网搜索或 grounding 能力。响应可以同时包含模型
生成的回答,以及明确的引用或其他搜索证据。

| Provider | 官网 | 模型原生搜索能力 | API Key | 默认启用 |
| --- | --- | --- | --- | :---: |
| **ARK** | [火山引擎 Ark](https://www.volcengine.com/product/ark) | Responses API + 豆包联网搜索 | `ARK_API_KEY` | 否 |
| **Codex Alpha**(实验性) | 兼容 Alpha Search 的反代网关 | 模型驱动的 Alpha Search | `AGENT_WEB_SEARCH_CODEX_ALPHA_API_KEY` | 否 |
| **DeepSeek** | [DeepSeek API](https://api-docs.deepseek.com/) | Anthropic Messages API 原生网页搜索 | `DEEPSEEK_API_KEY` | 否 |
| **Gemini** | [Google AI](https://ai.google.dev/gemini-api/docs/google-search) | Gemini Google Search grounding | `GEMINI_API_KEY` | 否 |
| **Grok** | [xAI](https://docs.x.ai/docs/guides/tools/overview) | xAI 网页搜索和 X Search | `XAI_API_KEY` | 否 |
| **Responses** | 兼容 Responses API 的网关 | 通用 OpenAI Responses API 网页搜索 | `AGENT_WEB_SEARCH_RESPONSES_API_KEY` | 否 |
| **Messages** | 兼容 Messages API 的网关 | 通用 Anthropic Messages API 网页搜索 | `AGENT_WEB_SEARCH_MESSAGES_API_KEY` | 否 |
| **智谱 Chat Search** | [智谱 AI](https://open.bigmodel.cn/) | GLM Chat Completions 原生联网搜索 | `ZHIPU_CHAT_SEARCH_API_KEY` | 否 |

### Agent 搜索提供商

这类 Provider 面向 Agent 提供搜索服务:支持自然语言查询,并返回结构化来源、
高信号摘录或适合引用的元数据,而不是传统搜索页面式体验。

| Provider | 官网 | 面向 Agent 的搜索能力 | API Key | 默认启用 |
| --- | --- | --- | --- | :---: |
| **Exa** | [Exa](https://exa.ai) | 语义 Search API 或免费 MCP 后端 | **无 Key 免费** · 可选 `EXA_API_KEY` | 是 |
| **Parallel** | [Parallel](https://parallel.ai) | 面向上下文的搜索 API 或免费 MCP | **无 Key 免费** · 可选 `PARALLEL_API_KEY` | 是 |
| **Brave** | [Brave Search](https://brave.com/search/api/) | 结构化 Web Search API | `BRAVE_SEARCH_API_KEY` | 否 |
| **Perplexity** | [Perplexity API](https://www.perplexity.ai/api-platform) | 原生结构化 Search API | `PERPLEXITY_API_KEY` | 否 |
| **Tavily** | [Tavily](https://tavily.com) | 面向 Agent 的 Search API | `TAVILY_API_KEY` | 否 |
| **You.com** | [You.com API](https://you.com/platform/api) | 统一网页与新闻 Search API | `YDC_API_KEY` | 否 |
| **智谱 Web Search** | [智谱 AI](https://open.bigmodel.cn/) | 独立的结构化 Web Search API | `ZHIPU_WEB_SEARCH_API_KEY` | 否 |

Provider 架构是开放的:添加新的搜索后端时,不需要修改 MCP、Hermes、CLI 或 Python 接口。

## 给 Agent 使用

> **前置要求:** 请先完成 [安装与快速上手](#安装与快速上手)。下文针对各接入形态提供详细的客户端配置与命令参考。

### 形态一:MCP<a id="option-1-mcp"></a>

当 Agent 支持工具服务器,或者你需要类型化的工具发现、协议级错误、远程
访问时,选择 MCP。同一个 `agent-web-search-mcp` 命令同时支持本地 stdio
和无状态 Streamable HTTP。

#### 本地 stdio MCP

先安装一次:

```bash
# 推荐:隔离安装
pipx install agent-web-search-mcp

# 或安装到当前 Python 环境
python -m pip install agent-web-search-mcp
```

然后让 MCP 客户端启动 `agent-web-search-mcp`:

```json
{
  "mcpServers": {
    "agent-web-search": {
      "command": "agent-web-search-mcp",
      "args": []
    }
  }
}
```

如果本机已经有 `uvx`,也可以不持久安装,让客户端使用命令 `uvx`、参数
`["agent-web-search-mcp"]`。

<details>
<summary><strong>Codex CLI、Claude Code 和 OpenCode 示例</strong></summary>

```bash
# Codex CLI
codex mcp add agent-web-search -- agent-web-search-mcp

# Claude Code
claude mcp add agent-web-search -- agent-web-search-mcp
```

OpenCode:

```json
{
  "$schema": "https://opencode.ai/config.json",
  "mcp": {
    "agent-web-search": {
      "type": "local",
      "command": ["agent-web-search-mcp"],
      "enabled": true
    }
  }
}
```

</details>

#### 远程 HTTPS MCP

可以直接使用 README 顶部的一键部署按钮,也可以自行运行同一个服务器:

```bash
python -c "import secrets; print(secrets.token_urlsafe(32))"
export AGENT_WEB_SEARCH_AUTH_TOKEN="<your-generated-token>"
agent-web-search-mcp --transport http
```

服务器提供需要鉴权的 `POST /mcp` 和公开的 `GET /healthz`。远程 MCP
客户端这样连接:

```json
{
  "mcpServers": {
    "agent-web-search": {
      "url": "https://<your-deployment-domain>/mcp",
      "headers": {
        "Authorization": "Bearer <your-deployment-token>"
      }
    }
  }
}
```

所有公网部署都必须设置至少 32 个字符的 `AGENT_WEB_SEARCH_AUTH_TOKEN`。
服务端无状态,不会创建 `MCP-Session-Id`。

### 形态二:CLI + Agent Skill<a id="agent-skill"></a>

当 Agent 已经有 Shell 能力并支持 Agent Skills 时,选择这个形态。Skill
会教 Agent 调用 CLI、选择控制参数、理解 `results` 并处理结构化失败,不需要
配置 MCP Server。

1. 安装 CLI:

   ```bash
   pipx install agent-web-search-mcp
   # 或:python -m pip install agent-web-search-mcp
   ```

2. 安装仓库内的 [`agent-web-search` Skill](https://github.com/JerryLiu369/agent-web-search/tree/main/skills/agent-web-search):

   ```bash
   npx skills add JerryLiu369/agent-web-search --skill agent-web-search
   ```

   如果 Agent 不使用 `skills` 安装器,就把 `skills/agent-web-search` 复制到
   对应客户端的 Skills 目录。

3. 验证 CLI,然后让 Agent 搜索:

   ```bash
   agent-web-search --version
   agent-web-search "OpenAI Codex CLI 最新版本有哪些变化?"
   ```

CLI 成功时向 stdout 写入一个 JSON 文档。如果所有 Provider 都失败,它会向
stderr 写入统一的 `all_providers_failed` JSON,并以状态码 1 退出,因此 Agent
可以区分真正的失败和空结果。

| CLI 选项 | MCP 参数 | 取值 | 默认值 |
| --- | --- | --- | --- |
| 位置参数 `QUERY` | `query` | 1–4,000 个字符的自然语言问题 | 必填 |
| `--provider`(可重复) | `providers` | 已启用的 Provider 名 | 所有已启用 |
| `--max-results` | `max_results` | 1–20 | `5` |
| `--time-range` | `time_range` | `d`、`w`、`m`、`y` | — |
| `--grok-search-mode` | `grok_search_mode` | `web_search`、`x_search`、`both` | `web_search` |

<details>
<summary><strong>从 GitHub 安装最新开发版本</strong></summary>

```bash
pipx install 'git+https://github.com/JerryLiu369/agent-web-search.git'
```

</details>

> [!IMPORTANT]
> 不要把 API Key 写入 Shell 历史、源代码、Git 提交、截图或纳入版本控制的
> MCP 配置。请通过服务端或本地环境变量提供 Key。

## 统一请求与响应

MCP 对外注册一个名为 `web_search` 的工具;CLI 映射到同一组输入。

| 参数 | 类型 | 必填 | 默认值 | 说明 |
| --- | --- | :---: | --- | --- |
| `query` | string,1–4,000 个字符 | 是 | — | 完整的自然语言搜索问题 |
| `max_results` | integer,1–20 | 否 | `5` | 期望返回的最大结果数量 |
| `time_range` | `d`、`w`、`m`、`y` | 否 | — | 过去一天、一周、一月或一年 |
| `providers` | string 数组 | 否 | 所有已启用 Provider | 将本次请求限制在指定的已启用 Provider 中 |
| `grok_search_mode` | `web_search`、`x_search`、`both` | 否 | `web_search` | 仅在启用 Grok 时可用 |

调用示例:

```json
{
  "query": "过去一个月发表了哪些 GPU 内核生成方向的论文?",
  "max_results": 5,
  "time_range": "m",
  "providers": ["ddgs", "exa"]
}
```

Provider 选择分为两层:

1. `AGENT_WEB_SEARCH_PROVIDERS` 决定进程启动时启用哪些 Provider。
2. 请求级 `providers` 参数可以进一步缩小范围,但不能启用启动时未启用的 Provider。

### 响应格式

每个成功返回的 Provider 会出现在 `providers` 字段中;失败的 Provider 会被剔除:

```json
{
  "query": "过去一个月发表了哪些 GPU 内核生成方向的论文?",
  "providers": {
    "ddgs": {
      "results": [
        {
          "title": "Example result",
          "url": "https://example.com/paper",
          "description": "Excerpt of the matching page",
          "published_at": "2026-08-02"
        }
      ]
    }
  }
}
```

| 字段 | 含义 |
| --- | --- |
| `answer` | 后端生成时返回的文本回答,无则省略该字段 |
| `results` | 结果行:`title`、`url`、`description`,以及可选的 `published_at` 和 `author` |

如果选中的 Provider 全部失败,MCP 会返回工具错误;CLI 则把同一载荷写入
stderr 并以状态码 1 退出。两者都使用稳定错误码 `all_providers_failed`,并附带
各 Provider 的诊断信息:

```json
{
  "error": {
    "code": "all_providers_failed",
    "message": "All enabled search providers failed. Check provider configuration, credentials, quotas, and network access.",
    "provider_errors": {
      "ddgs": "RuntimeError: rate limited"
    }
  },
  "query": "过去一个月发表了哪些 GPU 内核生成方向的论文?"
}
```

## Python API

CLI、MCP 服务器和 Hermes 插件都是 `agent_web_search.SearchEngine` 的薄封装,后者即公开的 Python API。`SearchRequest` 接受与 MCP 工具参数相同的字段:

```python
from agent_web_search import SearchEngine, SearchRequest

engine = SearchEngine()  # 构造时读取 AGENT_WEB_SEARCH_* 环境变量

response = engine.search(
    SearchRequest(query="MCP 规范最近有哪些变化?", max_results=5, time_range="m")
)

for name, provider in response.providers.items():
    print(f"{name}: searched={provider.searched}, results={len(provider.results)}")

if response.all_providers_failed:
    print(response.failed_provider_errors)
```

## 配置

CLI、MCP 服务器或 Hermes 插件启动时会读取环境变量。修改 Provider 设置后需要重启对应进程。仓库内的 [`.env.example`](https://github.com/JerryLiu369/agent-web-search/blob/main/.env.example) 以注释模板的形式列出了全部变量。

### 通用设置

| 变量 | 默认值 | 用途 |
| --- | --- | --- |
| `AGENT_WEB_SEARCH_PROVIDERS` | `ddgs,exa,parallel` | 以逗号分隔的启动时启用 Provider 列表 |
| `AGENT_WEB_SEARCH_TIMEOUT` | `60` | 单次上游 HTTP 调用的 socket 超时。多步 Provider 会成倍放大:keyless Parallel 最多发 3 个请求(最坏 3×),ARK 可能追加续写请求(最坏 2×),因此整次搜索最长可达该值的 3 倍 |

示例:

```bash
export AGENT_WEB_SEARCH_PROVIDERS="ddgs,exa,brave"
export AGENT_WEB_SEARCH_TIMEOUT="30"
```

```powershell
$env:AGENT_WEB_SEARCH_PROVIDERS = "ddgs,exa,brave"
$env:AGENT_WEB_SEARCH_TIMEOUT = "30"
```

### HTTP 传输设置

| 变量 | 默认值 | 用途 |
| --- | --- | --- |
| `AGENT_WEB_SEARCH_MCP_TRANSPORT` | `stdio` | 可选 `stdio` 或 `http`;`--transport` 可以覆盖它 |
| `AGENT_WEB_SEARCH_HTTP_HOST` | `0.0.0.0` | 容器部署时的 HTTP 监听地址 |
| `AGENT_WEB_SEARCH_HTTP_PORT` | `PORT` 或 `8000` | HTTP 监听端口;显式值优先于平台 `PORT` |
| `AGENT_WEB_SEARCH_AUTH_TOKEN` | — | HTTP 必需的 Bearer Token,至少 32 个字符 |
| `AGENT_WEB_SEARCH_ALLOW_ANONYMOUS` | `false` | 为可信网络或临时 Demo 显式关闭 HTTP 鉴权 |
| `AGENT_WEB_SEARCH_HTTP_ALLOWED_HOSTS` | — | 可选、逗号分隔的 Host 白名单 |
| `AGENT_WEB_SEARCH_HTTP_ALLOWED_ORIGINS` | — | 可选、逗号分隔的 Origin 白名单;必须同时配置 Host |
| `AGENT_WEB_SEARCH_HTTP_LOG_LEVEL` | `info` | 容器服务器的 Uvicorn 日志级别 |

HTTP 设置仍然全部来自环境变量;部署文件不会引入第二套应用配置格式。

### Provider 设置

Provider 的专用设置如下,包含全部 Provider 的凭据和模型参数。上面的支持列表按
搜索能力分组;本节是具体配置参考。

#### 1. DDGS

DDGS 使用 DuckDuckGo,不需要 API Key 或 Provider 专用环境变量。包安装时会自动安装 `ddgs` Python 依赖。

#### 2. Exa

Exa 同时支持付费和免 Key 模式。

| 变量 | 必填 | 用途 |
| --- | :---: | --- |
| `EXA_API_KEY` | 否 | 设置后使用付费 Search API |
| `EXA_MCP_URL` | 否 | 未设置 API Key 时覆盖默认免费 MCP 地址 |

未设置 `EXA_API_KEY` 时,Exa 会尽力通过免费 MCP 端点搜索。付费 API 通常具有更高的配额和可靠性。

#### 3. Parallel

Parallel 返回适合放入 LLM 上下文的信息密集型摘录。统一的 `parallel` Provider 会自动选择传输方式:

- 未设置 Key 时,使用 Parallel 免费 Search MCP。
- 设置 `PARALLEL_API_KEY` 后,使用付费 Search REST API。

两种方式都会把 `excerpts` 映射到统一结果的 description 字段,调用 Agent 无需区分 `parallel-free` 和 `parallel`。

| 变量 | 必填 | 用途 |
| --- | :---: | --- |
| `PARALLEL_API_KEY` | 否 | 启用付费 API;省略时使用免费 MCP |

Parallel 默认启用,Key 为可选项。

#### 4. ARK(推荐)

火山引擎 ARK 通过 Responses API 提供模型驱动的联网搜索。配置 Key 后,将 `ark` 加入 `AGENT_WEB_SEARCH_PROVIDERS`。

| 变量 | 必填 | 用途 |
| --- | :---: | --- |
| `ARK_API_KEY` | 是 | 单个 Key,或用逗号/换行分隔的多个 Key |
| `AGENT_WEB_SEARCH_ARK_MODELS` | 否 | 用逗号/换行分隔的 ARK 模型 ID;默认 `glm-5-2-260617,doubao-seed-2-1-turbo-260628,deepseek-v4-flash-ga-260731` |

只配置一个模型时会固定使用该模型;配置多个模型时,连续请求会轮询选择模型。配置多个 ARK Key 时,每次请求会选择一个 Key。

<details>
<summary><strong>可选的火山引擎协作奖励计划信息</strong></summary>

使用 Agent Web Search 不要求参加奖励计划。ARK 用户可以自行查看官方的[火山引擎协作奖励计划](https://www.volcengine.com/docs/82379/1391869?lang=zh)。配额、支持模型、有效期和数据授权条款可能变化,请在选择加入前查看官方最新条款。参与计划并不是使用 Agent Web Search 的前提。

</details>

#### 5. Brave

| 变量 | 必填 | 用途 |
| --- | :---: | --- |
| `BRAVE_SEARCH_API_KEY` | 是 | Brave Web Search API 凭据 |

配置 Key 后,将 `brave` 加入 `AGENT_WEB_SEARCH_PROVIDERS`。

#### 6. Gemini

| 变量 | 必填 | 用途 |
| --- | :---: | --- |
| `GEMINI_API_KEY` | 是 | Google AI API 凭据 |
| `AGENT_WEB_SEARCH_GEMINI_MODELS` | 否 | 用逗号/换行分隔的 Gemini 模型 ID;默认 `gemini-3.7-flash` |

Gemini 会把通用的结果数量和时间控制尽力转换为 Prompt 约束。只配置一个模型时固定使用该模型;配置多个模型时连续请求会轮询选择模型。

#### 7. Grok

| 变量 | 必填 | 用途 |
| --- | :---: | --- |
| `XAI_API_KEY` | 是 | xAI API 凭据 |
| `AGENT_WEB_SEARCH_GROK_MODELS` | 否 | 用逗号/换行分隔的 Grok 模型 ID;默认 `grok-4.6` |

只配置一个模型时固定使用该模型;配置多个模型时连续请求会轮询选择模型。

启用 Grok 后,公开工具 Schema 会增加 `grok_search_mode`:

- `web_search` 搜索网页。
- `x_search` 搜索 X,并在可用时采用原生日期过滤器。
- `both` 在一次请求中同时向服务端暴露这两种工具并让 Grok 选择;它不会发起两个独立的模型请求。

#### 8. Codex Alpha(实验性)

该 Provider 只通过 API key 调用实现 `/v1/alpha/search` 的兼容网关;网关内部使用的
OAuth 不属于本项目的认证方式。配置完整 endpoint(Provider 不会自动拼接路径)、key
和可选模型后,将 `codex_alpha` 加入 `AGENT_WEB_SEARCH_PROVIDERS`:

| 变量 | 必填 | 用途 |
| --- | :---: | --- |
| `AGENT_WEB_SEARCH_CODEX_ALPHA_ENDPOINT` | 是 | 完整 Alpha Search endpoint URL |
| `AGENT_WEB_SEARCH_CODEX_ALPHA_API_KEY` | 是 | 网关 Bearer API key |
| `AGENT_WEB_SEARCH_CODEX_ALPHA_MODEL` | 否 | 模型 ID,默认 `gpt-5.6-luna` |

该 Provider 只发送普通的 `search_query` 命令并返回标准网页搜索结果。

#### 9. DeepSeek

DeepSeek 使用官方 Anthropic 兼容 Messages API 和原生
`web_search_20250305` 服务端工具。Provider 会保留模型最终生成的文本,只把明确出现的
`web_search_result` 结果块映射为统一结果。因此,响应可以只有 `answer`,而 `results` 为空。

| 变量 | 必填 | 用途 |
| --- | :---: | --- |
| `DEEPSEEK_API_KEY` | 是 | DeepSeek API 凭据 |
| `AGENT_WEB_SEARCH_DEEPSEEK_BASE_URL` | 否 | Anthropic API 基础地址,默认 `https://api.deepseek.com/anthropic` |
| `AGENT_WEB_SEARCH_DEEPSEEK_MODELS` | 否 | 用逗号或换行分隔的模型 ID,默认 `deepseek-v4-flash` |

配置 Key 后,将 `deepseek` 加入 `AGENT_WEB_SEARCH_PROVIDERS`。Provider 会在配置的基础地址后追加 `/v1/messages`。配置多个模型时,连续请求会轮询选择模型。

#### 10. Perplexity

该 Provider 使用 Perplexity 原生的结构化 Search API,返回搜索结果行,而不是由 Sonar 生成的文本回答。该 Provider 不包含 OpenRouter 兼容逻辑。

| 变量 | 必填 | 用途 |
| --- | :---: | --- |
| `PERPLEXITY_API_KEY` | 是 | Perplexity Search API 凭据 |

配置 Key 后,将 `perplexity` 加入 `AGENT_WEB_SEARCH_PROVIDERS`。

#### 11. Tavily

| 变量 | 必填 | 用途 |
| --- | :---: | --- |
| `TAVILY_API_KEY` | 是 | Tavily Search API 凭据 |

配置 Key 后,将 `tavily` 加入 `AGENT_WEB_SEARCH_PROVIDERS`。

#### 12. You.com

You.com 返回统一的网页和新闻结果。Agent Web Search 会合并两部分、按 URL 去重,并将 `max_results` 应用于合并后的结果列表。

| 变量 | 必填 | 用途 |
| --- | :---: | --- |
| `YDC_API_KEY` | 是 | You.com Search API 凭据 |

配置 Key 后,将 `you` 加入 `AGENT_WEB_SEARCH_PROVIDERS`。

#### 13. 智谱 Web Search

智谱 Web Search 使用中国区独立的 Web Search API,返回结构化搜索结果。它与智谱
Chat Search 是两个独立 Provider,二者之间不会互相 fallback。

| 变量 | 必填 | 用途 |
| --- | :---: | --- |
| `ZHIPU_WEB_SEARCH_API_KEY` | 是 | 智谱 Web Search API 凭据 |
| `AGENT_WEB_SEARCH_ZHIPU_WEB_SEARCH_BASE_URL` | 否 | 中国区 API 基础地址,默认 `https://open.bigmodel.cn` |

配置 Key 后,将 `zhipu_web_search` 加入 `AGENT_WEB_SEARCH_PROVIDERS`。Provider 会在
基础地址后追加 `/api/paas/v4/web_search`。

#### 14. 智谱 Chat Search

智谱 Chat Search 使用中国区 GLM Chat Completions API 的原生联网搜索能力。它返回
模型回答和明确的顶层搜索结果;回答正文中提到的 URL 不会被猜测成引用。它与智谱
Web Search 是两个独立 Provider,不存在 API/Chat fallback。

| 变量 | 必填 | 用途 |
| --- | :---: | --- |
| `ZHIPU_CHAT_SEARCH_API_KEY` | 是 | 智谱 Chat Search API 凭据 |
| `AGENT_WEB_SEARCH_ZHIPU_CHAT_BASE_URL` | 否 | 中国区 API 基础地址,默认 `https://open.bigmodel.cn` |
| `AGENT_WEB_SEARCH_ZHIPU_CHAT_MODELS` | 否 | 用逗号/换行分隔的 GLM 模型 ID,默认 `glm-5.3-flash` |

配置 Key 后,将 `zhipu_chat_search` 加入 `AGENT_WEB_SEARCH_PROVIDERS`。Provider 会在
基础地址后追加 `/api/paas/v4/chat/completions`。配置多个模型时,连续请求会轮询选择模型。

#### 15. Responses

Responses 是通用 OpenAI Responses API 客户端,适用于在 `POST {base_url}/responses`
暴露服务端网页搜索工具的网关。它遍历 `output` 数组(不假设 `output[0]` 即为结果),
将 `web_search_call` 的 action sources 和 `url_citation` 引用统一为标准结果,并保留
模型生成的回答。只有 message 而没有任何 URL 的响应会保留回答、返回空 `results`,
并将 `searched` 标记为 false。

| 变量 | 必填 | 用途 |
| --- | :---: | --- |
| `AGENT_WEB_SEARCH_RESPONSES_BASE_URL` | 否 | 基础地址;默认 `https://api.openai.com/v1`。无 `/v1` 后缀时追加 `/v1/responses`,否则追加 `/responses` |
| `AGENT_WEB_SEARCH_RESPONSES_API_KEY` | 是 | Bearer 凭据;可回退到 `OPENAI_API_KEY` |
| `AGENT_WEB_SEARCH_RESPONSES_MODELS` | 否 | 用逗号/换行分隔的模型 ID,默认 `gpt-5-mini` |
| `AGENT_WEB_SEARCH_RESPONSES_TOOL_TYPE` | 否 | 搜索工具类型,默认 `web_search` |
| `AGENT_WEB_SEARCH_RESPONSES_TIMEOUT` | 否 | 单次请求超时(秒);设置后覆盖 `AGENT_WEB_SEARCH_TIMEOUT` |

配置 Key 后,将 `responses` 加入 `AGENT_WEB_SEARCH_PROVIDERS`。配置多个模型时,连续请求会轮询选择模型。

#### 16. Messages

Messages 是通用 Anthropic Messages API 客户端,适用于在 `POST {base_url}/v1/messages`
暴露服务端网页搜索工具的网关。它遍历 `content` 数组(不假设单个结果块即为结果),
将 `web_search_tool_result` / `web_search_result` 结果块统一为标准结果,缺失标题时
从引用或结果域名回填,并保留模型生成的回答。只有文本而没有任何 URL 的响应会保留
回答、返回空 `results`,并将 `searched` 标记为 false。

| 变量 | 必填 | 用途 |
| --- | :---: | --- |
| `AGENT_WEB_SEARCH_MESSAGES_BASE_URL` | 否 | 基础地址;默认 `https://api.anthropic.com`,会自动追加 `/v1/messages` |
| `AGENT_WEB_SEARCH_MESSAGES_ENDPOINT` | 否 | 完整 endpoint 覆盖;优先级高于基础地址 |
| `AGENT_WEB_SEARCH_MESSAGES_API_KEY` | 是 | `x-api-key` 凭据 |
| `AGENT_WEB_SEARCH_MESSAGES_MODELS` | 否 | 用逗号/换行分隔的模型 ID,默认 `claude-3-7-sonnet-20250219,claude-3-5-haiku-20241022` |
| `AGENT_WEB_SEARCH_MESSAGES_TOOL_TYPE` | 否 | 搜索工具类型,默认 `web_search_20250305` |
| `AGENT_WEB_SEARCH_MESSAGES_TOOL_NAME` | 否 | 搜索工具名称,默认 `web_search` |
| `AGENT_WEB_SEARCH_MESSAGES_TIMEOUT` | 否 | 单次请求超时(秒);设置后覆盖 `AGENT_WEB_SEARCH_TIMEOUT` |

配置 Key 后,将 `messages` 加入 `AGENT_WEB_SEARCH_PROVIDERS`。配置多个模型时,连续请求会轮询选择模型。

### 通用搜索控制

每个 Provider 会尽可能将公共控制参数映射到原生 API,不支持的参数会被忽略。

| Provider | `max_results` | `time_range` |
| --- | --- | --- |
| DDGS | 原生 `max_results` | 原生 `timelimit` |
| Exa | 原生结果数量 | 原生发布日期 |
| Parallel | REST:原生 `max_results`;keyless MCP:客户端截断(`results[:max_results]`) | 忽略 |
| ARK | 原生 `limit` | Prompt 约束 |
| Brave | 原生 `count` | 原生 `freshness` |
| Gemini | Prompt 约束 | Prompt 约束 |
| Grok | Prompt 约束 | Prompt;X Search 还会使用原生日期参数 |
| Codex Alpha | 本地结果截断 | 忽略 |
| DeepSeek | 本地搜索结果截断 | Prompt 约束 |
| Messages | 本地去重并截断 | Prompt 约束 |
| Perplexity | 原生 `max_results` | 原生时间范围过滤 |
| Tavily | 原生 `max_results` | 原生 `time_range` |
| You.com | 原生 `count`,合并后截断 | 原生 `freshness` |
| 智谱 Web Search | 原生 `count`,本地去重并截断 | 原生时间范围过滤 |
| 智谱 Chat Search | 原生 `count`,本地去重并截断 | 原生时间范围过滤 |
| Responses | 本地去重并截断 | Prompt 约束 |

基于 Prompt 的控制属于尽力而为,不是严格保证。

## 其他接口

### Hermes 原生插件

直接从 GitHub 安装原生插件:

```bash
pip install 'ddgs>=9.0'
hermes plugins install JerryLiu369/agent-web-search --no-enable
hermes plugins enable agent-web-search --allow-tool-override
```

该插件会有意替换 Hermes 内置的 `web_search` 工具,因此必须显式授予 `--allow-tool-override` 权限。启用后请启动新的 Hermes 会话;通过消息渠道使用时还需要重启 gateway。

Hermes 也可以不安装原生插件,而是通过通用 MCP 集成连接本项目。

### DeepSeek Harness 原生插件

直接从 GitHub 安装原生插件(桌面版和 CLI 版 profile 都一样 —— 桌面版自带 `dsh plugin` 命令,无需手动放置文件):

```bash
dsh plugin --profile <profile> add github:JerryLiu369/agent-web-search
python -m pip install agent-web-search-mcp
```

该插件会有意替换 DSH 原生 `web_search` seam 背后的实现 —— 保持同一个模型可见工具名、提示词、规范化来源和引用卡片;不会暴露 `mcp__...__web_search` 工具。请把 `agent-web-search-mcp` Python 命令安装在 DSH 所用的同一环境中,装完重启 DSH。桥接层把内置 Provider 委托给该命令,同时保留 DSH 原生设置、历史与诊断。完整步骤和一段可直接粘贴的安装 prompt 见 [`integrations/dsh/docs/INSTALL.md`](https://github.com/JerryLiu369/agent-web-search/blob/main/integrations/dsh/docs/INSTALL.md)。

DSH 也可以不装原生插件,而是用自带的 MCP 客户端连接本项目。

## 故障排查

- **`all_providers_failed`** —— 所有 Provider 都失败了。MCP 会标记工具错误;CLI 会把诊断写入 stderr 并退出 1。请检查 Key、配额和网络;临时限流可以有界重试一次。
- **找不到 `agent-web-search`** —— 使用 `pipx` 或 `pip` 安装 PyPI 包,然后重新打开 Shell,确保脚本目录已经加入 `PATH`。
- **HTTP 401 `invalid_token`** —— `Authorization: Bearer …` 请求头必须与 `AGENT_WEB_SEARCH_AUTH_TOKEN` 一致,且该 Token 至少 32 个字符。
- **响应里少了某个 Provider** —— 失败的 Provider 会从成功响应中剔除。Python API 可以通过 `response.failed_provider_errors` 查看原因。
- **修改 Provider 配置不生效** —— Provider 设置只在进程启动时读取一次;修改后请重启 CLI、MCP 服务器或 Hermes 插件。
- **MCP 客户端在工具返回前超时** —— `AGENT_WEB_SEARCH_TIMEOUT` 限定的是单次上游 HTTP 调用的超时,不是整次搜索。keyless Parallel 最多发 3 个请求,ARK 可能追加续写请求,最坏总耗时是其 3 倍;请据此设置 MCP 客户端的 tool 超时。

## 常见问题

### Agent Web Search 是什么?

Agent Web Search 是面向 AI Agent 的开源联网搜索层。它通过 MCP 服务器(stdio
或 Streamable HTTP)、CLI 和 Python API 暴露同一个 `web_search` 工具。工具背后
并发调用模型原生搜索 grounding(ARK、Gemini、Grok、DeepSeek、智谱 Chat Search、
Codex Alpha(实验性)以及通用 Responses/Messages 网关)、Agent 搜索 API(Exa、Parallel、Brave、
Perplexity、Tavily、You.com、智谱 Web Search),并以 DuckDuckGo 作为传统搜索
兜底,最终返回统一格式的 JSON。

### 有没有不需要 API Key 的免费联网搜索 MCP?

有。默认 Provider 组合 DDGS、Exa、Parallel 都不需要 API Key。在设置
`EXA_API_KEY` 或 `PARALLEL_API_KEY` 之前,Exa 和 Parallel 会尽力使用各自的免费
MCP 端点。付费 Provider 需要通过 `AGENT_WEB_SEARCH_PROVIDERS` 显式启用。

### 它和 Google/Bing 元搜索类 MCP 有什么区别?

元搜索服务器抓取传统搜索结果页再合并。Agent Web Search 聚合的是面向 Agent 的
搜索服务,其中模型原生 grounding 会返回带引用的综合 `answer`。
[与 open-webSearch 的对比基准](https://github.com/JerryLiu369/agent-web-search/blob/main/docs/benchmark-vs-open-websearch-2026-09-06.md)
记录了这种差异及其前提:从数据中心 IP 抓取 SERP 经常被反爬拦截,而基于 API 的
Provider 只会返回更少结果,不会完全为空。

### 支持哪些 Agent 和客户端?

任何支持 stdio 或 Streamable HTTP 的 MCP 客户端,包括 Codex CLI、Claude Code、
OpenCode、Cursor、Cline 和 Claude Desktop。Hermes 有原生插件。具备 Shell 能力
的 Agent 也可以不用 MCP,而是通过 CLI 加内置 Agent Skill 使用。

### 应该用 MCP 还是 CLI + Skill?

客户端支持工具服务器、需要类型化工具发现、协议级错误或远程部署时,用 MCP。
Agent 已有 Shell 且支持 Agent Skills 时,用 CLI + Skill,无需任何 MCP 配置。
两者返回的响应格式相同。

### 能否接入自己的 OpenAI 或 Anthropic 兼容网关做搜索 grounding?

可以。`responses` Provider 可调用任何带服务端联网搜索工具的 OpenAI Responses
API 网关,`messages` Provider 对 Anthropic Messages API 网关做同样的事。Base
URL、Key 和模型通过 [Provider 设置](#provider-设置) 中的环境变量配置。

### 能否部署为远程 MCP 服务器?

可以。`agent-web-search-mcp --transport http` 在 `POST /mcp` 提供无状态
Streamable HTTP 服务,并默认启用 Bearer Token 认证。仓库提供 Vercel、Railway、
Render、Zeabur 一键部署模板和 Dockerfile。

### 会收集遥测数据或保存我的 API Key 吗?

不会。项目没有遥测,也没有共享 Key 服务。Provider 凭据只从执行搜索的本机或
服务器环境变量读取,不会作为工具参数传入。

## 开发

使用 [`uv`](https://docs.astral.sh/uv/) 可以保持开发环境隔离且可复现:

```bash
git clone https://github.com/JerryLiu369/agent-web-search.git
cd agent-web-search
uv venv
uv pip install -e '.[dev]'
uv run --extra dev pytest -q
uv run ruff check .
```

<details>
<summary><strong>标准 venv + pip 方式</strong></summary>

```bash
python -m venv .venv
# Linux/macOS: source .venv/bin/activate
# Windows PowerShell: .venv\Scripts\Activate.ps1
python -m pip install -e '.[dev]'
pytest -q
ruff check .
```

</details>

[ARCHITECTURE.md](https://github.com/JerryLiu369/agent-web-search/blob/main/ARCHITECTURE.md) 是设计事实来源,[AGENTS.md](https://github.com/JerryLiu369/agent-web-search/blob/main/AGENTS.md) 列出了不可妥协的约束。在修改 Transport、配置、鉴权、部署、Provider 或工具 Schema 之前,请先阅读这两份文档,保持 stdio 与 HTTP 行为一致,并在同一改动中保持 `pytest` 和 `ruff` 通过。

## 许可证

[MIT](https://github.com/JerryLiu369/agent-web-search/blob/main/LICENSE)