Appearance
openrouter:web_search 是 OpenRouter 的 Server Tool(Beta),让任何 LLM 模型都能在推理过程中执行实时网络搜索。只需在 tools 数组中添加该工具,模型即可根据请求内容自主决定是否搜索、搜索几次,并将结果融入回复。支持五种搜索引擎:auto(默认)、native(provider 原生)、exa、firecrawl(BYOK)、parallel。可配置 max_results(单次搜索结果数)、max_total_results(整个请求的总结果上限)、search_context_size(每条结果的内容详细程度)和域名过滤。用量记录在响应 usage.server_tool_use.web_search_requests 中。本文还提供从旧版 Web Search Plugin(plugins 数组方式)迁移到新版的完整对照示例。
openrouter:web_search Server Tool(目前为 Beta)让任何 OpenRouter 模型都能获取实时网络信息。模型判断需要当前数据时,调用该工具执行搜索;OpenRouter 返回结果,模型据此生成有据可查的回复。
Beta 提醒:Server Tools 目前处于 Beta 阶段,API 和行为可能会有变更。
工作原理
- 在
tools数组中包含{ "type": "openrouter:web_search" } - 模型根据用户请求决定是否需要搜索,并生成搜索词
- OpenRouter 使用配置的引擎执行搜索(默认
auto,优先 provider 原生,回退到 Exa) - 搜索结果(URL、标题、摘要)返回给模型
- 模型综合结果生成回复,必要时可在一次请求中多次搜索
快速开始
javascript
const response = await fetch('https://openrouter.ai/api/v1/chat/completions', {
method: 'POST',
headers: {
Authorization: 'Bearer <OPENROUTER_API_KEY>',
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: 'openai/gpt-4o',
messages: [
{
role: 'user',
content: '本周 AI 领域有哪些重大进展?'
}
],
tools: [
{ type: 'openrouter:web_search' }
]
}),
});
const data = await response.json();
console.log(data.choices[0].message.content);参数配置
json
{
"type": "openrouter:web_search",
"parameters": {
"engine": "exa",
"max_results": 5,
"max_total_results": 20,
"search_context_size": "medium",
"allowed_domains": ["example.com"],
"excluded_domains": ["reddit.com"]
}
}| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
engine | string | auto | 搜索引擎:auto、native、exa、firecrawl、parallel |
max_results | integer | 5 | 单次搜索最多返回结果数(1–25),对 Exa、Firecrawl、Parallel 有效;native 忽略 |
max_total_results | integer | — | 整个请求所有搜索的总结果上限,控制费用和 context 占用 |
search_context_size | string | medium | 每条结果的内容量:low、medium、high;Exa 控制单条字符数,Parallel 控制所有结果总字符数 |
user_location | object | — | 用户大致位置,用于地理偏向搜索(目前仅 native 支持) |
allowed_domains | string[] | — | 只返回这些域名的结果 |
excluded_domains | string[] | — | 排除这些域名的结果 |
用户位置
json
{
"type": "openrouter:web_search",
"parameters": {
"user_location": {
"type": "approximate",
"city": "Beijing",
"region": "Beijing",
"country": "CN",
"timezone": "Asia/Shanghai"
}
}
}所有字段均为可选。
引擎选择
| 引擎 | 说明 |
|---|---|
auto(默认) | 优先使用 provider 原生搜索,不支持时回退到 Exa |
native | 强制使用 provider 内置搜索 |
exa | 使用 Exa 的搜索 API(关键词 + 语义混合) |
firecrawl | 使用 Firecrawl 搜索 API(BYOK,需自备密钥) |
parallel | 使用 Parallel 搜索 API |
引擎能力对比
| 功能 | Exa | Firecrawl | Parallel | Native |
|---|---|---|---|---|
| 域名过滤 | ✓ | ✗ | ✓ | 视 provider |
| 内容量控制 | ✓(单条限制) | ✗ | ✓(总量限制) | ✗ |
| API Key | 服务端 | BYOK | 服务端 | Provider 处理 |
域名过滤
json
{
"type": "openrouter:web_search",
"parameters": {
"allowed_domains": ["arxiv.org", "nature.com"],
"excluded_domains": ["reddit.com"]
}
}各引擎域名过滤支持情况:
| 引擎 | allowed_domains | excluded_domains | 备注 |
|---|---|---|---|
| Exa | ✓ | ✓ | 可同时使用 |
| Parallel | ✓ | ✓ | 互斥,二选一 |
| Firecrawl | ✗ | ✗ | 设置后返回错误 |
| Native (Anthropic) | ✓ | ✓ | 互斥,二选一 |
| Native (OpenAI) | ✓ | ✗ | excluded 被忽略 |
| Native (xAI) | ✓ | ✓ | 互斥,二选一 |
| Native (Perplexity) | ✗ | ✗ | 不支持 |
控制总结果数
在 Agent 循环中控制费用和 context 用量:
json
{
"type": "openrouter:web_search",
"parameters": {
"max_results": 5,
"max_total_results": 15
}
}达到上限后,后续搜索调用会返回"已达到限制"提示,不再执行真实搜索。
Responses API 支持
javascript
const response = await fetch('https://openrouter.ai/api/v1/responses', {
method: 'POST',
headers: {
Authorization: 'Bearer <OPENROUTER_API_KEY>',
'Content-Type': 'application/json',
},
body: JSON.stringify({
model: 'openai/gpt-4o',
input: '今天比特币价格是多少?',
tools: [
{ type: 'openrouter:web_search', parameters: { max_results: 3 } }
]
}),
});用量追踪
搜索用量记录在响应 usage 对象中:
json
{
"usage": {
"input_tokens": 105,
"output_tokens": 250,
"server_tool_use": {
"web_search_requests": 2
}
}
}web_search_requests 记录模型在这次请求中发起的搜索次数。
费用
| 引擎 | 费用 |
|---|---|
| Exa | 每 1000 条结果 $4(默认 5 条 = 最多 $0.02/次搜索) |
| Parallel | 每 1000 条结果 $4(与 Exa 相同) |
| Firecrawl | 直接使用你的 Firecrawl credits,OpenRouter 不收费 |
| Native | 由 provider 收费(OpenAI、Anthropic、Perplexity、xAI 各有定价) |
费用均叠加在处理请求和响应的标准 LLM token 费用之上。
从旧版 Web Search Plugin 迁移
旧版 plugins 数组方式已弃用,请迁移到新版 tools 数组方式。
主要差异:
| 对比项 | Web Search Plugin(已弃用) | Web Search Server Tool |
|---|---|---|
| 启用方式 | plugins: [{ id: "web" }] | tools: [{ type: "openrouter:web_search" }] |
| 搜索决策 | 每次请求固定搜索一次 | 模型自主决定是否/何时搜索 |
| 调用次数 | 1 次 | 0 到多次 |
| 总结果上限 | 无 | 有(max_total_results) |
迁移示例:
json
// 旧版(已弃用)
{
"model": "openai/gpt-4o",
"messages": [...],
"plugins": [{ "id": "web", "max_results": 3 }]
}
// 新版
{
"model": "openai/gpt-4o",
"messages": [...],
"tools": [
{ "type": "openrouter:web_search", "parameters": { "max_results": 3 } }
]
}json
// 旧版(:online 变体)
{ "model": "openai/gpt-4o:online" }
// 新版
{
"model": "openai/gpt-4o",
"tools": [{ "type": "openrouter:web_search" }]
}常见问题
Q: 模型一定会搜索吗?
A: 不一定。模型自主判断是否需要搜索。用户问"今天 XX 新闻"时大概率触发;问历史知识时可能直接回答。如需确保触发,可在系统提示中明确说明"当用户问到时效性问题时,必须使用搜索工具"。
Q: 如何控制搜索费用?
A: 使用 max_total_results 限制整个请求中所有搜索的总结果数。例如设置为 10,模型最多获取 10 条结果后就不能再搜索了。对于 Agent 循环场景,这是控制费用最有效的参数。
Q: Exa 和 Parallel 引擎的区别是什么?
A: 两者费用相同(每 1000 条 $4),都支持域名过滤。主要差异在内容量控制:Exa 的 search_context_size 控制每条结果的字符数;Parallel 的 search_context_size 控制所有结果的总字符数。如果需要精确控制每条结果的信息量,选 Exa;需要控制总 token 消耗,选 Parallel。