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)。
使用前需要两样东西:
- Bright Data API Token:从 Bright Data 控制台获取;
- 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)
| 参数 | 类型 | 必填 | 约束与默认值 | 说明 |
|---|---|---|---|---|
query | string | 是 | — | 搜索关键词,会被trim()后作为q参数 |
country | string | 否 | 两位字母代码(如"us"、"gb"),不匹配则校验失败 | 用于地理定向,映射到 Google 的gl参数 |
language | string | 否 | 两位字母代码(如"en"、"es"、"fr"),不匹配则校验失败 | 本地化搜索结果语言,映射到hl参数,默认en |
start | number | 否 | 非负整数 | 结果偏移量,用于分页(如10表示取第 2 页的 10 条结果),映射到start参数 |
输入校验由 search.ts 中的 zod schema 完成:country与language都必须匹配/^[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; - 默认(
format为json)时追加brd_json=1,请求 Bright Data 返回结构化 JSON(SERP),以便工具解析出organic数组; hl恒为语言参数(默认en),gl仅在国家参数存在时设置,start仅在有分页需求时设置;- 请求体以
format: 'json'、method: 'GET'、zone(默认sdk_serp)发送。
搜索测试(见 search.test.ts)验证了完整映射:query→q、country→gl、language→hl、start→start;也验证了最小输入(仅query)时 URL 只含q与hl=en,不带gl/start。
解析逻辑会把响应中的organic数组过滤为{ link, title, description }列表:缺失link或title的条目会被丢弃,响应缺失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_format为markdown,zone 默认sdk_unlocker。
六、配置详解:客户端选项、环境变量与默认值
两个工具以及createBrightDataTools()都接受可选的BrightDataClientOptions(见 client.ts):
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
apiKey | string | 取BRIGHTDATA_API_TOKEN环境变量 | 无则抛出Bright Data API token is required |
timeout | number | 120_000(120 秒) | 请求超时,非正数或非有限数时回退默认值 |
serpZone | string | 取BRIGHTDATA_SERP_ZONE,再回退sdk_serp | 搜索请求使用的 zone |
webUnlockerZone | string | 取BRIGHTDATA_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 环境下的兼容问题)。一次调用链路如下:
- 构造请求体:
toRequestBody()组装{ url, zone, format, method },搜索默认format: 'json',抓取默认format: 'raw'并带上data_format: 'markdown'; - 发起请求:
requestBrightData()向https://api.brightdata.com/request发送POST,请求头为Authorization: Bearer <apiKey>与Content-Type: application/json; - 超时控制:用
AbortController+setTimeout实现,超时后抛出Request timed out after <ms>ms; - 错误映射:
401/403→invalid API key or insufficient permissions;400→bad request: <响应文本>;- 其他非 2xx →
request failed with status <status>: <响应文本>;
- 响应解析:
format: 'json'时把响应文本JSON.parse后返回,否则原样返回文本(scrapeUrl对非字符串响应会JSON.stringify); - 清理:工具执行完毕后调用
closeClient()做 best-effort 清理,且保证close()抛错也不会掩盖主流程错误(见 client.ts 的closeClient与 client.test.ts)。
八、搜索参数的语言校验细节
client.search.google()在发请求前还会多做两步防御(见 client.ts):
language必须匹配/^[a-z]{2}$/i,否则直接抛错且不发请求(测试以'1_'为例验证不会打到网络);- 合法时统一
toLowerCase()归一化(如'EN'→'en'),保证hl=en这类 URL 参数大小写一致。
此外,只有format为json时才追加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: markdown、zone: sdk_unlocker)、错误透传。
十、实战建议与注意事项
- 两段式研究流程:在 Agent 的
instructions中明确"先用webSearch找到候选页面,再用webFetch读取正文再作答",能让模型按序使用工具,减少盲目抓取; - 分页技巧:
start每次递增 10(10、20…),结合输出里的currentPage可以设计多轮深度搜索的工作流; - 超时调整:Web Unlocker 处理复杂反爬页面可能耗时较长,默认 120 秒通常够用;若你的场景页面较轻,可通过
timeout收紧以降低等待; - zone 自定义:如果你在 Bright Data 控制台创建了专属 zone(用于配额统计或独立配置),务必通过
serpZone/webUnlockerZone或对应环境变量覆盖默认值,否则请求会落在默认 zone 上; - 凭证安全:优先使用环境变量注入
BRIGHTDATA_API_TOKEN,避免把 token 硬编码进源码或提交到仓库; - 错误处理:工具的错误已归一化为可读信息(key 无效、400 请求错误、超时等),在 Agent 上层做
try/catch或重试时可直接依赖这些信息。
十一、小结
@mastra/brightdata以极少的配置成本,把"搜索 + 抓取"两大联网能力以标准 Mastra Tool 的形式注入 Agent:webSearch负责从 Google 获取结构化自然搜索结果,webFetch负责用 Web Unlocker 穿透反爬读取正文,二者共享一套基于fetch的轻量客户端与统一的配置优先级。其核心实现集中在 integrations/brightdata/src 的client.ts、search.ts、fetch.ts三个文件中,配合 测试套件 即可完整掌握其行为边界,适合作为 Mastra 研究型、检索增强型 Agent 的联网底座。
【免费下载链接】mastraMastra is the modern TypeScript framework for AI-powered applications and agents.项目地址: https://gitcode.com/GitHub_Trending/ma/mastra
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考