跳转到内容
本站为社区维护的非官方中文翻译,与 Cloudflare, Inc. 无关联。本站不提供账户登录,请勿在任何非官方站点输入您的 Cloudflare 账户信息。官方文档:developers.cloudflare.com

Web fetch

最后更新 查看 MarkdownAgent 设置

为 Agent 提供 web_fetch tool 以读取 URL。Agents SDK 处理 HTTP 请求周边工作:将文档转换为可读文本、将长页面拆成更小的结果,并控制模型可以 fetch 的 URL。

将提供的 adapter 与 Pi Durable、AI SDK 或 TanStack AI 一起使用。对于其他 harness,使用 agents/webfetch 中公开的 fetch、分页和格式化函数。

tool 提供的能力

研究型 Agent 可能需要读取网页、PDF 报告和 JSON feed。web_fetch 不会把每个响应体直接返回给模型,而是处理每种格式,并提供它所读取内容的上下文。

任务 web_fetch 的做法
读取网页和文档 通过 Workers AI Markdown Conversion 将 HTML、PDF 和支持的 Office 文档转换为 Markdown。
优先使用 Markdown 先请求 Markdown。支持 Markdown for Agents 的站点可直接返回 Markdown,无需转换。
读取结构化数据 美化打印 JSON,并原样传递 Markdown 和其他文本格式。
读取长页面 返回有界的内容窗口,并提供用于读取下一部分的 offset。
理解响应 包含最终 URL、HTTP 状态、内容类型、总字符数和续读信息。
控制请求 应用你的主机限制、重定向检查、字节上限和超时。遵循 harness 的取消。
从错误中恢复 指导模型修正输入、重试或改用其他来源,并为你的应用提供结构化错误。

将 tool 添加到 harness

这些示例需要 Agents SDK 0.28.0 或更高版本,以及已有的 harness。要新建 Pi Durable Agent,请从 Pi harness 指南开始。

  1. 在 Worker 项目中更新 Agents SDK:

    npm i agents@latest
  2. 在 Wrangler 配置中添加 Workers AI 绑定(binding),用于 HTML 和文档转换:

    {
      "$schema": "./node_modules/wrangler/config-schema.json",
      "ai": {
        "binding": "AI",
        "remote": true
      }
    }
    [ai]
    binding = "AI"
    remote = true

    该 tool 使用 Worker 的 fetch 检索 URL。Markdown、JSON 和纯文本会跳过 Workers AI 转换。本地开发期间的转换会针对你的 Cloudflare 账户远程运行。

  3. 使用后续示例之一,向 harness 注册该 tool。

Pi Durable

在 Pi harness factory 中,在将其传给 Harness.open() 之前,把 tool 安装到 registry:

import { webFetchTool } from "agents/webfetch/pi";

// Inside the harness factory, before Harness.open():
this.registry.install({
	name: "web-tools",
	tools: [webFetchTool({ binding: this.env.AI })],
});
import { webFetchTool } from "agents/webfetch/pi";

// Inside the harness factory, before Harness.open():
this.registry.install({
	name: "web-tools",
	tools: [webFetchTool({ binding: this.env.AI })],
});

让 Agent 读取 URL,例如文档页面或 PDF 报告。模型可以用 url 调用 web_fetch,然后传入建议的续读 offset 以读取更多内容。

Pi tool 标记为 replay: "safe"。session 恢复时,Pi 会重新运行因 evict 而中断的 fetch。已完成的结果会保留存储,恢复期间不会再次 fetch。取消正在运行的调用时,该 tool 也会遵循 Pi 的 abort signal。

AI SDK

将 tool 添加到现有 streamText() 或 generateText() 调用的 tools 对象:

import { streamText } from "ai";
import { webFetchTool } from "agents/webfetch/ai-sdk";

const tools = {
	web_fetch: webFetchTool({ binding: env.AI }),
};

const result = streamText({ model, messages, tools });
import { streamText } from "ai";
import { webFetchTool } from "agents/webfetch/ai-sdk";

const tools = {
	web_fetch: webFetchTool({ binding: env.AI }),
};

const result = streamText({ model, messages, tools });

若你自行转换 UI messages,请将相同的 tools 传给 convertToModelMessages(messages, { tools })。这样模型在读取先前结果时会保留格式化的 header 和 untrusted-content wrapper。

TanStack AI

将服务端 tool 添加到现有 chat() 调用:

import { chat } from "@tanstack/ai";
import { webFetchTool } from "agents/webfetch/tanstack-ai";

const stream = chat({
	adapter,
	messages,
	tools: [webFetchTool({ binding: env.AI })],
});
import { chat } from "@tanstack/ai";
import { webFetchTool } from "agents/webfetch/tanstack-ai";

const stream = chat({
	adapter,
	messages,
	tools: [webFetchTool({ binding: env.AI })],
});

其他 harnesses

在 harness 的 tool handler 内使用 fetchWeb()。它返回完整转换后的页面。使用 windowWebFetchPage() 和 renderWebFetchPage(),向模型提供与内置 adapter 相同的有界结果:

import {
	fetchWeb,
	renderWebFetchPage,
	windowWebFetchPage,
} from "agents/webfetch";

// Register this handler with your harness's tool interface.
// Forward the harness's cancellation signal when it provides one.
async function readUrl(input, env, signal) {
	const page = await fetchWeb(
		{ url: input.url, format: input.format },
		{ binding: env.AI, signal },
	);
	const output = windowWebFetchPage(page, {
		offset: input.offset,
		pageChars: 20_000,
	});
	return renderWebFetchPage(output);
}
import {
	fetchWeb,
	renderWebFetchPage,
	windowWebFetchPage,
	type WebFetchToolInput,
} from "agents/webfetch";

// Register this handler with your harness's tool interface.
// Forward the harness's cancellation signal when it provides one.
async function readUrl(
	input: WebFetchToolInput,
	env: { AI: Ai },
	signal?: AbortSignal,
) {
	const page = await fetchWeb(
		{ url: input.url, format: input.format },
		{ binding: env.AI, signal },
	);
	const output = windowWebFetchPage(page, {
		offset: input.offset,
		pageChars: 20_000,
	});
	return renderWebFetchPage(output);
}

用必填的 url、可选的非负整数 offset,以及可选的 "auto" 或 "raw" format 定义 tool 的输入 schema。将 WebFetchError 映射到 harness 的错误结果。这些函数不需要 Durable Object、浏览器或 Worker Loader 绑定。

读取长页面

默认情况下,模型每次调用最多收到 20,000 个字符。每个结果包含 header,并将内容包在 untrusted_web_content 标签中:

web_fetch: https://example.com/report · 200 · text/html → markdown · chars 0–19873 of 81200 · continue with offset=19873
<untrusted_web_content>
# Report
...
</untrusted_web_content>

模型使用结果中的 offset 继续读取,该 offset 可能停在换行处。你的应用会在结构化输出中收到 nextOffset,到达末尾时为 null。Pi 将该输出存储在 details.output 中;AI SDK 从 execute 返回它。TanStack AI 返回格式化文本。

内置 source 会为每次 tool 调用再次 fetch URL。读取五个窗口就会进行五次 fetch,两次调用之间内容可能变化。要复用已 fetch 的页面,请保留 fetchWeb() 返回的 WebFetchPage,再用下一个 offset 调用 windowWebFetchPage()。

wrapper 将外部内容标记为数据而非指令。它不能保证抵御 prompt injection。

控制请求

模型选择 url、offset 和 format。你的应用在创建 tool 时选择请求策略和限制:

import { webFetchTool } from "agents/webfetch/pi";

const readDocs = webFetchTool({
	binding: env.AI,
	allowedHosts: ["developers.cloudflare.com"],
	pageChars: 10_000,
	maxBytes: 1_000_000,
	timeoutMs: 15_000,
	maxRedirects: 3,
});
import { webFetchTool } from "agents/webfetch/pi";

const readDocs = webFetchTool({
	binding: env.AI,
	allowedHosts: ["developers.cloudflare.com"],
	pageChars: 10_000,
	maxBytes: 1_000_000,
	timeoutMs: 15_000,
	maxRedirects: 3,
});
选项 默认值 效果
pageChars 20000 一次 tool 结果内容窗口的最大字符数。
maxBytes 5000000 拒绝前读取的最大响应体字节数。
timeoutMs 30000 以毫秒计的截止时间,包括重定向和转换。
maxRedirects 5 最多跟随的重定向次数。接受 0 到 20 的整数。
allowedHosts 任何公开主机 tool 可以 fetch 的主机名。*.example.com 匹配子域,但不匹配 example.com 本身。
blockedHosts 无 tool 必须拒绝的主机名,在 allowedHosts 之前检查。
allowPrivateHosts false 设为 true 时允许本地和私有主机,用于本地开发。

内置 source 会检查每个 URL 和重定向目标。它会拒绝非 HTTP scheme、URL 中的凭据、超过 2,000 个字符的 URL,以及 HTTPS 到 HTTP 的重定向。默认会阻止私有 IP 字面量和本地主机名,但不会通过 DNS 解析来检查公开主机名背后的地址。

要添加缓存或使用不同的检索服务,请通过 source 选项提供 WebFetchSource,而不是 binding。自定义 source 负责 URL 验证、主机限制、字节上限和重定向处理。tool 仍会应用 pageChars 和 timeoutMs。你可以包装 createDirectWebFetch() 以保留内置请求策略。

处理错误,并在需要时选择浏览器

可读的 HTTP 错误页面会随其状态一起返回。Fetch 失败使用 WebFetchError 代码,例如 web_fetch_timeout、web_fetch_too_large 和 web_fetch_unsupported_content_type,并带有 retryable 字段。Pi 在 details 中以 ok: false 返回失败;AI SDK 和 TanStack AI adapter 会抛出 WebFetchError。取消会作为 abort 传播,而不是 fetch 失败。

使用 format: "raw" 可在不转换的情况下读取文本响应体。raw 模式无法返回 PDF 或其他二进制文档内容。不支持图片、音频和视频。

当 Agent 需要 JavaScript 渲染的内容、登录 session、屏幕截图或交互时,使用 Browser。Web fetch 会发出不带浏览器 cookie、凭据或自定义请求标头的 GET 请求。检测到 bot 挑战时会返回 web_fetch_blocked,并建议模型使用浏览器或其他来源。

这篇文档对您有帮助吗?