OpenRouter Responses API Beta Web Search:联网搜索与引用注解

Responses API Beta 通过 plugins: [{ id: 'web' }] 参数启用网页搜索能力,也可使用 模型名:online 变体(如 openai/o4-mini:online)。搜索结果以 url_citation 注解的形式内联在响应文本中,每条注解包含 URL 和对应的文本范围(start_index/end_index)。xAI 模型额外支持 x_search_filter 参数过滤 X/Twitter 帖子。

Beta API:该 API 处于 beta 阶段,可能存在破坏性变更。

基础网页搜索

通过 plugins 参数启用 web 搜索:

const response = await fetch('https://openrouter.ai/api/v1/responses', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_OPENROUTER_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    model: 'openai/o4-mini',
    input: 'What was a positive news story from today?',
    plugins: [{ id: 'web', max_results: 2 }],
    max_output_tokens: 9000,
  }),
});

const result = await response.json();
console.log(result);

Online 模型变体

部分模型提供内置网页搜索的 :online 变体,无需额外配置 plugins:

body: JSON.stringify({
  model: 'openai/o4-mini:online',
  input: 'What was a positive news story from today?',
  max_output_tokens: 9000,
}),

X 搜索过滤器(仅 xAI 模型)

使用 xAI 模型(如 x-ai/grok-4.1-fast)时,可通过 x_search_filter 过滤 X/Twitter 搜索结果:

{
  "model": "x-ai/grok-4.1-fast",
  "input": "What are people saying about AI?",
  "plugins": [{ "id": "web" }],
  "x_search_filter": {
    "allowed_x_handles": ["OpenRouterAI"],
    "from_date": "2025-01-01",
    "enable_image_understanding": true
  }
}
参数 类型 说明
allowed_x_handles string[] 只包含这些账号的帖子(最多 10 个)
excluded_x_handles string[] 排除这些账号的帖子(最多 10 个)
from_date string 开始日期(ISO 8601,如 "2025-01-01"
to_date string 结束日期(ISO 8601)
enable_image_understanding boolean 分析帖子中的图片
enable_video_understanding boolean 分析帖子中的视频

注意:allowed_x_handlesexcluded_x_handles 互斥,不能同时设置。

带引用注解的响应格式

网页搜索响应会在文本内容的 annotations 数组中包含引用信息:

{
  "output": [
    {
      "type": "message",
      "id": "msg_abc123",
      "status": "completed",
      "role": "assistant",
      "content": [
        {
          "type": "output_text",
          "text": "OpenRouter is a unified API for accessing multiple LLM providers...",
          "annotations": [
            {
              "type": "url_citation",
              "url": "https://openrouter.ai/docs",
              "start_index": 0,
              "end_index": 85
            },
            {
              "type": "url_citation",
              "url": "https://openrouter.ai/models",
              "start_index": 120,
              "end_index": 180
            }
          ]
        }
      ]
    }
  ]
}

start_indexend_index 表示引用对应的文本范围(字符索引)。

引用注解处理

function extractCitations(response: any) {
  const messageOutput = response.output?.find((o: any) => o.type === 'message');
  const textContent = messageOutput?.content?.find((c: any) => c.type === 'output_text');
  const annotations = textContent?.annotations || [];

  return annotations
    .filter((annotation: any) => annotation.type === 'url_citation')
    .map((annotation: any) => ({
      url: annotation.url,
      text: textContent.text.slice(annotation.start_index, annotation.end_index),
      startIndex: annotation.start_index,
      endIndex: annotation.end_index,
    }));
}

const result = await response.json();
const citations = extractCitations(result);
console.log('Found citations:', citations);

Streaming 网页搜索

streaming 模式下可实时监控搜索进度:

  • response.output_item.addeditem.type === 'message')— 消息开始生成
  • response.completed — 搜索和响应全部完成,可从 response.output 中提取引用

最佳实践

  1. 控制结果数量:合理设置 max_results,平衡搜索质量和速度
  2. 处理引用:解析 annotations 数组,为用户展示来源信息
  3. 精确查询:搜索词越具体,结果越相关
  4. 异常处理:网页搜索可能因网络或限流失败,需要做好兜底
  5. 频率限制:注意搜索调用的频率限制

常见问题

Q: plugins: [{ id: 'web' }]:online 模型变体有什么区别?

A: 两者都能启用网页搜索,但实现机制不同。plugins 是通用的插件配置方式,适用于任何支持的模型;:online 变体是模型层面的内置搜索能力,通常由模型提供商直接支持。建议优先使用 plugins 方式,兼容性更广。

Q: max_results 最大可以设多少?

A: 没有明确的文档限制,但建议不超过 5-10 条,避免过多搜索结果增加 token 消耗和响应时间。

Q: 搜索结果的实时性如何?

A: 这取决于搜索引擎的索引频率。通常可以获取近期新闻和最新信息,但并非实时(几分钟内的内容可能无法获取)。