Tabbit博客

Claude Agent SDK 浏览器工具:可运行的 Playwright 示例

用 Claude Agent SDK 接入受限的 Playwright 浏览器,无需 API 密钥即可验证成功、控件缺失和调用上限。

本文目录
  1. 选择浏览器接入方式
  2. 分开检查注册、执行和任务结果
  3. 实现三个工具
  4. 按执行顺序读源码
  5. 在本地运行示例
  6. 对照普通路径和故障路径
  7. 查看工具回执
  8. 在执行动作的地方约束工具
  9. 确定何时停止
  10. 遇到问题先核对页面
  11. 在模型之外验证结果
  12. 先迁移一条小流程

Claude Agent SDK 负责 Agent 循环,可以通过 MCP 调用工具。浏览器由工具处理器启动,成功条件也由项目定义。本例要求状态码实际出现在本地测试页上,点击完成只是其中一步。

选择浏览器接入方式

如果流程固定、输入已知且结果可以验收,适合做成范围明确的工具。探索陌生页面时,通用 Playwright MCP 提供的交互方式更灵活。Anthropic 的 API SDK 还有一套使用独立驱动接口的浏览器工具集。复制示例前,先确认自己接的是哪套 SDK 和接口。

API SDK 浏览器工具集文档 · Playwright 接入文档

浏览器 Agent · 浏览器自动化 · 浏览器自动化 Agent

分开检查注册、执行和任务结果

MCP 客户端能列出三个短名称,说明工具注册成功。下一层是处理函数是否打开了正确的页面。回执同时记录 URL 和可见状态,便于确认结果来自哪张页面。最后一层是任务验收,即使工具调用成功,也要单独看到预期状态才算完成。遇到故障时按这个顺序定位。

实现三个工具

用 tool() 声明参数校验和处理函数,再通过 createSdkMcpServer() 注册。可选 Agent 入口把服务放在 query().options.mcpServers.fixture 下,因此模型看到的工具名是 mcp__fixture__reveal_status。允许名单写完整名称,处理函数仍应约束每次调用能够访问的范围。 SDK 自定义工具文档

示例只允许打开普通或缺少控件的测试页。Playwright 创建没有登录状态的新上下文,参数用枚举,导航限定在测试页自己的来源。按按钮的无障碍名称精确查找,只有恰好一个匹配才点击。点击后读取状态区,并把可见文字与预期状态码核对。

工具实际回执
open_fixture({variant})Status code hidden
read_status()只读页面状态
reveal_status()Status code: SDK-17
点击后的可见状态

浏览器 Agent 安全 · 虚拟浏览器

按执行顺序读源码

先看 fixture.mjs 的两种测试路径,再到 browser-tools.mjs 找精确角色定位、状态回读和调用预算,最后读 smoke.mjs。冒烟客户端通过内存 MCP 枚举工具和调用工具。可选 Agent 循环使用相同的处理函数。先跑冒烟,便于把工具故障与模型授权或提示问题分开。

在本地运行示例

冒烟测试经内存传输连接真实的 SDK MCP 服务,由确定性客户端调用工具,并启动本地 Chromium。它不需要模型凭据。可选 Agent 入口需要你自己的授权 API 密钥。本次运行了冒烟测试,模型入口没有执行。

下载示例项目

npm ci
npx playwright install chromium
npm test

对照普通路径和故障路径

第一次调用打开普通页,第二次显示状态码,第三次独立读取状态。随后打开缺失按钮的故障页,预期操作失败,再读一次确认状态码仍然隐藏。后续用只读调用触发额度上限,第九次确认预算由宿主执行。冒烟通过说明这些断言在合成页上成立。

查看工具回执

故障页故意移除了按钮。操作工具返回错误、零个匹配,以及仍然隐藏的状态。独立页面读取确认代码没有出现。八次调用用完后,第九次返回预算错误。截图记录页面当时的状态,JSON 记录工具如何报告这次尝试。

{
  "isError": true,
  "ok": false,
  "code": "TARGET_MISSING_OR_AMBIGUOUS",
  "expected": "Reveal status code",
  "matches": 0,
  "observed": "Status code hidden"
}
故障测试页没有按钮,状态码仍然隐藏

在执行动作的地方约束工具

本项目只有一个本地来源、两种输入和一个按钮。替换测试页时保留同等的边界。页面内容是待处理数据,里面的指令无权扩大工具权限。不要把网页给出的选择器、脚本或目标地址直接传进处理器。增加写操作之前,先约定允许修改的字段、可执行的环境,以及结果无法确认时如何处理。

确定何时停止

控件缺失或有歧义时,保存页面状态,检查选择器后再改。点击已经执行但状态未更新时,先重新读取页面。调用用完时停止,保留最后一个已确认结果。涉及写入的流程应先准备回读检查,再决定是否重试写操作。

失败下一步
TARGET_MISSING_OR_AMBIGUOUS检查选择器
POSTCONDITION_FAILED重新读取页面
TOOL_BUDGET_EXHAUSTED停止并保留最后一次结果

一位 Claude Code 用户发现,助手称表单测试已通过,浏览器却没有可见操作。另一条浏览器工具讨论中,有人建议同时验证错误提示出现和后续动作确实停下。两条反馈帮助确定了本例的独立回读与停止检查。 r/ClaudeCode · r/AI_Agents

首次任务验收清单 · DevTools 浏览器调试

遇到问题先核对页面

状态读取失败可能因为适配器没打开目标页、页面缺少匹配控件,或点击已经触发但应用拒绝更新。保存失败代码和实际状态。超时或没有匹配时应先查看真实页面,避免把定位条件放宽到可能误点。确定性客户端能复现的问题,优先修工具或测试页,再调整模型提示。

在模型之外验证结果

可选 Agent 入口关闭内置工具,只允许三个工具名,并限制轮数和运行时长。即使模型报告成功,宿主也会独立检查页面。迁移时先写一条你能单独运行的回读检查,例如重新加载后核对保存的字段。

npm run agent

Agentic 推理

先迁移一条小流程

把合成页换成测试来源,把状态码换成一个明确的业务条件,并保留同样窄的输入范围。延续调用预算,记录能区分成功和失败的最少信息,例如动作名、稳定错误码与简短的验证结果。共享日志排除凭据、带用户信息的页面文字和原始表单值。小流程可以重复验证后,再增加其他动作。

常见问题

浏览器由哪个组件启动?

工具宿主里的本地 Playwright 适配器负责启动浏览器。

冒烟测试需要 API 密钥吗?

不需要。客户端直接调用 SDK 注册的 MCP 工具。

可以给示例传任意网址吗?

示例只接受两种测试页模式,导航限定在本地测试来源。

点击后为什么还要验收?

浏览器可以执行点击,但应用仍可能没有产生预期状态。

和通用 Playwright MCP 有什么区别?

通用服务提供可复用的浏览器操作,本例提供三个有明确结果的流程工具。

可以直接接真实表单吗?

先用测试页复现,接真实表单前明确写入策略并实现独立验证。

下一步

让 Tabbit 与你并肩工作。

跨标签页调研、自动化重复的浏览器工作,让每一处上下文都触手可及。