WebSearchTool:联网搜索
这个工具到底做什么
WebSearchTool 负责让 Claude Code 查询互联网的最新信息。
它解决的核心问题不是“打开某个网页”,而是:
当主线程需要知道当前世界上最近发生了什么、某个产品最新文档是什么、某个问题有哪些公开资料时,如何安全地发起联网搜索。
所以它和 WebFetchTool 的区别一定要先记清:
WebSearchTool:找信息源WebFetchTool:读指定页面
在真实使用里,这两个工具经常是一前一后配合。
它的 schema 很简单,但能力很强
tools/WebSearchTool/WebSearchTool.ts:
const inputSchema = z.strictObject({
query: z.string().min(2).describe('The search query to use'),
allowed_domains: z.array(z.string()).optional(),
blocked_domains: z.array(z.string()).optional(),
})
看起来只有 3 个字段,但已经涵盖了最关键的搜索控制:
- 搜什么
- 只搜哪些域名
- 排除哪些域名
这意味着 Claude Code 的联网搜索不是“随便搜一下”,而是支持受约束的搜索。
它不是 Bash 调搜索引擎,而是接 Anthropic 的 Web Search 能力
源码里最关键的一段是这部分工具 schema 构造:
function makeToolSchema(input: Input): BetaWebSearchTool20250305 {
return {
type: 'web_search_20250305',
name: 'web_search',
allowed_domains: input.allowed_domains,
blocked_domains: input.blocked_domains,
max_uses: 8,
}
}
这说明 WebSearchTool 不是自己去模拟浏览器,也不是 shell 调第三方搜索接口。
它实际上是把官方的 Web Search server tool 接进了 Claude Code 的工具系统。
换句话说,它做的是:
由 Claude Code 主线程触发,再由底层支持 Web Search 的模型能力去执行搜索
一张图看搜索链路
它的核心调用方式很值得研究
call() 里这段代码最能说明它的本质:
const queryStream = queryModelWithStreaming({
messages: [userMessage],
systemPrompt: asSystemPrompt([
'You are an assistant for performing a web search tool use',
]),
tools: [],
options: {
extraToolSchemas: [toolSchema],
querySource: 'web_search_tool',
...
},
})
这里有几个关键点:
- 它自己重新发起了一次模型调用
- 这次调用的目的不是普通回答,而是执行搜索
- 搜索工具是通过
extraToolSchemas注入进去的
这说明 WebSearchTool 其实是一个包装型工具:
- 外层是 Claude Code 的标准工具
- 内层再发起一次支持 web search 的模型请求
它为什么不是直接把结果返回,而是要先解析内容块
源码里有一段非常关键的解析逻辑:
function makeOutputFromSearchResponse(
result: BetaContentBlock[],
query: string,
durationSeconds: number,
): Output
注释写得很直白:返回内容不是一个单纯数组,而是一串混合块:
server_tool_useweb_search_tool_resulttext- citation 相关块
所以 WebSearchTool 的一个核心工作就是:
把底层返回的搜索结果块重新整理成 Claude Code 更容易消费的结构
它的输出其实是“搜索结果 + 说明文本”的混合体
输出 schema 里有一段非常重要:
results: z
.array(z.union([searchResultSchema(), z.string()]))
.describe('Search results and/or text commentary from the model')
这意味着返回结果不是纯搜索命中列表,而可能同时包含:
- 一组搜索 hits
- 一段文字说明
换句话说,WebSearchTool 并不是只把链接丢回来,而是允许模型在搜索结果外再补一些中间解释。
这也是它比普通搜索 API 更像 Agent 工具的地方
普通搜索 API 常常返回:
- 标题
- URL
- 摘要
而 Claude Code 的 WebSearchTool 还会处理:
- 工具调用块
- 文本解释块
- 引用与来源要求
这让它更适合直接接入主循环,而不是只当一个数据源。
prompt 里对“来源”要求非常严格
tools/WebSearchTool/prompt.ts:
CRITICAL REQUIREMENT - You MUST follow this:
- After answering the user's question, you MUST include a "Sources:" section at the end of your response
- In the Sources section, list all relevant URLs from the search results as markdown hyperlinks
这说明 Anthropic 对这个工具的产品要求很明确:
- 只要用了联网搜索
- 最终回答里就应该带来源
这对可信度和可验证性非常重要。
一张图看它和回答生成的关系
从产品角度看,这也是 Claude Code 比“模型偷偷搜一下然后不告诉你来源”更成熟的地方。
它还会强制提醒“用当前年份搜索”
getWebSearchPrompt() 里还有一条很有意思的约束:
IMPORTANT - Use the correct year in search queries:
- The current month is ${currentMonthYear}. You MUST use this year when searching for recent information
这说明 Anthropic 已经意识到一个非常真实的问题:
如果模型搜“latest React docs”却没带当前年份,很可能召回到旧内容
所以 prompt 明确要求它在搜“最新信息”时带上当前年份。
这是一个很典型的产品化修补动作。
它并不是在所有环境里都能开
isEnabled() 里可以看到它会检查 provider 和 model:
if (provider === 'firstParty') return true
if (provider === 'vertex') {
const supportsWebSearch =
model.includes('claude-opus-4') ||
model.includes('claude-sonnet-4') ||
model.includes('claude-haiku-4')
return supportsWebSearch
}
if (provider === 'foundry') return true
return false
这说明 WebSearchTool 不是“所有 Claude Code 运行环境都能用”的固定能力。
它会受到:
- API provider
- 模型能力
- 平台支持情况
的共同影响。
这也是为什么这类工具要单独做 isEnabled()。
它的权限模型和 WebFetch 不一样
WebSearchTool 的权限逻辑更粗一点:
async checkPermissions(_input): Promise<PermissionResult> {
return {
behavior: 'passthrough',
message: 'WebSearchTool requires permission.',
suggestions: [
{
type: 'addRules',
rules: [{ toolName: WEB_SEARCH_TOOL_NAME }],
behavior: 'allow',
destination: 'localSettings',
},
],
}
}
这说明它更偏“工具级权限”,不像 WebFetchTool 细化到域名级规则。
原因也很好理解:
WebSearchTool处理的是泛化搜索WebFetchTool处理的是具体 URL 访问
后者在安全边界上天然更细。
它和 WebFetchTool 是最经典的一前一后组合
这两者的配合关系几乎可以画成固定模板:
这个链路特别适合:
- 最新文档查询
- 新闻或最近公告
- 对比多个资料来源
- 从搜索命中里继续深挖单个页面
一次典型使用路径
比如用户问:
Claude Code 官方命令页最近怎么写
/usage的?
主线程常见路径会是:
WebSearchTool搜官方文档或特定域名- 找到命令文档页
- 再交给
WebFetchTool抓正文 - 最后组织回答并附上来源
这就是为什么 WebSearchTool 更像“找入口”,而不是“直接完成研究”。
最容易误解它的地方
误解一:WebSearchTool 就是搜索引擎 API 包装
不完全对。
它还包括:
- 模型发起的 server tool 调用
- 内容块解析
- 来源约束
- 环境与 provider 判定
误解二:有了 WebSearchTool 就不需要 WebFetchTool
也不对。
搜索结果通常只是入口,真正看正文往往还得 WebFetchTool。
误解三:它总能搜到最新内容
它只是提供联网搜索能力,不等于结果一定完美。
所以 Anthropic 还专门在 prompt 里要求:
- 使用当前年份
- 回答时列来源
这些都是为了降低“搜到旧资料”或“说不清来源”的风险。
小结
如果用一句话总结:
WebSearchTool是 Claude Code 的联网检索入口,它通过官方 web search schema 发起搜索,再把底层搜索结果块整理成主循环可消费的结构化结果。
它真正重要的地方,不只是“能搜”,而是:
能把搜索结果、来源约束、模型环境和后续网页深读串成一条完整的联网工作流。