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)仍然可用,但不支持动态过滤。
对于 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 请求时:
- Claude 根据提示决定何时搜索。
- API 执行搜索并将结果提供给 Claude。此过程在单个请求中可能重复多次。
- 在轮次结束时,Claude 提供带有引用来源的最终响应。
动态过滤
Web search 是一项 token 密集型任务。使用基本 web search 时,Claude 需要将搜索结果拉入上下文,从多个网站获取完整 HTML,并在得出答案之前对所有内容进行推理。通常,大部分内容是无关的,这可能会降低响应质量。
使用 web_search_20260209 工具版本,Claude 可以编写和执行代码来后处理查询结果。Claude 不再对完整 HTML 文件进行推理,而是在将搜索结果加载到上下文之前动态过滤,只保留相关内容并丢弃其余内容。
动态过滤特别适用于:
- 搜索技术文档
- 文献综述和引用验证
- 技术研究
- 响应基础和验证
动态过滤需要启用 code execution tool。Web search tool(带和不带动态过滤)在 Claude API、AWS 上的 Claude Platform 和 Microsoft 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
如何使用 web search
你组织的管理员必须在 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_domains 和 blocked_domains 进行域名过滤,请参见服务器工具。
本地化
user_location 参数允许你根据用户位置本地化搜索结果。
type:位置类型(必须为approximate)city:城市名称region:地区或州country:国家timezone:IANA 时区 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:来源页面的 URLtitle:来源页面的标题page_age:网站最后更新时间encrypted_content:加密内容,必须在多轮对话中传回以用于引用
引用
Web search 始终启用引用,每个 web_search_result_location 包括:
url:引用来源的 URLtitle:引用来源的标题encrypted_index:必须在多轮对话中传回的引用。cited_text:最多 150 个字符的引用内容
Web search 引用字段 cited_text、title 和 url 不计入输入或输出 token 使用量。
直接向最终用户显示 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 期间发生错误,则不收费。