Skip to content

6.8 外部工具 — WebFetch 与 WebSearch

前置阅读6.4 BashTool(出站对比) · 6.3 治理流水线


学习目标

完成本节学习后,你应该能够:

  1. 区分 WebFetch(拉取 URL 内容)与 WebSearch(检索索引)的输入输出与风险模型。
  2. 解释 为何用专用 HTTP 工具替代 Bash 里的 curl策略集中、SSRF 防护、响应大小上限。
  3. 列举 Web 工具在治理流水线中的检查点:URL 白名单、重定向限制、内容类型过滤。
  4. 说明 搜索结果 snippet vs 全文 对 Token 与版权的影响。
  5. 关联 ReadMcpResource(在 6.9 详述)与 Web 工具的边界:HTTP 通用 vs MCP 资源模型。

生活类比:持证记者 vs 私人侦探

  • WebFetch持证记者采访指定地址:你只能去报备过的门牌(URL 策略),进门最多录音 N 分钟(响应截断),危险品室(二进制下载)默认不进。
  • WebSearch报社资料室:管理员给你剪报摘要(snippet),未必附原文全书;要快、要广,但细节需再 Fetch

WebFetch vs WebSearch(总表)

维度WebFetchWebSearch
输入url, headers?, method?query, locale?, timeRange?
输出HTML/文本片段、状态码元数据结果列表(标题、URL、摘要)
主要风险SSRF、恶意内容、超大响应查询注入、结果投毒(SEO)
与 Bash替代 curl 主路径替代「手搓搜索引擎 API」

WebFetch:实现要点

控制点说明
DNS 重绑定解析后再次校验 IP 段
内网 IP默认拒绝 10/8192.168/16
重定向限制次数,每跳重验
Content-Length预检上限
超时连接 + 首字节 + 总时长

源码片段:URL 策略(概念)

typescript
const FetchInput = z.object({
  url: z.string().url(),
  maxBytes: z.number().int().positive().max(2_000_000).optional(),
});

function isUrlAllowed(url: URL, policy: FetchPolicy): boolean {
  if (policy.blockPrivateIp && isPrivateIp(url.hostname)) return false;
  if (policy.allowlistHosts && !policy.allowlistHosts.has(url.hostname)) return false;
  if (url.protocol !== "https:" && policy.httpsOnly) return false;
  return true;
}

WebSearch:结果形态

typescript
const SearchHit = z.object({
  title: z.string(),
  url: z.string().url(),
  snippet: z.string(),
  publishedAt: z.string().optional(),
});

const WebSearchOutput = z.object({
  hits: z.array(SearchHit).max(15),
  provider: z.string(),
});

生活类比菜单(hits)与后厨实物(fetch 全文)分开,避免一上来端整头烤全羊。


Mermaid:外部工具在流水线中的位置


内容与提示注入

风险缓解
页面含「忽略上文」内容消毒、引用分隔符
搜索引擎摘要被 SEO 污染多源交叉、低权重采纳
PDF/HTML 隐写类型白名单、纯文本管线

与 MCP 的分工

场景工具
任意公开文档WebFetch
需登录或 OAuth 的 SaaSMCP 工具
稳定资源 URIReadMcpResource

遥测

事件字段
web_fetchhost, status, bytes
web_searchprovider, hitCount
ssrf_blockedreason

常见反模式

反模式后果
允许 file:// Fetch本地文件读出
无截断上下文与内存爆炸
搜索结果直接当真理错误事实传播

小结

  • WebFetch 解决受控拉取WebSearch 解决发现与导航
  • 替代 curl 的价值在策略与遥测集中
  • SSRF + 大小 + 注入 是三连击,应在前置阶段处理。

自测题

  1. 重定向到 file:// 时应如何处理?
  2. 为何搜索摘要仍可能触发提示注入?
  3. WebFetch 返回 Markdown 与 HTML 各有什么利弊?

上一节6.7 AgentTool · 下一节6.9 MCP 工具


WebSearch 提供商维度(概念表)

维度说明
地域合规结果是否受区域法规影响
索引新鲜度新闻/文档滞后
snippet 长度影响后续是否必须 Fetch
配额与计费QPS、按调用计费
可观测性是否返回可追溯 requestId

生活类比:选搜索 API 像选通讯社——不只看价格,还要看发稿速度版权边界


重试与退避

场景建议
429 / 5xx指数退避 + 最大重试次数
DNS 失败快速失败,提示检查网络策略
TLS 错误记录证书指纹,勿静默忽略
typescript
async function fetchWithRetry(url: string, opts: { maxRetries: number }) {
  let delay = 300;
  for (let i = 0; i < opts.maxRetries; i++) {
    try {
      return await controlledFetch(url);
    } catch (e) {
      if (i === opts.maxRetries - 1) throw e;
      await sleep(delay);
      delay *= 2;
    }
  }
  throw new Error("unreachable");
}

缓存策略

类型适用注意
URL 正文短缓存静态文档与鉴权响应勿混缓存
搜索结果不缓存强时效查询避免陈旧事实
ETag大页面增量需服务端支持

与 REPL / Bash 的边界

需求推荐
拉取公开 API JSONWebFetch(策略化)
在本地算矩阵REPL / 语言运行时
克隆 Git 仓库专用 VCS 工具或受控 Bash

避免「WebFetch 拉脚本 | bash」这种二段式绕过 —— 应在策略层识别组合风险。


合规与版权提示(教学)

实践说明
snippet 展示控制长度,注明来源 URL
全文抓取遵守 robots 与服务条款(视场景)
内网文档走 VPN + 内网 URL 白名单

FAQ

问:为何不直接把 HTML 全量塞进上下文?
答:Token、版权、XSS 消毒三重压力;应用 readability 类提取与上限。

问:WebSearch 结果能当作引用来源吗?
答:只能当线索;关键事实应 Fetch 原文交叉验证

问:与 ReadMcpResource 如何二选一?
答:公网匿名可读 → WebFetch;需登录/组织内资源 URI → MCP(见 6.9)。


小结补充

  • WebFetch + WebSearch 常成对出现:先搜后取
  • 重试、缓存、合规 属于生产必选项,而非「以后再说」。
  • 对外部工具保持 fail-closed:默认假设内容不可信,需消毒与截断。

本项目仅用于教育学习目的。Claude Code 源码版权归 Anthropic, PBC 所有。