Web search tool


Web search tool 让 Claude 直接访问实时网络内容,使其能够用超出知识截止日期的最新信息回答问题。响应包含从搜索结果中提取的来源引用。

最新版本的 web search tool(web_search_20260209)支持 Claude Mythos Preview、Claude Opus 4.7、Claude Opus 4.6 和 Claude Sonnet 4.6 的动态过滤。Claude 可以编写和执行代码,在搜索结果到达上下文窗口之前进行过滤,只保留相关信息并丢弃其余内容。这会产生更准确的响应,同时减少 token 消耗。之前的工具版本(web_search_20250305)仍然可用,但不支持动态过滤。

Note

对于 Claude Mythos Preview,web search 在 Claude API、Microsoft Foundry 和 Vertex AI 上受支持。Mythos Preview 在 Amazon Bedrock 或 AWS 上的 Claude Platform 上不支持 web search。

零数据留存资格和 allowed_callers 变通方案,请参见服务器工具

模型支持参见工具参考

Web search 的工作原理

当你将 web search tool 添加到 API 请求时:

  1. Claude 根据提示决定何时搜索。
  2. API 执行搜索并将结果提供给 Claude。此过程在单个请求中可能重复多次。
  3. 在轮次结束时,Claude 提供带有引用来源的最终响应。

动态过滤

Web search 是一项 token 密集型任务。使用基本 web search 时,Claude 需要将搜索结果拉入上下文,从多个网站获取完整 HTML,并在得出答案之前对所有内容进行推理。通常,大部分内容是无关的,这可能会降低响应质量。

使用 web_search_20260209 工具版本,Claude 可以编写和执行代码来后处理查询结果。Claude 不再对完整 HTML 文件进行推理,而是在将搜索结果加载到上下文之前动态过滤,只保留相关内容并丢弃其余内容。

动态过滤特别适用于:

  • 搜索技术文档
  • 文献综述和引用验证
  • 技术研究
  • 响应基础和验证
Note

动态过滤需要启用 code execution tool。Web search tool(带和不带动态过滤)在 Claude API、AWS 上的 Claude PlatformMicrosoft Foundry 上可用。在 Vertex AI 上,仅基本 web search tool(不带动态过滤)可用。Web search 在 Amazon Bedrock 上不可用。

要启用动态过滤,请使用 web_search_20260209 工具版本:

curl https://api.anthropic.com/v1/messages \
    --header "x-api-key: $ANTHROPIC_API_KEY" \
    --header "anthropic-version: 2023-06-01" \
    --header "content-type: application/json" \
    --data '{
        "model": "claude-opus-4-7",
        "max_tokens": 4096,
        "messages": [
            {
                "role": "user",
                "content": "Search for the current prices of AAPL and GOOGL, then calculate which has a better P/E ratio."
            }
        ],
        "tools": [{
            "type": "web_search_20260209",
            "name": "web_search"
        }]
    }'
ant messages create <<'YAML'
model: claude-opus-4-7
max_tokens: 4096
messages:
  - role: user
    content: >-
      Search for the current prices of AAPL and GOOGL, then calculate
      which has a better P/E ratio.
tools:
  - type: web_search_20260209
    name: web_search
YAML
import anthropic

client = anthropic.Anthropic()

response = client.messages.create(
    model="claude-opus-4-7",
    max_tokens=4096,
    messages=[
        {
            "role": "user",
            "content": "Search for the current prices of AAPL and GOOGL, then calculate which has a better P/E ratio.",
        }
    ],
    tools=[{"type": "web_search_20260209", "name": "web_search"}],
)
print(response)
import Anthropic from "@anthropic-ai/sdk";

const anthropic = new Anthropic();

const response = await anthropic.messages.create({
  model: "claude-opus-4-7",
  max_tokens: 4096,
  messages: [
    {
      role: "user",
      content:
        "Search for the current prices of AAPL and GOOGL, then calculate which has a better P/E ratio."
    }
  ],
  tools: [{ type: "web_search_20260209", name: "web_search" }]
});

console.log(response);
using Anthropic;
using Anthropic.Models.Messages;

AnthropicClient client = new();

var parameters = new MessageCreateParams
{
    Model = Model.ClaudeOpus4_7,
    MaxTokens = 4096,
    Messages = [new() { Role = Role.User, Content = "Search for the current prices of AAPL and GOOGL, then calculate which has a better P/E ratio." }],
    Tools = [new ToolUnion(new WebSearchTool20260209())]
};

var message = await client.Messages.Create(parameters);
Console.WriteLine(message);
package main

import (
	"context"
	"fmt"
	"log"

	"github.com/anthropics/anthropic-sdk-go"
)

func main() {
	client := anthropic.NewClient()

	response, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{
		Model:     anthropic.ModelClaudeOpus4_7,
		MaxTokens: 4096,
		Messages: []anthropic.MessageParam{
			anthropic.NewUserMessage(anthropic.NewTextBlock("Search for the current prices of AAPL and GOOGL, then calculate which has a better P/E ratio.")),
		},
		Tools: []anthropic.ToolUnionParam{
			{OfWebSearchTool20260209: &anthropic.WebSearchTool20260209Param{}},
		},
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(response)
}
import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;
import com.anthropic.models.messages.Message;
import com.anthropic.models.messages.MessageCreateParams;
import com.anthropic.models.messages.Model;
import com.anthropic.models.messages.WebSearchTool20260209;

void main() {
    AnthropicClient client = AnthropicOkHttpClient.fromEnv();

    MessageCreateParams params = MessageCreateParams.builder()
        .model(Model.CLAUDE_OPUS_4_7)
        .maxTokens(4096L)
        .addUserMessage("Search for the current prices of AAPL and GOOGL, then calculate which has a better P/E ratio.")
        .addTool(WebSearchTool20260209.builder().build())
        .build();

    Message response = client.messages().create(params);
    IO.println(response);
}
<?php

use Anthropic\Client;

$client = new Client(apiKey: getenv("ANTHROPIC_API_KEY"));

$message = $client->messages->create(
    maxTokens: 4096,
    messages: [
        ['role' => 'user', 'content' => 'Search for the current prices of AAPL and GOOGL, then calculate which has a better P/E ratio.'],
    ],
    model: 'claude-opus-4-7',
    tools: [
        [
            'type' => 'web_search_20260209',
            'name' => 'web_search',
        ],
    ],
);

echo $message;
require "anthropic"

client = Anthropic::Client.new

message = client.messages.create(
  model: "claude-opus-4-7",
  max_tokens: 4096,
  messages: [
    { role: "user", content: "Search for the current prices of AAPL and GOOGL, then calculate which has a better P/E ratio." }
  ],
  tools: [{
    type: "web_search_20260209",
    name: "web_search"
  }]
)
puts message
Note

你组织的管理员必须在 Claude Console 中启用 web search。

在 API 请求中提供 web search tool:

curl https://api.anthropic.com/v1/messages \
    --header "x-api-key: $ANTHROPIC_API_KEY" \
    --header "anthropic-version: 2023-06-01" \
    --header "content-type: application/json" \
    --data '{
        "model": "claude-opus-4-7",
        "max_tokens": 1024,
        "messages": [
            {
                "role": "user",
                "content": "What is the weather in NYC?"
            }
        ],
        "tools": [{
            "type": "web_search_20250305",
            "name": "web_search",
            "max_uses": 5
        }]
    }'
ant messages create \
  --model claude-opus-4-7 \
  --max-tokens 1024 \
  --message '{role: user, content: What is the weather in NYC?}' \
  --tool '{type: web_search_20250305, name: web_search, max_uses: 5}'
import anthropic

client = anthropic.Anthropic()

response = client.messages.create(
    model="claude-opus-4-7",
    max_tokens=1024,
    messages=[{"role": "user", "content": "What's the weather in NYC?"}],
    tools=[{"type": "web_search_20250305", "name": "web_search", "max_uses": 5}],
)
print(response)
import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic();

async function main() {
  const response = await client.messages.create({
    model: "claude-opus-4-7",
    max_tokens: 1024,
    messages: [
      {
        role: "user",
        content: "What's the weather in NYC?"
      }
    ],
    tools: [
      {
        type: "web_search_20250305",
        name: "web_search",
        max_uses: 5
      }
    ]
  });

  console.log(response);
}

main().catch(console.error);
using Anthropic;
using Anthropic.Models.Messages;

AnthropicClient client = new();

var parameters = new MessageCreateParams
{
    Model = Model.ClaudeOpus4_7,
    MaxTokens = 1024,
    Messages = [new() { Role = Role.User, Content = "What's the weather in NYC?" }],
    Tools = [new ToolUnion(new WebSearchTool20250305() { MaxUses = 5 })]
};

var message = await client.Messages.Create(parameters);
Console.WriteLine(message);
package main

import (
	"context"
	"fmt"
	"log"

	"github.com/anthropics/anthropic-sdk-go"
)

func main() {
	client := anthropic.NewClient()

	response, err := client.Messages.New(context.TODO(), anthropic.MessageNewParams{
		Model:     anthropic.ModelClaudeOpus4_7,
		MaxTokens: 1024,
		Messages: []anthropic.MessageParam{
			anthropic.NewUserMessage(anthropic.NewTextBlock("What's the weather in NYC?")),
		},
		Tools: []anthropic.ToolUnionParam{
			{OfWebSearchTool20250305: &anthropic.WebSearchTool20250305Param{
				MaxUses: anthropic.Int(5),
			}},
		},
	})
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(response)
}
import com.anthropic.client.AnthropicClient;
import com.anthropic.client.okhttp.AnthropicOkHttpClient;
import com.anthropic.models.messages.Message;
import com.anthropic.models.messages.MessageCreateParams;
import com.anthropic.models.messages.Model;
import com.anthropic.models.messages.WebSearchTool20250305;

void main() {
    AnthropicClient client = AnthropicOkHttpClient.fromEnv();

    MessageCreateParams params = MessageCreateParams.builder()
        .model(Model.CLAUDE_OPUS_4_7)
        .maxTokens(1024L)
        .addUserMessage("What's the weather in NYC?")
        .addTool(WebSearchTool20250305.builder()
            .maxUses(5L)
            .build())
        .build();

    Message response = client.messages().create(params);
    IO.println(response);
}
<?php

use Anthropic\Client;

$client = new Client(apiKey: getenv("ANTHROPIC_API_KEY"));

$message = $client->messages->create(
    maxTokens: 1024,
    messages: [
        ['role' => 'user', 'content' => "What's the weather in NYC?"],
    ],
    model: 'claude-opus-4-7',
    tools: [
        [
            'type' => 'web_search_20250305',
            'name' => 'web_search',
            'max_uses' => 5,
        ],
    ],
);

echo $message;
require "anthropic"

client = Anthropic::Client.new

message = client.messages.create(
  model: "claude-opus-4-7",
  max_tokens: 1024,
  messages: [
    { role: "user", content: "What's the weather in NYC?" }
  ],
  tools: [{
    type: "web_search_20250305",
    name: "web_search",
    max_uses: 5
  }]
)
puts message

工具定义

Web search tool 支持以下参数:

{
  "type": "web_search_20250305",
  "name": "web_search",

  // 可选:限制每个请求的搜索次数
  "max_uses": 5,

  // 可选:仅包含来自这些域名的结果
  "allowed_domains": ["example.com", "trusteddomain.org"],

  // 可选:永不包含来自这些域名的结果
  "blocked_domains": ["untrustedsource.com"],

  // 可选:本地化搜索结果
  "user_location": {
    "type": "approximate",
    "city": "San Francisco",
    "region": "California",
    "country": "US",
    "timezone": "America/Los_Angeles"
  }
}

最大使用次数

max_uses 参数限制执行的搜索次数。如果 Claude 尝试超过允许的搜索次数,web_search_tool_result 是一个错误,错误码为 max_uses_exceeded

域名过滤

有关使用 allowed_domainsblocked_domains 进行域名过滤,请参见服务器工具

本地化

user_location 参数允许你根据用户位置本地化搜索结果。

  • type:位置类型(必须为 approximate
  • city:城市名称
  • region:地区或州
  • country:国家
  • timezoneIANA 时区 ID

响应

以下是示例响应结构:

{
  "role": "assistant",
  "content": [
    // 1. Claude 决定搜索
    {
      "type": "text",
      "text": "I'll search for when Claude Shannon was born."
    },
    // 2. 使用的搜索查询
    {
      "type": "server_tool_use",
      "id": "srvtoolu_01WYG3ziw53XMcoyKL4XcZmE",
      "name": "web_search",
      "input": {
        "query": "claude shannon birth date"
      }
    },
    // 3. 搜索结果
    {
      "type": "web_search_tool_result",
      "tool_use_id": "srvtoolu_01WYG3ziw53XMcoyKL4XcZmE",
      "content": [
        {
          "type": "web_search_result",
          "url": "https://en.wikipedia.org/wiki/Claude_Shannon",
          "title": "Claude Shannon - Wikipedia",
          "encrypted_content": "EqgfCioIARgBIiQ3YTAwMjY1Mi1mZjM5LTQ1NGUtODgxNC1kNjNjNTk1ZWI3Y...",
          "page_age": "April 30, 2025"
        }
      ]
    },
    {
      "text": "Based on the search results, ",
      "type": "text"
    },
    // 4. Claude 带引用的响应
    {
      "text": "Claude Shannon was born on April 30, 1916, in Petoskey, Michigan",
      "type": "text",
      "citations": [
        {
          "type": "web_search_result_location",
          "url": "https://en.wikipedia.org/wiki/Claude_Shannon",
          "title": "Claude Shannon - Wikipedia",
          "encrypted_index": "Eo8BCioIAhgBIiQyYjQ0OWJmZi1lNm..",
          "cited_text": "Claude Elwood Shannon (April 30, 1916 – February 24, 2001) was an American mathematician, electrical engineer, computer scientist, cryptographer and i..."
        }
      ]
    }
  ],
  "id": "msg_a930390d3a",
  "usage": {
    "input_tokens": 6039,
    "output_tokens": 931,
    "server_tool_use": {
      "web_search_requests": 1
    }
  },
  "stop_reason": "end_turn"
}

搜索结果

搜索结果包括:

  • url:来源页面的 URL
  • title:来源页面的标题
  • page_age:网站最后更新时间
  • encrypted_content:加密内容,必须在多轮对话中传回以用于引用

引用

Web search 始终启用引用,每个 web_search_result_location 包括:

  • url:引用来源的 URL
  • title:引用来源的标题
  • encrypted_index:必须在多轮对话中传回的引用。
  • cited_text:最多 150 个字符的引用内容

Web search 引用字段 cited_texttitleurl 不计入输入或输出 token 使用量。

Note

直接向最终用户显示 API 输出时,必须包含对原始来源的引用。如果你在显示给最终用户之前对 API 输出进行修改,包括重新处理和/或与你自己的材料结合,请根据与法律团队的咨询适当显示引用。

错误

当 web search tool 遇到错误(如达到速率限制)时,Claude API 仍返回 200(成功)响应。错误在响应体中使用以下结构表示:

{
  "type": "web_search_tool_result",
  "tool_use_id": "srvtoolu_a93jad",
  "content": {
    "type": "web_search_tool_result_error",
    "error_code": "max_uses_exceeded"
  }
}

可能的错误码:

  • too_many_requests:超出速率限制
  • invalid_input:无效的搜索查询参数
  • max_uses_exceeded:超出最大 web search tool 使用次数
  • query_too_long:查询超出最大长度
  • unavailable:发生内部错误

pause_turn 停止原因

有关在 pause_turn 停止原因后继续,请参见服务器工具

Prompt caching

有关跨轮次缓存工具定义,请参见工具使用与 prompt caching

流式传输

启用流式传输后,你将作为流的一部分接收搜索事件。搜索执行期间会有暂停:

event: message_start
data: {"type": "message_start", "message": {"id": "msg_abc123", "type": "message"}}

event: content_block_start
data: {"type": "content_block_start", "index": 0, "content_block": {"type": "text", "text": ""}}

// Claude 决定搜索

event: content_block_start
data: {"type": "content_block_start", "index": 1, "content_block": {"type": "server_tool_use", "id": "srvtoolu_xyz789", "name": "web_search"}}

// 搜索查询流式传输
event: content_block_delta
data: {"type": "content_block_delta", "index": 1, "delta": {"type": "input_json_delta", "partial_json": "{\"query\":\"latest quantum computing breakthroughs 2025\"}"}}

// 搜索执行期间暂停

// 搜索结果流式传输
event: content_block_start
data: {"type": "content_block_start", "index": 2, "content_block": {"type": "web_search_tool_result", "tool_use_id": "srvtoolu_xyz789", "content": [{"type": "web_search_result", "title": "Quantum Computing Breakthroughs in 2025", "url": "https://example.com"}]}}

// Claude 带引用的响应(此示例中省略)

批量请求

你可以在 Messages Batches API 中包含 web search tool。通过 Messages Batches API 的 web search tool 调用与常规 Messages API 请求中的定价相同。

使用量和定价

Web search 使用量在 token 使用量之外额外收费:

{
  "usage": {
    "input_tokens": 105,
    "output_tokens": 6039,
    "cache_read_input_tokens": 7123,
    "cache_creation_input_tokens": 7345,
    "server_tool_use": {
      "web_search_requests": 1
    }
  }
}

Web search 在 Claude API 上的定价为每 1,000 次搜索 $10,加上搜索生成内容的标准 token 成本。对话中检索的 web search 结果在单轮中执行的搜索迭代和后续对话轮次中计为输入 token。

每次 web search 计为一次使用,无论返回的结果数量。如果 web search 期间发生错误,则不收费。

下一步