Tools 工具组

WebFetchTool:抓取网页

这个工具到底做什么

WebFetchTool 负责抓取一个已经知道 URL 的网页,把网页内容转成 Claude Code 更容易处理的文本,再根据传入的 prompt 提炼结果。

它和 WebSearchTool 的分工非常明确:

  • WebSearchTool:帮模型去网上找结果
  • WebFetchTool:拿着确定的 URL 去读具体页面

所以你可以把它理解成:

Claude Code 的“网页阅读器 + 小模型摘要器”

而不是“联网搜索工具”。

它的输入为什么只有两个字段

tools/WebFetchTool/WebFetchTool.ts

const inputSchema = 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'),
})

这两个字段刚好对应了它的两步工作:

  1. 先把网页内容抓回来
  2. 再根据 prompt 提炼想要的信息

所以 WebFetchTool 并不是“单纯下载网页”,而是把“抓取”和“阅读”合并成一个完整动作。

一张图看它的完整链路

加载图表中...

它不是直接把网页全文塞回主模型

这是 WebFetchTool 最值得注意的设计点。

tools/WebFetchTool/utils.tsprompt.ts 里,可以看到它会把抓到的网页内容交给一个次级模型处理:

import { queryHaiku } from '../../services/api/claude.js'
import { makeSecondaryModelPrompt } from './prompt.js'

prompt.ts 里定义了这一步的提示词拼装:

export function makeSecondaryModelPrompt(
  markdownContent: string,
  prompt: string,
  isPreapprovedDomain: boolean,
): string {
  return `
Web page content:
---
${markdownContent}
---

${prompt}
`
}

这说明它的真实工作方式是:

  1. 抓网页
  2. 转成 markdown
  3. 把 markdown 和用户/模型给的提问一起交给一个更小更快的模型
  4. 只把提炼后的结果回给主循环

这和“把整页 HTML 全塞进主上下文”相比,节省了很多上下文。

这也是它和浏览器工具最大的不同

WebFetchTool 不是浏览器。
它更像一个面向内容提取的远程阅读器

它不擅长:

  • 登录态页面交互
  • 点击、表单、动态操作
  • 复杂 JS 页面行为模拟

而它擅长的是:

  • 文档页
  • 博客文章
  • 公网说明页
  • 某个 URL 的结构化摘要

所以 Anthropic 在 prompt 里还专门提醒:

IMPORTANT: WebFetch WILL FAIL for authenticated or private URLs.
If so, look for a specialized MCP tool that provides authenticated access.

中文理解

如果这是一个登录态页面、私有文档或者受权限保护的站点,WebFetchTool 很可能失败。
这时更应该找 MCP 工具,或者走别的受认证能力。

权限系统不是按“整个互联网”放行,而是按域名做

WebFetchTool 有一段很关键的权限逻辑:

function webFetchToolInputToPermissionRuleContent(input) {
  const { url } = parsedInput.data
  const hostname = new URL(url).hostname
  return `domain:${hostname}`
}

后面的 checkPermissions() 会围绕这个 domain:hostname 去判断:

  • deny
  • ask
  • allow

这说明 Claude Code 并不是简单地说“允许联网/不允许联网”,而是把网页抓取权限进一步细化到了域名级别

一张图看权限判断

加载图表中...

这套设计非常像一个真正产品化的安全模型。

它对“预批准域名”有特殊优化

源码里有两个非常重要的函数:

import { isPreapprovedHost } from './preapproved.js'
import { isPreapprovedUrl } from './utils.js'

这意味着某些被系统认可的域名,会走更顺畅的抓取路径。
而且 makeSecondaryModelPrompt() 里也会根据是不是预批准域名,生成不同的摘要约束。

对于普通域名,它会额外强调:

  • 引用要短
  • 不要大段复述原文
  • 不要越界讨论法律问题
  • 不要生成歌词等敏感长引用

这本质上是在做版权和内容风险控制。

它还内置了缓存机制

utils.ts 里可以看到:

const CACHE_TTL_MS = 15 * 60 * 1000
const MAX_CACHE_SIZE_BYTES = 50 * 1024 * 1024

const URL_CACHE = new LRUCache<string, CacheEntry>({
  maxSize: MAX_CACHE_SIZE_BYTES,
  ttl: CACHE_TTL_MS,
})

这说明 WebFetchTool 会缓存最近抓取过的网页内容。
这样做的好处是:

  • 同一 URL 重复抓取更快
  • 减少网络开销
  • 减少重复模型处理

它甚至还单独维护了域名预检查缓存:

const DOMAIN_CHECK_CACHE = new LRUCache<string, true>({
  max: 128,
  ttl: 5 * 60 * 1000,
})

这类细节非常像成熟产品,而不是 demo 工具。

它对 URL 安全做了很多约束

validateURL() 里,代码并不只是“能 parse 就行”,还会限制:

  • URL 长度
  • 是否包含用户名/密码
  • 是否看起来像公开域名

源码里还能看到这一句:

const MAX_URL_LENGTH = 2000

以及对内部、异常或不适合抓取目标的前置过滤。
这说明 Anthropic 很清楚:网页抓取是一个容易变成安全通道的能力,所以必须加边界。

重定向处理也很谨慎

WebFetchTool 并不会对任何跨域重定向都自动跟随。
源码里会检查重定向是否安全:

export function isPermittedRedirect(
  originalUrl: string,
  redirectUrl: string,
): boolean

允许的大致是:

  • 同域跳转
  • www. 的增删
  • 路径变化

而如果跳到了不同 host,它不会偷偷继续抓,而是返回一个明确结果,让主线程重新决定。

WebFetchTool.ts 里有这段非常典型的逻辑:

if ('type' in response && response.type === 'redirect') {
  const message = `REDIRECT DETECTED: The URL redirects to a different host. ...`
}

这说明它把“跨域重定向”视为一个需要显式处理的安全事件,而不是普通网络细节。

它还区分文本和二进制内容

utils.ts 里有:

import {
  isBinaryContentType,
  persistBinaryContent,
} from '../../utils/mcpOutputStorage.js'

这说明 WebFetchTool 抓到的内容不一定总是 HTML 文本。
如果是二进制响应,它会走持久化处理,而不是硬塞成文本。

这再次说明它的实现目标不是“随便下载东西”,而是“在产品约束下安全处理网页内容”。

典型使用路径

一个很常见的链路是:

  1. 主线程先用 WebSearchTool 搜某个主题
  2. 选中其中一条结果 URL
  3. 再调用 WebFetchTool
  4. 用 prompt 指定“提取我真正关心的信息”
  5. 把摘要结果带回主线程
加载图表中...

它和 WebSearchTool 的关系

这个区别必须记清楚:

  • WebSearchTool 负责“找答案来源”
  • WebFetchTool 负责“读具体页面”

你可以把它们理解成:

加载图表中...

很多联网任务实际上会同时使用这两个工具。

最容易误解它的地方

误解一:它就是一个 HTTP GET

不对。
它还做了:

  • 权限判断
  • 域名检查
  • HTML 转 markdown
  • 小模型摘要
  • 缓存
  • 重定向安全处理

误解二:它能代替浏览器

也不对。
它更适合静态或可直接抓取的内容页,不适合复杂登录态和交互页面。

误解三:它和 WebSearchTool 差不多

不是一个层级。
一个负责搜,一个负责读。

小结

如果用一句话概括:

WebFetchTool 是 Claude Code 的“定向网页读取器”,它把 URL 抓取、内容清洗、小模型摘要、域名权限和安全控制整合成了一个正式的只读工具。

它真正厉害的地方,不是“能联网”,而是:

能在联网的同时,把风险、上下文和结果规模都控制住。