Web 工具:AI 如何访问互联网
深入 Claude Code 的网络访问工具——WebFetchTool 内容获取、WebSearchTool 搜索、代理配置、安全考量
问题引入
AI 编码助手的知识有一个天然的截止日期——模型训练数据的时间点。当用户问"React 19 的新 API 怎么用"或"这个 npm 包最新版有什么 breaking changes"时,AI 只能靠互联网访问来获取最新信息。
但让 AI 访问互联网带来了新的安全挑战:
- SSRF(Server-Side Request Forgery) — AI 可能被注入恶意 URL,访问内网服务
- 数据外泄 — 恶意网页可能指示 AI 将用户代码发送到外部
- Token 炸弹 — 一个巨大的网页可能消耗全部上下文空间
- 认证泄露 — 如果 AI 带着用户的 cookie 或 token 访问网页,可能泄露凭据
Claude Code 通过两个专用工具解决这些问题:WebFetchTool(获取指定 URL 的内容)和 WebSearchTool(搜索互联网)。在 CCR(Claude Code Remote)环境中,还有一个上游代理层提供额外的网络控制。
WebFetchTool:内容获取
WebFetchTool 从指定 URL 获取内容,并让 AI 用自然语言 prompt 处理获取到的内容。
输入模型
两个参数:url 和 prompt。prompt 的设计意图是让 AI 不仅仅获取原始内容,而是带着目的去提取信息。例如:"从这个 API 文档中提取所有 endpoint 和它们的参数"。
输出包含 HTTP 状态码、处理后的文本、获取时间和内容大小:
预批准域名白名单
WebFetchTool 最重要的安全机制之一是预批准域名列表:
这些域名可以无需用户确认即可访问。列表的选择标准是"代码相关的文档站点"——它们是只读的参考资料,不涉及认证或用户数据。
注意源码中的安全警告:
这是一个关键的安全区分:WebFetch 只做 GET 请求(只读),而沙箱的网络限制控制的是任意网络操作(包括 POST)。两者不能共享白名单。
路径级别的预批准
某些域名只对特定路径预批准。例如 github.com/anthropics 是预批准的,但 github.com/random-user 不是。路径匹配强制要求段边界(/),防止 /anthropics-evil/malware 被误匹配。
数据结构在模块加载时预处理为两个查找表(HOSTNAME_ONLY Set 和 PATH_PREFIXES Map),使运行时匹配为 O(1)。
权限检查流程
权限规则以 domain:hostname 格式存储。当用户批准访问某个域名时,该域名的所有 URL 都被批准。
Prompt 中的认证警告
这个警告始终包含在 prompt 中,不管 ToolSearchTool 是否可用。源码注释解释了原因:如果这个前缀根据 ToolSearch 可用性有条件地切换,会导致工具描述在连续的 API 调用间"闪烁"(flicker),破坏 Anthropic API 的 prompt 缓存——每次闪烁都意味着两次缓存未命中。
WebSearchTool:互联网搜索
WebSearchTool 使用 Anthropic 的 Web Search API 进行互联网搜索。与 WebFetchTool 不同,它不是获取特定 URL,而是搜索整个互联网。
架构特殊性
WebSearchTool 不是简单地调用搜索 API——它是一个模型套模型的架构:
它创建一个内部的 API 调用,传入 web_search_20250305 类型的工具 Schema。API 端会自动执行搜索并返回结果。这种架构的好处是:搜索的实际执行由 Anthropic 的基础设施处理,客户端只需要处理流式响应。
搜索限制
每次调用最多执行 8 次搜索。allowed_domains 和 blocked_domains 允许 AI 控制搜索范围——例如只搜索官方文档站点,或排除已知的低质量结果源。
提供商可用性
WebSearchTool 只在支持 Web Search API 的提供商上可用:Anthropic 第一方、Google Vertex(仅 Claude 4.0+ 模型)和 Foundry。
进度报告
WebSearchTool 在搜索过程中通过 onProgress 回调报告进度。由于搜索是流式的,它可以在搜索结果到达时实时更新 UI,而不是等所有搜索完成后才返回。
上游代理(Upstream Proxy)
在 CCR(Claude Code Remote)环境中,所有网络流量通过上游代理路由,提供额外的安全控制。
初始化流程
关键安全措施:
-
prctl 防护 —
PR_SET_DUMPABLE=0阻止同 UID 的进程通过 ptrace 读取此进程的堆内存。这防止了 prompt 注入攻击通过gdb -p $PPID窃取会话 token -
Token 文件删除 — token 在 relay 启动成功后从磁盘删除,仅保留在进程内存中。删除只在 relay 确认可用后执行,以便 supervisor 在失败时可以用磁盘上的 token 重试
-
失败开放 — 任何步骤的失败都只是禁用代理,不会中断会话。注释说得很清楚:"A broken proxy setup must never break an otherwise-working session."
NO_PROXY 列表
Anthropic API 使用三种格式的同一域名,因为不同的运行时(Bun、Python、Go)解析 NO_PROXY 的方式不同。这种防御性编程确保 Anthropic API 请求永远不会通过上游代理,避免了 MITM 代理的伪造 CA 破坏非 Bun 运行时的 HTTPS 验证。
环境变量传播
代理环境变量以多种格式设置,覆盖不同的客户端库:
HTTPS_PROXY/https_proxy— 大小写两种形式(Node.js 用大写,Python 用小写)SSL_CERT_FILE— OpenSSL 通用NODE_EXTRA_CA_CERTS— Node.js 专用REQUESTS_CA_BUNDLE— Python requests 库CURL_CA_BUNDLE— curl 命令
子进程(Bash、MCP、LSP、Hooks)都通过 subprocessEnv() 继承这些变量。
安全考量总结
六层安全防护,从最宽松(预批准白名单自动通过)到最严格(上游代理 MITM 拦截),形成了纵深防御。
关键的安全隔离:WebFetch 白名单 =/= 沙箱网络白名单。huggingface.co 可能是读取文档的安全来源(WebFetch),但允许它通过沙箱进行任意网络操作就可能成为数据外泄通道(支持文件上传)。
设计启示
Claude Code 的 Web 工具设计体现了几个核心原则:
-
最小权限 — 默认不允许访问任何域名,只有代码文档站点被预批准,其他需要用户明确授权
-
安全隔离 — WebFetch(只读 GET)和沙箱网络(任意操作)有独立的白名单,WebSearch 不需要白名单(由 API 端控制)
-
失败开放 vs 失败关闭 — 上游代理失败时开放(不阻断会话),但权限检查失败时关闭(阻止访问)。这反映了不同组件的风险等级
-
多运行时兼容 — 环境变量、NO_PROXY 格式、CA 证书路径——每个网络配置都考虑了 Bun/Node.js/Python/curl 的差异