AutoGPT 平台 Tavily Extract 网页内容抽取块:批量 URL 到 LLM 友好文本的实战指南
Tavily Extract 是 AutoGPT 平台中用于"网页正文抽取"的官方积木块(Block),它接收一个或多个 URL,调用 Tavily 的抽取 API 将页面清洗为适合 LLM 直接消费的 markdown 或 text 纯文本,是构建 RAG 索引、文章摘要、搜索结果富化等 Agent 工作流的基础组件。本文基于 tavily/extract.md 文档并结合 extract.py 源码,带你掌握该块的输入输出契约、失败隔离机制、精确计费逻辑与三类典型落地场景。
一、什么是 Tavily Extract
在 AutoGPT 平台中,Tavily 集成以一组独立积木块的形式暴露给 Agent 构建者,每个积木块封装一次 Tavily API 调用。根据 tavily 目录 下的源码,该集成目前共提供四个块:搜索(search)、内容抽取(extract)、站点地图(map)与整站抓取(crawl),并共享同一套 provider 配置。
其中 Tavily Extract 的作用一句话概括(源码定义于 extract.py 第 65 行):
"Extracts page content from one or more URLs using Tavily, optimized for LLM consumption"——用一个或多个 URL,借助 Tavily 抽取针对 LLM 消费优化的页面内容。
它归属于 BlockCategory.SEARCH 搜索类积木,是"搜索 → 富化"链路中负责把链接变成可读正文的取数环节。例如上游先用 Tavily Search 或 Tavily Map 定位到一批相关页面,再交给 Extract 拉取全文。
二、工作原理与关键设计
一次请求的处理流程
从源码调用链看,TavilyExtractBlock.run()(extract.py 第 100-151 行)的执行流程如下:
- 用凭证中的 API Key 构造
AsyncTavilyClient(异步客户端,见_extract私有方法 extract.py 第 93-98 行); - 以
urls、extract_depth(取枚举值basic/advanced)、format(取枚举值markdown/text)以及include_usage=True四个参数调用client.extract(...),请求 Tavily 返回用量报告; - 解析响应,把成功页封装为
TavilyPageContent对象列表; - 依据用量报告(缺失时退化为估算公式)核算本次执行的 provider 成本并写入执行统计;
- 依次产出输出。
值得注意的几点设计:
- 批量上限 20:每个请求最多传入 20 个 URL,超出会在 schema 层被拦截(
urls字段设置了max_length=20,见 extract.py 第 34-37 行)。 - 深度影响抽取量:
extract_depth设为advanced时,会从每个页面中抽取更多内容,包括表格和嵌入式内容,代价是更高的积分成本。 - 格式决定输出形态:
format决定清洗后内容返回为markdown(保留标题、列表、链接等结构)还是纯text。
失败隔离:坏链接不会拖垮整批任务
与"单 URL 失败即整体失败"的朴素实现不同,Tavily Extract 将「抓取成功」与「抓取失败」的 URL 分开上报:
- 成功抓取到的页面整体返回在
results输出(同时逐条单独输出到result); - 无法抓取的 URL 单独出现在
failed_urls输出上。
这意味着即便输入列表里混有几个失效链接,成功的页面仍然会被完整产出,你只需针对 failed_urls 做重试或丢弃处理即可(对应源码中 yield "failed_urls", [...] 的逻辑,见 extract.py 第 149-151 行)。
三、输入与输出契约
输入(Inputs)
| 输入 | 说明 | 类型 | 必填 |
|---|---|---|---|
| credentials | Tavily 集成凭证,需要配置 Tavily API Key | CredentialsMetaInput | 是 |
| urls | 要抽取内容的 URL 列表(单次请求最多 20 个) | List[str] | 是 |
| extract_depth | 抽取深度:basic 或 advanced(后者可抽取更多数据,包括表格与嵌入式内容) |
"basic" | "advanced" |
否(默认 basic) |
| format | 抽取内容的返回格式 | "markdown" | "text" |
否(默认 markdown) |
对应源码 extract.py 第 30-47 行 的定义中,extract_depth 与 format 都被标记为 advanced=True,属于高级参数。底层可选值来自枚举类型 _api.py 第 38-45 行:TavilyExtractDepth(basic/advanced)与 TavilyFormat(markdown/text)。
输出(Outputs)
| 输出 | 说明 | 类型 |
|---|---|---|
| error | 抽取失败时的错误信息 | str |
| results | 成功抽取的页面列表 | List[TavilyPageContent] |
| result | 单个抽取到的页面(results 中逐条单独产出) | TavilyPageContent |
| failed_urls | 无法抽取的 URL 列表 | List[str] |
单个页面的 TavilyPageContent 结构由 _api.py 第 63-67 行 定义,仅含两个字段:
url:该页面的 URL;raw_content:抽取清洗后的页面正文。
需要说明的是,error 字段在 Output schema 中存在并带默认空字符串(见 extract.py 第 57-60 行),而真正的调用异常(如网络错误、API 校验失败)会在 run() 内被包装为 BlockExecutionError 抛出并中止该块执行(extract.py 第 111-116 行);单 URL 级别的抓取失败则不会抛错,而是走 failed_urls 输出。两者分工明确:API 级失败抛异常,页面级失败进 failed_urls。
四、计费逻辑:从用量报告读取真实消耗
Tavily 以 API 积分(credit)计费,AutoGPT 平台侧对 Tavily 的价格换算集中定义在 _config.py 中:
- 1 个 Tavily credit 对应 0.008 美元(
CREDIT_USD = 0.008,见 _api.py 第 7 行); - 平台 provider 配置中,基础成本按
COST_USD计价,1000 平台积分对应 1 美元(with_base_cost(1000, BlockCostType.COST_USD))。
文档约定的扣费规则
- 每成功抽取 5 个 URL 计 1 credit;
- 若使用
advanced深度,则每 5 个 URL 计 2 credits; - 抽取失败的 URL 不计费。
源码中的实际核算方式
extract.py 第 118-143 行 展示了更精细的实现:由于调用时传入了 include_usage=True,响应会携带 Tavily 的用量报告,代码通过 credits_from_response()(_api.py 第 10-15 行)优先读取报告中的真实 credits;只有报告缺失时,才退化为按文档费率估算——即 math.ceil(成功URL数 / 5) × (advanced 为 2,否则 1)。
这里有一个容易误读的细节值得单独说明(源码注释原话):Tavily 的用量报告是增量式的,抽取费用按每 5 个 URL 的结算边界累加,因此某次请求返回 0 credits 是合法的正常值,并不代表报告丢失。实现上对 "0" 与非 0 数字一视同仁地采用,只有 usage 为空或 credits 非数字时才走估算分支。
最终,本次执行的 provider 成本 credits_used × CREDIT_USD(类型为 cost_usd)通过 self.merge_stats(NodeExecutionStats(...))(extract.py 第 138-143 行)写入节点执行统计,供后续计费对账使用——merge_stats 由块基类 Block 提供。
五、典型应用场景
官方文档(extract.md)给出了三类最有代表性的用法:
1. 内容入库(Content Ingestion)
把一列文章或文档 URL 批量转成干净文本,交给后续的摘要任务或 RAG 向量索引。由于输出自带 markdown 格式选项,可在入库前保留标题层级与列表结构,比纯文本更适合做切片与语义检索。配合块的 results 批量输出,一条工作流即可完成"抓取 → 清洗 → 入库"。
2. 链接富化(Link Enrichment) 承接上游搜索或地图(map)块的结果:先用 Tavily Search 或 Map 找出最相关的若干页面,再把这些 URL 送入 Extract 拉取全文,弥补搜索结果只有摘要片段的不足,让 LLM 拿到完整上下文后作答或总结。
3. 健壮的批量抓取(Resilient Batch Scraping)
一次抽取大量 URL,通过 failed_urls 输出单独路由失败项进行重试或补偿,而不必丢弃已经成功抓取的页面——这正是上一节"失败隔离"设计最直接的收益场景。
六、在 AutoGPT 平台中接入与运行
- 准备凭证:Tavily 集成通过环境变量/平台凭证提供 API Key,字段名为
TAVILY_API_KEY(定义见 _config.py 第 10-14 行)。在积木的credentials输入中填入你的 Tavily API Key。 - 添加积木到画布:在积木库的搜索分类中找到 Tavily Extract,连上输入与输出边。
- 配置参数:
urls传入待抽取链接(最多 20 个);需要表格与嵌入式内容时把extract_depth调为advanced;根据下游消费方式选择markdown或text。 - 处理输出:从
results拿到全部成功页面,从failed_urls做失败重试;注意result会与results同时产出相同数据(逐条),两者取一即可,避免下游重复处理。
块的自动化测试输入与断言(extract.py 第 69-90 行)展示了预期行为:对单 URL https://agpt.co 应产出包含 1 个元素的 results、url 等于该地址的 result,以及空列表 failed_urls;测试 Mock 的响应结构 {"results": [{"url", "raw_content"}], "failed_results": [], "usage": {"credits": 1}} 同时也印证了上文关于响应解析与计费字段来源的描述。
七、小结与延伸
Tavily Extract 以 "最多 20 个 URL 一批、成功失败分流、计费透明可预期" 三个特性,成为 AutoGPT 平台搜索类积木中承担网页正文抽取的标准件。如果还想打通更完整的链路,可以继续阅读同目录的 tavily/search.md(网页搜索)、tavily/map.md(站点链接地图)与 tavily/crawl.md(整站抓取),其核心实现分别对应 search.py、map.py 与 crawl.py;其中 crawl 复用与 extract 相同的 TavilyExtractDepth 深度枚举与同款计费约定(见 crawl.py 与 _api.py),掌握本块即可举一反三。
atomcodeClaude Code 的开源替代方案。连接任意大模型,编辑代码,运行命令,自动验证 — 全自动执行。用 Rust 构建,极致性能。 | An open-source alternative to Claude Code. Connect any LLM, edit code, run commands, and verify changes — autonomously. Built in Rust for speed. Get StartedRust0629
MiniCPM5-2BMiniCPM5-2B 是一款面向端侧、本地部署和资源受限场景的 2B 稠密 Transformer,能够达到同尺寸开源模型 SOTA 水平。Markdown00
GLM-5.3GLM-5.3 与 GLM-5.2 使用相同的基座模型——所有提升均来自后训练。与 GLM-5.2 相比,它在复杂编程和长程任务上的表现显著提升。Jinja00
HivisionIDPhotos⚡️HivisionIDPhotos: a lightweight and efficient AI ID photos tools. 一个轻量级的AI证件照制作算法。Python07
DragonOSDragonOS is an operating system developed from scratch using Rust, with Linux compatibility. It is designed for **Serverless** scenarios. 使用Rust从0自研内核,具有Linux兼容性的操作系统,面向云计算Serverless场景而设计。Rust00
Spark-X2.5-1.7BSpark-X2.5-1.7B 旨在让强大的 AI 更加实用、高效且易于获取。这些模型在广泛的日常任务中表现出色,涵盖对话、写作、翻译、推理、编程、工具调用和智能体工作流,并在同等规模的开源模型中取得领先结果。Spark-X2.5 将面向效率的架构与最高 1M tokens 的原生上下文窗口相结合,并支持 200 多种语言。Python00