12-Web工具

12. Web工具族 - WebSearch与WebFetch

所属分组:工具系统

概述

Web 工具族是 Claude Code 中实现网络信息获取的核心工具集,包括 WebSearchTool 和 WebFetchTool。这两个工具分别负责网络搜索和网页内容抓取,为 Claude 提供实时的外部信息获取能力,弥补模型训练数据的时效性限制。

WebSearchTool 通过调用 Anthropic 的 Web Search API 执行实时搜索,支持查询过滤和结果汇总;WebFetchTool 则负责从指定 URL 抓取内容,并支持通过提示词对内容进行处理。本文将深入分析这两个工具的实现机制、权限控制、内容处理流程以及与模型的交互方式。

源码位置

  • WebSearchTool 核心实现:tools/WebSearchTool/WebSearchTool.ts(file:///e:/2026plan/AI_Lab/claude-code-sourcemap-main/restored-src/src/tools/WebSearchTool/WebSearchTool.ts)
  • WebSearchTool UI 组件:tools/WebSearchTool/UI.tsx(file:///e:/2026plan/AI_Lab/claude-code-sourcemap-main/restored-src/src/tools/WebSearchTool/UI.tsx)
  • WebSearchTool 提示词:tools/WebSearchTool/prompt.ts(file:///e:/2026plan/AI_Lab/claude-code-sourcemap-main/restored-src/src/tools/WebSearchTool/prompt.ts)
  • WebFetchTool 核心实现:tools/WebFetchTool/WebFetchTool.ts(file:///e:/2026plan/AI_Lab/claude-code-sourcemap-main/restored-src/src/tools/WebFetchTool/WebFetchTool.ts)
  • WebFetchTool UI 组件:tools/WebFetchTool/UI.tsx(file:///e:/2026plan/AI_Lab/claude-code-sourcemap-main/restored-src/src/tools/WebFetchTool/UI.tsx)
  • WebFetchTool 提示词:tools/WebFetchTool/prompt.ts(file:///e:/2026plan/AI_Lab/claude-code-sourcemap-main/restored-src/src/tools/WebFetchTool/prompt.ts)
  • WebFetchTool 工具函数:tools/WebFetchTool/utils.ts(file:///e:/2026plan/AI_Lab/claude-code-sourcemap-main/restored-src/src/tools/WebFetchTool/utils.ts)
  • WebFetchTool 预批准列表:tools/WebFetchTool/preapproved.ts(file:///e:/2026plan/AI_Lab/claude-code-sourcemap-main/restored-src/src/tools/WebFetchTool/preapproved.ts)

核心实现分析

WebSearchTool 实现机制

WebSearchTool 的核心实现位于 tools/WebSearchTool/WebSearchTool.ts,它通过调用 Anthropic 的 Web Search API 执行实时搜索:

ts 复制代码
export const WebSearchTool = buildTool({
  name: WEB_SEARCH_TOOL_NAME,
  searchHint: 'search the web for current information',
  maxResultSizeChars: 100_000,
  shouldDefer: true,
  async description(input) {
    return `Claude wants to search the web for: ${input.query}`
  },
  // ... 其他配置
} satisfies ToolDef<InputSchema, Output, WebSearchProgress>)
输入输出 Schema
ts 复制代码
const inputSchema = lazySchema(() =>
  z.strictObject({
    query: z.string().min(2).describe('The search query to use'),
    allowed_domains: z
      .array(z.string())
      .optional()
      .describe('Only include search results from these domains'),
    blocked_domains: z
      .array(z.string())
      .optional()
      .describe('Never include search results from these domains'),
  }),
)

const outputSchema = lazySchema(() =>
  z.object({
    query: z.string().describe('The search query that was executed'),
    results: z
      .array(z.union([searchResultSchema(), z.string()]))
      .describe('Search results and/or text commentary from the model'),
    durationSeconds: z
      .number()
      .describe('Time taken to complete the search operation'),
  }),
)

WebSearchTool 支持查询词、允许域名列表和阻止域名列表作为输入参数,输出包含查询结果和文本摘要的组合。

搜索执行流程

call 方法实现了完整的搜索执行流程:

  1. 构建工具 Schema:将用户输入转换为 Anthropic Web Search API 所需的格式
  2. 调用模型 :使用 queryModelWithStreaming 发送搜索请求,支持流式响应
  3. 处理流式结果 :解析 server_tool_useweb_search_tool_result 事件,提取搜索结果
  4. 生成输出:将搜索结果和模型摘要组合成最终输出

关键代码片段:

ts 复制代码
const toolSchema = makeToolSchema(input)
const queryStream = queryModelWithStreaming({
  messages: [userMessage],
  systemPrompt: asSystemPrompt(['You are an assistant for performing a web search tool use']),
  tools: [],
  signal: context.abortController.signal,
  options: {
    model: useHaiku ? getSmallFastModel() : context.options.mainLoopModel,
    extraToolSchemas: [toolSchema],
    querySource: 'web_search_tool',
    // ...
  },
})
平台兼容性

WebSearchTool 根据不同的 API 提供商判断是否启用:

ts 复制代码
isEnabled() {
  const provider = getAPIProvider()
  const model = getMainLoopModel()

  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
}

WebFetchTool 实现机制

WebFetchTool 负责从指定 URL 抓取内容,并支持通过提示词对内容进行处理:

ts 复制代码
export const WebFetchTool = buildTool({
  name: WEB_FETCH_TOOL_NAME,
  searchHint: 'fetch and extract content from a URL',
  maxResultSizeChars: 100_000,
  shouldDefer: true,
  // ... 其他配置
} satisfies ToolDef<InputSchema, Output>)
输入输出 Schema
ts 复制代码
const inputSchema = lazySchema(() =>
  z.strictObject({
    url: z.string().url().describe('The URL to fetch content from'),
    prompt: z.string().describe('The prompt to run on the fetched content'),
  }),
)

const outputSchema = lazySchema(() =>
  z.object({
    bytes: z.number().describe('Size of the fetched content in bytes'),
    code: z.number().describe('HTTP response code'),
    codeText: z.string().describe('HTTP response code text'),
    result: z.string().describe('Processed result from applying the prompt to the content'),
    durationMs: z.number().describe('Time taken to fetch and process the content'),
    url: z.string().describe('The URL that was fetched'),
  }),
)

WebFetchTool 需要 URL 和提示词两个参数,输出包含抓取内容的处理结果。

权限控制机制

WebFetchTool 实现了多层次的权限控制:

  1. 预批准域名检查 :通过 isPreapprovedHost 检查域名是否在预批准列表中
  2. 规则匹配 :根据 denyaskallow 三种规则类型进行权限判断
  3. 动态授权建议:提供添加允许规则的建议,方便用户快速授权

关键代码片段:

ts 复制代码
async checkPermissions(input, context): Promise<PermissionDecision> {
  // 检查预批准列表
  if (isPreapprovedHost(parsedUrl.hostname, parsedUrl.pathname)) {
    return { behavior: 'allow', updatedInput: input, decisionReason: { type: 'other', reason: 'Preapproved host' } }
  }

  // 检查 deny 规则
  const denyRule = getRuleByContentsForTool(permissionContext, WebFetchTool, 'deny').get(ruleContent)
  if (denyRule) {
    return { behavior: 'deny', message: `${WebFetchTool.name} denied access to ${ruleContent}.`, decisionReason: { type: 'rule', rule: denyRule } }
  }

  // 检查 ask 规则
  const askRule = getRuleByContentsForTool(permissionContext, WebFetchTool, 'ask').get(ruleContent)
  if (askRule) {
    return { behavior: 'ask', suggestions: buildSuggestions(ruleContent) }
  }

  // 默认行为:询问用户
  return { behavior: 'ask', suggestions: buildSuggestions(ruleContent) }
}
内容处理流程

call 方法实现了完整的内容抓取和处理流程:

  1. URL 获取 :调用 getURLMarkdownContent 获取网页内容
  2. 重定向检测:检查是否存在跨域重定向,若有则提示用户重新调用
  3. 内容处理:根据内容类型和大小决定是否直接返回或通过模型处理
  4. 二进制内容处理:对于 PDF 等二进制内容,保存到本地并在结果中提示

关键代码片段:

ts 复制代码
const response = await getURLMarkdownContent(url, abortController)

// 重定向检测
if ('type' in response && response.type === 'redirect') {
  const message = `REDIRECT DETECTED: The URL redirects to a different host.
Original URL: ${response.originalUrl}
Redirect URL: ${response.redirectUrl}
...`
  return { data: { bytes: Buffer.byteLength(message), code: response.statusCode, ... } }
}

// 内容处理
let result: string
if (isPreapproved && contentType.includes('text/markdown') && content.length < MAX_MARKDOWN_LENGTH) {
  result = content
} else {
  result = await applyPromptToMarkdown(prompt, content, abortController.signal, isNonInteractiveSession, isPreapproved)
}

结果渲染

两个工具都通过 mapToolResultToToolResultBlockParam 方法将结果转换为模型可理解的格式:

ts 复制代码
// WebSearchTool
mapToolResultToToolResultBlockParam(output, toolUseID) {
  const { query, results } = output
  let formattedOutput = `Web search results for query: "${query}"\n\n`
  // ... 处理结果
  formattedOutput += '\nREMINDER: You MUST include the sources above in your response to the user using markdown hyperlinks.'
  return { tool_use_id: toolUseID, type: 'tool_result', content: formattedOutput.trim() }
}

// WebFetchTool
mapToolResultToToolResultBlockParam({ result }, toolUseID) {
  return { tool_use_id: toolUseID, type: 'tool_result', content: result }
}

关键设计要点

  1. 预批准机制:WebFetchTool 通过预批准域名列表实现安全的零授权访问,支持文档、博客等公共内容的快速获取
  2. 重定向防护:检测跨域重定向并阻止自动跟随,防止钓鱼攻击和权限绕过
  3. 流式搜索:WebSearchTool 支持流式搜索结果,实时显示搜索进度
  4. 平台适配:根据 API 提供商和模型类型动态决定是否启用搜索功能
  5. 内容处理策略:根据内容类型和大小采用不同的处理策略,平衡性能和质量

与其他模块的关系

  • 工具系统:WebSearchTool 和 WebFetchTool 是工具系统的重要组成部分,与其他工具并列使用
  • 权限系统:依赖权限系统进行域名级别的访问控制
  • API 服务层 :WebSearchTool 依赖 services/api/claude.ts 中的 queryModelWithStreaming 方法
  • 配置系统:预批准域名列表通过配置系统管理
  • UI 层 :通过各自的 UI.tsx 组件提供工具使用和结果的终端渲染

小结

Web 工具族为 Claude Code 提供了实时网络信息获取能力,WebSearchTool 支持实时搜索和结果汇总,WebFetchTool 支持网页内容抓取和处理。两个工具都实现了完善的权限控制机制,通过预批准列表和规则匹配确保安全访问。其设计体现了安全性和可用性的平衡,为用户提供了灵活而安全的网络信息获取方式。

相关推荐
爱分享的程序猿-Clark9 小时前
【前端分享】大前端监控体系搭建实战
前端
夕除9 小时前
sign 是什么
java·前端
An_s9 小时前
Android仿真翻页(一),基于pagecurl二开
前端·javascript·html
weixin_462901979 小时前
网页 HTML ↔ ESP32 完整通信体系详解
前端·html
禅思院9 小时前
Agent记忆管理,是一场工程上的平衡艺术
前端·架构·ai编程
crary,记忆9 小时前
React Hook 浅学 2.0 - 自定义Hook
前端·react.js·前端框架
触底反弹9 小时前
🔥 React 零基础入门(下):Props + State + useEffect 生命周期深度解析
前端·react.js·面试
Lalolander9 小时前
金蝶 ERP 项目延期交付怎么办?ERP 拖期原因与补救方案
大数据·制造·金蝶erp·erp集成·半导体行业数字化转型·金众诚科技
咖啡星人k9 小时前
GitHub Copilot 加入 Agent 浏览器:验证 Web 应用进入编码闭环
前端·人工智能·github·copilot·前端开发·ai agent