news 2026/9/14 18:29:47

Mastra 集成 Bright Data:为 AI Agent 打造可穿透反爬的搜索与网页抓取工具

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Mastra 集成 Bright Data:为 AI Agent 打造可穿透反爬的搜索与网页抓取工具

Mastra 集成 Bright Data:为 AI Agent 打造可穿透反爬的搜索与网页抓取工具

【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastra

@mastra/brightdata是 Mastra 官方生态中对接 Bright Data 的集成包,为 Agent 提供webSearch(SERP 搜索)与webFetch(网页抓取)两个开箱即用的工具,底层由 Bright Data 的 SERP API 与 Web Unlocker 驱动,可绕过机器人检测与 CAPTCHA,适合需要实时检索网页、读取被普通爬虫拦截的站点的研究型 Agent。读完本文,你将掌握该包的安装、配置、两个工具的参数语义,以及其在 Mastra Agent 中的接入方式与底层调用机制。

一、这个集成解决什么问题

普通爬虫或搜索引擎 API 在面对 Google 搜索结果页,以及启用了 Cloudflare、Akamai 等反爬保护的目标网站时,经常返回验证码页面或直接拒绝访问。@mastra/brightdata的思路是把这两件脏活外包给 Bright Data:

  • SERP API:代理 Google 搜索请求,返回解析好的自然搜索结果(链接、标题、摘要),并对搜索结果应用 Bright Data 的代理/反检测能力;
  • Web Unlocker:抓取任意 URL,自动处理机器人检测、CAPTCHA、指纹识别等反爬手段,把页面内容以 Markdown 形式返回给 Agent。

因此,这两个工具特别适合"先搜到页面、再读取正文"的两段式研究流程。从包描述(见 package.json)与 README 可以确认,这正是该集成的核心定位。

二、安装与前置准备

在 Mastra 项目中安装:

npm install @mastra/brightdata

包以@mastra/core>=1.0.0-0 <2.0.0-0)和zod>=3.0.0)为 peer 依赖,要求 Node.js>=22.13.0,并作为 ESM 模块发布("type": "module",同时提供require的 CJS 产物,见 package.json)。

使用前需要两样东西:

  1. Bright Data API Token:从 Bright Data 控制台获取;
  2. Zone(区域)配置:工具默认使用两个内置 zone——SERP 搜索默认sdk_serp,Web Unlocker 抓取默认sdk_unlocker(定义见 client.ts),一般无需改动。

三、快速开始:把搜索与抓取能力挂到 Agent 上

README 给出的核心用法是调用createBrightDataTools()一次性拿到两个工具,然后注入 Agent 的tools

import { createBrightDataTools } from '@mastra/brightdata'; import { Agent } from '@mastra/core/agent'; const { webSearch, webFetch } = createBrightDataTools(); export const researchAgent = new Agent({ id: 'research-agent', name: 'Research Agent', model: 'openai/gpt-5.6-sol', instructions: 'Search for relevant pages, then fetch the best sources before answering.', tools: { webSearch, webFetch }, });

其中createBrightDataTools(config?)的源码实现非常简单(见 tools.ts):

export function createBrightDataTools(config?: BrightDataClientOptions) { return { webSearch: createBrightDataSearchTool(config), webFetch: createBrightDataFetchTool(config), }; }

也就是说,它等价于分别调用createBrightDataSearchTool()createBrightDataFetchTool()config会被透传给底层两个工具。也可以在同一个 Agent 里只挂其中一个工具:

import { createBrightDataSearchTool } from '@mastra/brightdata'; export const searchOnlyAgent = new Agent({ id: 'search-only-agent', name: 'Search Only Agent', model: 'openai/gpt-5.6-sol', instructions: 'Always use the web search tool to answer questions.', tools: { webSearch: createBrightDataSearchTool() }, });

3.1 模型说明

示例中的model字段(如'openai/gpt-5.6-sol')为 README 中的示意值,实际应替换为你账户中可用的模型标识(如'anthropic/claude-sonnet-4-6'等),并保证对应的模型提供方凭证已配置。

四、工具一:webSearch(Google 搜索)

工具 ID 为brightdata-search,功能描述为:搜索 Google 并返回解析后的自然搜索结果(link/title/description),底层走 SERP API 绕过机器人检测,支持国家与语言定向,以及基于结果偏移的分页(见 search.ts)。

4.1 输入参数(inputSchema)

参数类型必填约束与默认值说明
querystring搜索关键词,会被trim()后作为q参数
countrystring两位字母代码(如"us""gb"),不匹配则校验失败用于地理定向,映射到 Google 的gl参数
languagestring两位字母代码(如"en""es""fr"),不匹配则校验失败本地化搜索结果语言,映射到hl参数,默认en
startnumber非负整数结果偏移量,用于分页(如10表示取第 2 页的 10 条结果),映射到start参数

输入校验由 search.ts 中的 zod schema 完成:countrylanguage都必须匹配/^[a-z]{2}$/i(两位字母),start必须为int().nonnegative()

4.2 输出结构(outputSchema)

{ query: string; // 原始查询词 results: Array<{ // 解析后的自然搜索结果 link: string; // 结果 URL title: string; // 结果标题 description: string; // 结果摘要 }>; currentPage: number; // 当前页号,缺失或非法时回退为 1 }

4.3 底层请求如何构造

webSearch执行时会调用客户端client.search.google(query, { country, language, start })。从源码看,请求 URL 是这样拼出来的(client.ts 的buildGoogleSearchUrl):

  • 目标为https://www.google.com/search
  • 默认(formatjson)时追加brd_json=1,请求 Bright Data 返回结构化 JSON(SERP),以便工具解析出organic数组;
  • hl恒为语言参数(默认en),gl仅在国家参数存在时设置,start仅在有分页需求时设置;
  • 请求体以format: 'json'method: 'GET'zone(默认sdk_serp)发送。

搜索测试(见 search.test.ts)验证了完整映射:queryqcountrygllanguagehlstartstart;也验证了最小输入(仅query)时 URL 只含qhl=en,不带gl/start

解析逻辑会把响应中的organic数组过滤为{ link, title, description }列表:缺失linktitle的条目会被丢弃,响应缺失organic时结果为空数组,current_page非法(0 或缺失)时回退为1。这些边界行为均有对应测试覆盖(见 search.test.ts)。

五、工具二:webFetch(网页抓取)

工具 ID 为brightdata-fetch,功能描述为:抓取网页并返回 Markdown 内容,底层走 Web Unlocker,可绕过机器人检测与 CAPTCHA,包括普通爬虫无法访问的页面(见 fetch.ts)。

5.1 输入与输出

// 输入 { url: string } // 必须为合法 URL(zod 的 z.string().url()) // 输出 { url: string; content: string } // content 为页面的 Markdown 内容

5.2 底层请求如何构造

webFetch执行时调用client.scrapeUrl(input.url, { dataFormat: 'markdown' }),最终请求体为(fetch.test.ts 断言了精确的请求体):

{ "data_format": "markdown", "format": "raw", "method": "GET", "url": "https://example.com", "zone": "sdk_unlocker" }

注意与搜索工具的差异:抓取走raw格式(返回原始文本而不是 JSON 解析),data_formatmarkdown,zone 默认sdk_unlocker

六、配置详解:客户端选项、环境变量与默认值

两个工具以及createBrightDataTools()都接受可选的BrightDataClientOptions(见 client.ts):

配置项类型默认值说明
apiKeystringBRIGHTDATA_API_TOKEN环境变量无则抛出Bright Data API token is required
timeoutnumber120_000(120 秒)请求超时,非正数或非有限数时回退默认值
serpZonestringBRIGHTDATA_SERP_ZONE,再回退sdk_serp搜索请求使用的 zone
webUnlockerZonestringBRIGHTDATA_WEB_UNLOCKER_ZONE,再回退sdk_unlocker抓取请求使用的 zone

6.1 配置优先级

从 client.ts 的实现看,优先级为显式配置 > 环境变量 > 内置默认值

const apiKey = config?.apiKey ?? process.env.BRIGHTDATA_API_TOKEN; const serpZone = config?.serpZone ?? process.env.BRIGHTDATA_SERP_ZONE ?? DEFAULT_SERP_ZONE; const webUnlockerZone = config?.webUnlockerZone ?? process.env.BRIGHTDATA_WEB_UNLOCKER_ZONE ?? DEFAULT_WEB_UNLOCKER_ZONE;

客户端测试(见 client.test.ts)逐一验证了:无 token 时报错、config 优先于环境变量、zone 可分别通过 config 或环境变量覆盖。

6.2 显式传参示例

import { createBrightDataTools } from '@mastra/brightdata'; const { webSearch, webFetch } = createBrightDataTools({ apiKey: process.env.BRIGHTDATA_API_TOKEN, serpZone: 'my_custom_serp_zone', webUnlockerZone: 'my_custom_unlocker_zone', timeout: 60_000, });

也可以只传一部分,例如只覆盖serpZone而让抓取继续走默认 zone。

6.3 环境变量清单

export BRIGHTDATA_API_TOKEN=your_api_token export BRIGHTDATA_SERP_ZONE=sdk_serp # 可选 export BRIGHTDATA_WEB_UNLOCKER_ZONE=sdk_unlocker # 可选

七、底层原理:一次请求的完整链路

该集成不再依赖@brightdata/sdk运行时客户端,而是用标准fetch直连 Bright Data REST 接口(详见 client.ts 与 changelog 中 #16630 的说明——这一改造同时修复了 Bun 环境下的兼容问题)。一次调用链路如下:

  1. 构造请求体toRequestBody()组装{ url, zone, format, method },搜索默认format: 'json',抓取默认format: 'raw'并带上data_format: 'markdown'
  2. 发起请求requestBrightData()https://api.brightdata.com/request发送POST,请求头为Authorization: Bearer <apiKey>Content-Type: application/json
  3. 超时控制:用AbortController+setTimeout实现,超时后抛出Request timed out after <ms>ms
  4. 错误映射
    • 401/403invalid API key or insufficient permissions
    • 400bad request: <响应文本>
    • 其他非 2xx →request failed with status <status>: <响应文本>
  5. 响应解析format: 'json'时把响应文本JSON.parse后返回,否则原样返回文本(scrapeUrl对非字符串响应会JSON.stringify);
  6. 清理:工具执行完毕后调用closeClient()做 best-effort 清理,且保证close()抛错也不会掩盖主流程错误(见 client.ts 的closeClient与 client.test.ts)。

八、搜索参数的语言校验细节

client.search.google()在发请求前还会多做两步防御(见 client.ts):

  1. language必须匹配/^[a-z]{2}$/i,否则直接抛错且不发请求(测试以'1_'为例验证不会打到网络);
  2. 合法时统一toLowerCase()归一化(如'EN''en'),保证hl=en这类 URL 参数大小写一致。

此外,只有formatjson时才追加brd_json=1;请求方若显式指定format: 'raw',则可拿到真实的原始 SERP 文本(见 client.test.ts)。

九、测试与验证方式

该集成自带完整 vitest 测试套件,位于 integrations/brightdata/src/tests,可在本地运行:

cd integrations/brightdata && pnpm test

测试覆盖了四个层面:

  • tools.test.ts:createBrightDataTools返回两个工具,且 ID、描述、输入/输出 schema 齐全;
  • client.test.ts:API key 来源与优先级、zone 覆盖、语言校验与归一化、brd_json逻辑、401 错误映射、closeClient行为;
  • search.test.ts:参数映射、最小输入、organic缺失/脏数据处理、current_page回退、错误透传;
  • fetch.test.ts:请求体精确断言(data_format: markdownzone: sdk_unlocker)、错误透传。

十、实战建议与注意事项

  1. 两段式研究流程:在 Agent 的instructions中明确"先用webSearch找到候选页面,再用webFetch读取正文再作答",能让模型按序使用工具,减少盲目抓取;
  2. 分页技巧start每次递增 10(1020…),结合输出里的currentPage可以设计多轮深度搜索的工作流;
  3. 超时调整:Web Unlocker 处理复杂反爬页面可能耗时较长,默认 120 秒通常够用;若你的场景页面较轻,可通过timeout收紧以降低等待;
  4. zone 自定义:如果你在 Bright Data 控制台创建了专属 zone(用于配额统计或独立配置),务必通过serpZone/webUnlockerZone或对应环境变量覆盖默认值,否则请求会落在默认 zone 上;
  5. 凭证安全:优先使用环境变量注入BRIGHTDATA_API_TOKEN,避免把 token 硬编码进源码或提交到仓库;
  6. 错误处理:工具的错误已归一化为可读信息(key 无效、400 请求错误、超时等),在 Agent 上层做try/catch或重试时可直接依赖这些信息。

十一、小结

@mastra/brightdata以极少的配置成本,把"搜索 + 抓取"两大联网能力以标准 Mastra Tool 的形式注入 Agent:webSearch负责从 Google 获取结构化自然搜索结果,webFetch负责用 Web Unlocker 穿透反爬读取正文,二者共享一套基于fetch的轻量客户端与统一的配置优先级。其核心实现集中在 integrations/brightdata/src 的client.tssearch.tsfetch.ts三个文件中,配合 测试套件 即可完整掌握其行为边界,适合作为 Mastra 研究型、检索增强型 Agent 的联网底座。

【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastra

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/14 18:27:32

基于YOLOv8的鱼类疾病检测系统:从数据标注到模型部署全流程解析

简介&#xff1a;基于Python和YOLOv8的鱼类疾病检测系统&#xff0c;面向水产养殖从业者、计算机视觉学习者和算法工程师&#xff0c;借助深度学习实现鱼类疾病自动化识别&#xff0c;解决人工巡检效率低、漏检率高的问题。系统覆盖22种鱼类及其常见病症&#xff08;如出血、眼…

作者头像 李华
网站建设 2026/9/14 18:26:42

FPGA HDMI发射器IP核深度解析:从AXI-Stream到EDID动态适配

简介&#xff1a;本资源是一个面向FPGA开发者的HDMI输出IP核工程包&#xff0c;专为Xilinx全系列器件&#xff08;从Artix到Virtex&#xff09;设计&#xff0c;解决高清音视频信号在数字系统中可靠编码与物理层传输的关键问题&#xff0c;适用于多媒体终端、显示控制、嵌入式视…

作者头像 李华
网站建设 2026/9/14 18:25:33

Kvasir-SEG息肉检测数据集:YOLO格式解析与医疗目标检测实战

简介&#xff1a;本资源是面向医学图像AI初学者与目标检测实践者的YOLO格式息肉检测专用数据集&#xff0c;基于Kvasir-SEG公开数据构建&#xff0c;聚焦单类别&#xff08;息肉&#xff09;的端到端训练需求&#xff0c;适用于结肠镜辅助诊断模型开发、课程实验及竞赛基线训练…

作者头像 李华
网站建设 2026/9/14 18:24:41

Scrapy-Redis分布式爬虫架构与实战指南

1. Scrapy框架与分布式爬虫基础解析Scrapy作为Python生态中最强大的爬虫框架之一&#xff0c;其设计哲学遵循"Dont Repeat Yourself"原则。单机模式下&#xff0c;Scrapy通过内置的调度器&#xff08;Scheduler&#xff09;管理请求队列&#xff0c;使用基于内存的集…

作者头像 李华
网站建设 2026/9/14 18:24:31

AI葡萄智能绑蔓机器人 Qt信创完整项目

# AI葡萄智能绑蔓机器人 Qt信创完整项目 ## 项目定位 适配**统信UOS/银河麒麟**国产信创平台(飞腾/龙芯aarch64、x86),Qt5.15/Qt6 + OpenCV4; 业务:轻量化YOLOv8视觉识别葡萄架面**新梢、老蔓、钢丝架线、交叉密枝**,自动判定合规绑缚点位;区分**第一次嫩梢绑蔓(20–3…

作者头像 李华