Claude Platform Docs
Messages工具

浏览器使用工具

借助浏览器使用工具,让 Claude 在您自己的浏览器环境中导航、读取网页并与网页交互。

"browser use tool"(浏览器使用工具)让 Claude 能够在您的应用程序所运行的浏览器中导航、读取网页并与网页交互。它既通过页面的结构("accessibility tree"(无障碍树)、元素、表单和标签页)也通过像素(屏幕截图和视口坐标)来处理页面,而计算机使用工具则仅通过屏幕截图和坐标来处理整个桌面。它是一个由 Anthropic 定义的客户端工具集:在您的 tools 数组中加入一个 browser_toolset_20260801 条目,默认即可为 Claude 提供 27 个成员工具,例如 navigateread_pageleft_clickscreenshot,当您启用它们时还会再增加四个(javascript_execfile_uploadread_consoleread_network)。您的应用程序针对自己的浏览器自动化运行每一次调用;没有任何内容在 Anthropic 一侧运行。它目前在 Claude Managed Agents 中不可用。本页用"您的应用程序"指代调用 Messages API 的"agent loop"(智能体循环),用"您的执行器"指代其中驱动浏览器并生成工具结果的部分。

当任务始终停留在网页内部时,请选择浏览器使用而非计算机使用:Claude 可以读取页面的结构,除了按坐标之外还可以按引用对元素执行操作,可以直接设置表单值,并且可以跨标签页工作,而您无需运行桌面。如果 Claude 只需要读取您可以指向的页面,或者在网络上查找来源,那么网页抓取工具网页搜索工具更加轻量,因为它们是由 API 为您运行的服务器工具,无需操作浏览器。当页面使用 JavaScript 构建其内容,或者任务意味着要对页面执行操作而不仅仅是读取时,请改为选择浏览器使用。

使用浏览器使用时,Claude 会读取实时网页并对其执行操作,因此页面提供的一切都是不受信任的输入,而 Claude 采取的操作可能产生真实的影响。部署之前请参阅安全注意事项

快速开始

浏览器使用工具可在 Claude API 和 Google Cloud 上使用:在 Messages API 请求的 tools 数组中添加一个类型为 browser_toolset_20260801、不带 name 的条目。

client = anthropic.Anthropic()

response = client.messages.create(
    model="claude-opus-5",
    max_tokens=2048,
    tools=[{"type": "browser_toolset_20260801"}],
    messages=[
        {
            "role": "user",
            "content": "Open example.com/docs and tell me how to get started.",
        }
    ],
)
print(response)

Claude 的第一个响应以 stop_reason: "tool_use" 结束,并携带一个或多个成员 tool_use 块,每个块在 name 中指明一个成员工具,并携带 "toolset_name": "browser"

Output
{
  "id": "msg_01HCDu4XSTLzTAcodEQ58vDo",
  "type": "message",
  "role": "assistant",
  "model": "claude-opus-5",
  "content": [
    {
      "type": "text",
      "text": "I'll open the documentation and read the page to find the getting-started instructions."
    },
    {
      "type": "tool_use",
      "id": "toolu_01NRLabsLyVHZPKxbKvkfSMn",
      "name": "navigate",
      "toolset_name": "browser",
      "input": { "url": "https://example.com/docs" }
    },
    {
      "type": "tool_use",
      "id": "toolu_01UvHU5cDyTZ2vXKf5wCkPqR",
      "name": "read_page",
      "toolset_name": "browser",
      "input": { "filter": "interactive" }
    }
  ],
  "stop_reason": "tool_use",
  "stop_sequence": null
}

您的执行器先运行 navigate,再运行 read_page,然后您的应用程序在下一个请求中为每个块返回一个 tool_result,并在每个结果上回显 toolset_namenavigate 的结果在一个 browser_state 块中报告它加载的标签页;read_page 的结果是文本,其中每个元素都带有一个引用:

{
  "role": "user",
  "content": [
    {
      "type": "tool_result",
      "tool_use_id": "toolu_01NRLabsLyVHZPKxbKvkfSMn",
      "toolset_name": "browser",
      "content": [
        { "type": "text", "text": "Navigated to https://example.com/docs" },
        {
          "type": "browser_state",
          "tabs": [
            {
              "tab_id": "tab-1",
              "title": "Documentation",
              "url": "https://example.com/docs",
              "active": true
            }
          ]
        }
      ]
    },
    {
      "type": "tool_result",
      "tool_use_id": "toolu_01UvHU5cDyTZ2vXKf5wCkPqR",
      "toolset_name": "browser",
      "content": [
        {
          "type": "text",
          "text": "link \"Documentation\" [ref_1]\nlink \"Getting started\" [ref_2]\ntextbox \"Search docs\" [ref_3]\nbutton \"Search\" [ref_4]\nlink \"Pricing\" [ref_5]"
        }
      ]
    }
  ]
}

Claude 现在持有可以据以执行操作的引用,因此它的下一轮可以点击 ref_2 来打开入门页面,而无需先在屏幕截图中定位该链接。

浏览器使用的工作原理

浏览器使用以智能体循环的方式运行:Claude 返回成员工具调用,您的执行器针对浏览器运行它们,然后您返回结果,直到 Claude 以文本作答。

  1. 为 Claude 提供浏览器使用工具和用户提示

    • browser_toolset_20260801 条目(以及可选的其他工具)添加到您的 API 请求中。
    • 包含一个需要处理网页的用户提示,例如"打开 example.com/docs 并告诉我如何开始。"
  2. Claude 以成员工具调用作出响应

    • Claude 在单个助手轮次中返回一个或多个 tool_use 块;一个轮次中的多个块构成一个批量操作,例如先 left_click,再 type,再 key
    • 每个块的 name 是成员名称,每个块都携带 "toolset_name": "browser",而 input 仅包含该成员的参数,没有 action 字段。响应的 stop_reasontool_use
  3. 按顺序运行调用并返回结果

    • 遍历 response.content 中的每个 tool_use 块(不要假设恰好只有一个),并按它们出现的顺序依次运行,因为后面的调用通常依赖于前面的调用。
    • 在一条新的 user 消息中为每个块返回一个 tool_result,通过 tool_use_id 匹配,并在每个结果上回显 "toolset_name": "browser"。每个调用都必须得到应答,否则下一个请求会被拒绝。
    • 如果某个调用失败,请为该块返回 is_error: true 及文本描述,然后对该轮次中之后的每个块应用批量操作中的中止规则。
  4. Claude 继续执行直到任务完成

    • Claude 读取结果(页面文本、无障碍树、屏幕截图、标签页状态),如果还需要更多信息,则返回进一步的成员调用,这会让您回到第 3 步。
    • 否则,它向用户返回文本响应。

下面是该循环中工具调用步骤的骨架,分为两部分。首先,存根成员处理程序代替您的浏览器自动化。五个成员(navigateread_pageleft_clicktypescreenshot)返回将成为结果内容的文本(对于 screenshot 则是图像块),而调度器会对它未实现的任何成员抛出错误。

# 占位图像数据;真实的执行器会捕获视口并返回 PNG 字节
PLACEHOLDER_PNG = "iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNkYPhfDwAChwGA60e6kgAAAABJRU5ErkJggg=="


def navigate(url):
    return f"navigated to {url}"


def read_page():
    return 'link "Docs" [ref_1]\nbutton "Search" [ref_2]'


def click(target):
    # 目标是来自 read_page 或 find 的元素引用,或视口坐标
    if target["type"] == "ref":
        return f"clicked {target['ref']}"
    return f"clicked at ({target['x']}, {target['y']})"


def type_text(text):
    return f"typed: {text}"


def capture_screenshot() -> list[ImageBlockParam]:
    # screenshot 以图像块而非文本作答:返回结果内容列表
    return [
        {
            "type": "image",
            "source": {"type": "base64", "media_type": "image/png", "data": PLACEHOLDER_PNG},
        }
    ]


def handle_browser_action(name, tool_input):
    if name == "navigate":
        return navigate(tool_input["url"])
    elif name == "read_page":
        return read_page()
    elif name == "left_click":
        return click(tool_input["target"])
    elif name == "type":
        return type_text(tool_input["text"])
    elif name == "screenshot":
        return capture_screenshot()
    # 按需处理其他操作
    raise ValueError(f"Unknown or unimplemented member: {name}")

第二部分按顺序运行一个批次,将每个块分派给这些处理程序,在每个结果上回显 toolset_name,并应用批量操作中的中止规则,将处理程序错误转换为错误结果。调用它的采样循环就是理解智能体循环中展示的那个循环,只是 tools 中放的是浏览器工具集。

NOT_EXECUTED = "Not executed: an earlier action in this turn failed."


def process_tool_calls(response: Message) -> list[ToolResultBlockParam]:
    """
    Run the browser actions in Claude's response in order and answer each
    one. After the first failure the rest are skipped, because Claude planned
    them assuming the earlier actions succeeded.
    """
    tool_results: list[ToolResultBlockParam] = []
    failed = False
    for block in response.content:
        # 仅声明了浏览器工具集;如添加其他工具,请在此处路由
        if block.type != "tool_use" or block.toolset_name != "browser":
            continue
        result: ToolResultBlockParam = {
            "type": "tool_result",
            "tool_use_id": block.id,
            "toolset_name": "browser",
        }
        if failed:
            result["content"] = NOT_EXECUTED
            result["is_error"] = True
        else:
            try:
                # 字符串或内容块列表;真实的执行器还会向
                # 导航和标签页管理结果中添加 browser_state 块
                result["content"] = handle_browser_action(block.name, block.input)
            except Exception as err:
                result["content"] = f"Error: {err}"
                result["is_error"] = True
                failed = True
        tool_results.append(result)
    return tool_results

请根据(toolset_namename)这一对值而不是仅根据 name 来分派每个块,因为同一请求中的自定义工具可能与某个成员同名;客户端工具集描述了两个工具集共享的这部分约定。如果 Claude 指明了您的执行器未实现的成员,或者您已禁用的成员,请用错误结果应答该块,而不是丢弃它。

当您以流式传输方式接收响应时,每个成员的 input 会作为一个完整的 input_json_delta 到达,而不是分片到达,因此请等待该轮次结束后再运行批次。

批量操作

包含多个成员调用的轮次是一个批量操作:按调用出现的顺序运行它们,在第一次失败时停止,并用 is_error: true 和确切文本 Not executed: an earlier action in this turn failed. 应答之后的每个调用。批次使用与并行工具使用相同的响应形状;区别在于您按顺序而非并发地运行这些块。在这里,Claude 在一个轮次中点击它之前找到的搜索框、输入查询并按下 Enter:

{
  "role": "assistant",
  "content": [
    {
      "type": "tool_use",
      "id": "toolu_01D7FLrfh4GYq7yT1ULFeyMV",
      "name": "left_click",
      "toolset_name": "browser",
      "input": { "target": { "type": "ref", "ref": "ref_3" } }
    },
    {
      "type": "tool_use",
      "id": "toolu_01Ez4kLb1nQ2vXo8sJ9pWm3c",
      "name": "type",
      "toolset_name": "browser",
      "input": { "text": "install" }
    },
    {
      "type": "tool_use",
      "id": "toolu_01FkP8rTz6uYh2mNq4LsXw7v",
      "name": "key",
      "toolset_name": "browser",
      "input": { "text": "Enter" }
    }
  ]
}

您的应用程序在一条 user 消息中返回三个 tool_result 块,每个块都携带 toolset_name 和一段简短的文本确认,例如 Clicked element ref_3.。按下 Enter 会加载结果页面,因此 key 的结果还携带一个包含该标签页更新后 URL 的 browser_state 块(其他结果上的标签页上下文)。如果点击失败了,它的结果将携带您的错误文本,而另外两个结果将携带中止文本,如从执行器返回错误中所示。

您不需要在每次调用后都返回屏幕截图。Claude 通常以一个观察调用(screenshotread_pageget_page_text)结束一个批次,您的应用程序也可以将自己的观察结果(例如一张新的屏幕截图或无障碍树)作为额外的内容块附加到批次中最后一个结果上,以节省一次往返。由于标签页管理结果必须恰好是一个 browser_state 块,请将其附加到最后一个不是标签页管理调用的结果上。

如果您的执行器每次往返只能运行一个调用,请在 tool_choice 中将 disable_parallel_tool_use 设为 true,Claude 每轮最多返回一个成员调用,代价是更多的往返次数(禁用并行工具使用)。计算机使用工具的批量操作下的其余约定同样适用,包括在下一条 user 消息中为每个 tool_use 返回一个 tool_result,但有两点例外:中止文本,以及成功结果的 content 所包含的内容。结果内容改为遵循本页的成员工具new_tabswitch_tabclose_tablist_tabs 的结果恰好是一个 browser_state 块,不含文本或图像(标签页管理结果),而任何其他成员的结果可以在其文本或图像之外添加一个 browser_state 块(其他结果上的标签页上下文)。批次内的缓存断点在何处生效,在计算机使用工具的工具参数cache_control 行中有说明。

目标和坐标

对某个位置执行操作的成员工具接受一个 target 对象,它要么是视口像素坐标,要么是对 read_pagefind 返回的元素的引用。成员工具表格中用 Target 表示接受任一形状的参数。

形状target.type字段接受者
CoordinateTarget"coordinate"xy(整数,视口像素)left_clickright_clickmiddle_clickdouble_clicktriple_clickhoverleft_click_dragfromtarget)、left_mouse_downleft_mouse_upmouse_movescroll
RefTarget"ref"ref(元素引用,例如 "ref_2"left_clickright_clickmiddle_clickdouble_clicktriple_clickhoverscroll_toform_inputfile_upload

坐标是视口像素,即全视口 screenshot 的像素空间,原点位于渲染页面的左上角;没有周围的桌面或窗口边框。工具集不声明显示尺寸,Claude 从您返回的屏幕截图推断视口大小,因此请保持它们尺寸一致。zoom 不会改变坐标系,因此它的 region 以及 Claude 在看到放大图像后发出的任何坐标仍然是全视口像素。

屏幕截图必须符合图像限制。 API 不会缩小工具集图像:超过您模型的图像尺寸限制,或超过请求包含超过 20 张图像时适用的更严格的单图限制的屏幕截图或缩放图像会被拒绝。请在返回前调整大小,并在分派 Claude 的坐标之前按您缩放因子的倒数将其放大回去(调整屏幕截图大小以符合图像限制)。

元素引用来自 read_pagefind 它们输出中的每个元素都带有一个标签,例如 [ref_2],如快速开始的结果所示:

link "Documentation" [ref_1]
link "Getting started" [ref_2]
textbox "Search docs" [ref_3]
button "Search" [ref_4]
link "Pricing" [ref_5]

Claude 在之后的点击、hoverscroll_toform_inputfile_upload 调用中以 {"type": "ref", "ref": "ref_2"} 目标的形式传回引用,或者作为 read_pageref 参数来读取子树。您的执行器负责分配引用,保存每个引用到底层节点(无障碍节点 ID、存储的选择器或等效物)的映射,并在引用传回时对该节点执行操作。

引用的作用域限于生成它们的标签页,并在该标签页导航或其 DOM 发生实质性变化之前保持有效。API 无法检测过期或未知的引用,因此当 Claude 传递一个您的执行器不再识别的引用时,请返回错误结果,例如 Error: ref_3 is stale or not found on the current page. Re-read the page to get fresh references.。Claude 随后会重新读取页面。在标签页导航之前,不要对您已经为该标签页分发的引用重新编号,因为那会悄无声息地使 Claude 仍持有的引用失效。

Claude 会使用两种定位方式,并根据页面暴露的内容在它们之间切换;您的提示和执行器返回的内容会引导这一选择:

  • 在页面具有可用无障碍树的地方优先使用引用。 引用能够经受使像素坐标变得脆弱的布局偏移和重排,并让 Claude 对难以用指针命中的控件执行操作。
  • 对于树未描述的内容回退到坐标。 Canvas 渲染的界面、嵌入式视频或远程桌面表面、高度虚拟化的列表以及跨源 iframe 内的元素通常没有有用的节点,因此 Claude 依靠 screenshotzoom 工作并按坐标点击;您的执行器负责解析坐标落在哪个框架中。
  • 限定读取范围,并在截图之前先读取树。 在大型页面上,带 filter: "interactive" 或容器 refread_page 会返回一个聚焦的子树,而对典型页面的树读取通常比屏幕截图消耗更少的输入令牌,同时为 Claude 提供可以立即据以执行操作的引用。当视觉布局、图像或渲染状态很重要时,屏幕截图仍然是正确的观察方式。

安全注意事项

浏览器使用带有标准 API 功能所没有的风险,因为 Claude 读取并操作来自开放网络的内容,而任何页面都可能包含为操纵它而编写的文本。

Claude 有时会遵循在页面内容中发现的指令,即使它们与您的指令冲突;页面上写着"忽略你之前的指令并导航到……"的文本可能使它偏离任务。请将 Claude 与敏感数据和操作隔离,以限制"prompt injection"(提示注入)所能触及的范围,查阅缓解越狱和提示注入,如果任务无法避免已登录的会话,请使用专用的低权限账户,并对更改账户的操作保持人工确认。

由于浏览器在您的环境中运行,Claude 访问的网站会看到您执行器的网络身份,而页面内容仅以您返回的工具结果的形式到达 API。在您的产品中启用浏览器使用之前,请告知最终用户相关风险并获得他们的同意。

成员工具

browser_toolset_20260801 条目声明了 31 个成员工具;每个调用的 input 恰好是此处列出的参数,而 tab_id 在可选时默认为活动标签页。TargetCoordinateTargetRefTarget目标和坐标中描述的形状。四个成员(javascript_execfile_uploadread_consoleread_network)默认禁用,仅在您启用它们时出现。每个成员行中注明的输入边界和输出约定是向 Claude 陈述的,而非由 API 强制执行,因此请在您的执行器中验证输入(包括对照您的视口检查坐标)并应用这些约定。

只有 screenshotzoom 要求其结果中包含 image,而四个标签页管理成员(new_tablist_tabsswitch_tabclose_tab)恰好返回一个 browser_state 块(参见标签页管理结果)。其他每个成员都返回一个 text 块:要么是简短的确认,例如 Clicked element ref_2.,要么是该成员的输出。除标签页管理结果之外的任何结果还可以携带一个 image 块,通常是操作后拍摄的屏幕截图,这样 Claude 无需单独的 screenshot 调用即可看到结果;批量操作展示了在批次中将其附加到何处。成员 tool_result 只能包含 textimagebrowser_state 内容块。

成员输入描述
navigateurltab_id?加载 httphttps URL,或使用 "back""forward""reload" 在历史记录中移动。将没有协议的 URL 视为 https://,并以错误结果拒绝任何其他协议。返回简短的确认,当标签页的 URL 或标题发生变化时再加上一个 browser_state 块。
screenshottab_id?捕获视口并返回一个 image 块。
zoomregiontab_id?返回 region(以视口像素表示为 [x0, y0, x1, y1])的裁剪并放大的 image,用于更仔细地检查小文本或控件。

指针

成员输入描述
left_clicktarget: Targetmodifiers?tab_id?左键点击坐标或被引用的元素。modifiers 是点击期间按住的组合键,例如 "shift""ctrl+shift"
right_clicktarget: Targetmodifiers?tab_id?右键点击坐标或元素。
middle_clicktarget: Targetmodifiers?tab_id?中键点击坐标或元素。
double_clicktarget: Targetmodifiers?tab_id?左键双击坐标或元素。
triple_clicktarget: Targetmodifiers?tab_id?左键三击坐标或元素,通常会选中一行或一个段落。
hovertarget: Targettab_id?将指针移到坐标或元素上方而不点击。
left_click_dragfrom: CoordinateTargettarget: CoordinateTargettab_id?from 处按下,拖动到 target,然后释放。
left_mouse_downtarget: CoordinateTargettab_id?在坐标处按下并按住左键;与 left_mouse_up 配对以实现自定义拖动。
left_mouse_uptarget: CoordinateTargettab_id?在坐标处释放左键。
mouse_movetarget: CoordinateTargettab_id?将指针移动到坐标。
scrolltarget: CoordinateTargetscroll_directionscroll_amount?tab_id?在视口位置滚动。scroll_direction"up""down""left""right"scroll_amount 以滚轮刻度为单位,1 到 10,默认 3。
scroll_totarget: RefTargettab_id?将被引用的元素滚动到视图中。

键盘和计时

成员输入描述
typetexttab_id?在当前焦点处输入字面字符串。
keytextrepeat?tab_id?按下一个键或组合键。text 是单个键("Enter")、用 + 连接的组合键("ctrl+a")或以空格分隔的序列("Backspace Backspace");repeat 为 1 到 100,默认 1。
hold_keytextdurationtab_id?按住一个键或组合键 duration 秒,0 到 30。
waitdurationtab_id?暂停 duration 秒,0 到 30。

页面读取

成员输入描述
read_pagefilter?depth?ref?tab_id?以文本形式返回页面的无障碍树,每个元素都带有一个引用标签,例如 [ref_2]。省略 filter 时返回每个可见元素;为 "interactive" 时仅返回可见的交互元素;为 "all" 时还包括视口之外的元素。depth 限制树的深度(最小 1,默认 15),ref 将读取范围限定为该元素的子树。将输出限制在 50,000 个字符以内并在文本中说明;Claude 随后会用更小的 depthref 缩小范围。
findquerytab_id?搜索与自然语言描述(例如 "search field""add to cart button")匹配的元素,并以与 read_page 相同的带标签格式返回最多 20 个匹配项。
get_page_texttab_id?以纯文本形式返回页面的可见文本,优先返回主要文章内容;适用于文章、文档和其他以文本为主的页面。

表单和文件

成员输入描述
form_inputtarget: RefTargetvaluetab_id?直接设置表单元素的值。valuestringnumberboolean;对复选框使用 boolean,对下拉选择框使用选项的值或可见文本。
file_upload(默认禁用)target: RefTargetpaths?document_ids?tab_id?从执行器文件系统上的 paths、您的应用程序已暂存的 document_ids 或两者设置文件输入元素上的文件;至少需要其中之一。参见上传文件

诊断和脚本

成员输入描述
read_console(默认禁用)tab_id?返回自上次读取以来累积的标签页控制台条目(日志、警告和错误行),每个条目一行。参见读取控制台和网络活动
read_network(默认禁用)tab_id?返回自上次读取以来标签页的网络请求(方法、URL、状态、MIME 类型、计时),每个条目一行。
javascript_exec(默认禁用)texttab_id?在页面上下文中将 text 作为 JavaScript 运行,并以文本形式返回最后一个表达式的值。参见启用可选成员

标签页管理

成员输入描述
new_tab(无)打开一个标签页并使其成为活动标签页。
list_tabs(无)报告标签页清单。
switch_tabtab_id(必需)使 tab_id 成为活动标签页。
close_tabtab_id(必需)关闭 tab_id

成功时,这些成员中的每一个都恰好返回一个 browser_state 块,不含文本或图像;参见标签页管理结果

配置工具集

type 之外,工具集条目还接受 configscache_controlallowed_callers;这些字段与计算机使用工具集共享的规则列在客户端工具集下,本节介绍浏览器特有的默认值。configs 是一个以成员名称为键的对象,每个成员的值接受两个字段:

字段默认值含义
enabledtrue,但四个可选成员false是否向 Claude 提供该成员。
defer_loadingfalse工具集的定义是否为工具搜索而延迟加载。必须在每个已启用的成员上解析为相同的值。在四个可选成员保持禁用的情况下,延迟加载工具集意味着在其他 27 个成员上设置它;参见客户端工具集

启用或禁用成员工具

configs 中只列出您想要更改的成员;您省略的每个成员都保持其默认值。例如,一个实现了控制台读取但未实现低级指针或按键保持控制的执行器会启用 read_console 并保留三个成员不提供:

{
  "type": "browser_toolset_20260801",
  "configs": {
    "read_console": { "enabled": true },
    "left_mouse_down": { "enabled": false },
    "left_mouse_up": { "enabled": false },
    "hold_key": { "enabled": false }
  }
}

被禁用的成员会从 Claude 看到的定义中消失;这并不保证 Claude 永远不会指明它,因此您的执行器仍应以错误结果应答此类调用。

与其他工具组合

在同一个 tools 数组中将浏览器使用工具与您自己的工具以及其他 Anthropic 提供的工具一起声明。自定义工具可以与某个成员同名(例如您自己的 navigate),因为 toolset_name 可以区分 Claude 的调用,但其他任何条目都不能命名为 browser,并且一个请求只能包含一个浏览器工具集条目。

您也可以将它与计算机使用工具一起声明,无论是工具集还是更早的计算机使用工具版本。两者独立工作,各自使用自己的坐标系(这里是视口像素,那里是桌面屏幕截图像素),而 Claude 对同名成员(例如 screenshotkey)的调用通过 toolset_name 加以区分。

启用可选成员

四个成员工具默认禁用:javascript_execfile_upload 是因为它们扩大了被操纵的页面可能让 Claude 做的事情,read_consoleread_network 是因为并非每个浏览器自动化栈都能提供这些日志,而且它们扩大了到达 Claude 的页面控制内容的范围。仅当您的执行器实现了某个成员且任务需要它时,才使用 configs 启用它(例如 "configs": {"file_upload": {"enabled": true}})。

上传文件

file_upload 直接设置 <input type="file"> 元素上的文件,这比驱动原生文件选择器更可靠。它的 target 只能是引用,因为该调用需要元素的身份,并且它接受 pathsdocument_ids 或两者:

  • paths 是执行器文件系统上的文件路径,适用于执行器可以直接读取您应用程序文件的部署(与您填充下载的 path 的条件相同)。
  • document_ids 是您的应用程序为浏览器暂存的文件的标识符,适用于执行器无法直接读取的部署。您的应用程序定义这些标识符的含义;请像限定 paths 那样限定它们的解析范围,仅限于为此任务暂存的文件。
{
  "type": "tool_use",
  "id": "toolu_01N7gVzFEfZjLjgsYwnrPgrF",
  "name": "file_upload",
  "toolset_name": "browser",
  "input": {
    "target": { "type": "ref", "ref": "ref_12" },
    "paths": ["/home/user/uploads/summary.pdf"],
    "tab_id": "tab-2"
  }
}

Claude 在读取不受信任的页面时写下这些路径,因此不受限制的实现会让恶意页面指示将执行器可读取的任何文件上传到该页面控制的网站。仅当您的执行器解析每个路径(跟随符号链接和 .. 段)并且不接受专用的、列入允许列表的上传目录(其中仅包含用于该任务的文件)之外的任何内容时,才启用该成员。不要为此重用浏览器的下载目录;如果这样做,页面导致浏览器下载的每个文件都将变得可上传。

在页面中运行 JavaScript

javascript_exec 在页面的上下文中运行 Claude 编写的表达式,并以文本形式返回最后一个表达式的值;Claude 编写的是表达式,而不是 return 语句。代码以页面的完整权限运行,包括其 cookie、存储和同源请求。仅在不持有任何凭据的会话中启用该成员,保持安全注意事项中的域名允许列表有效,将返回值视为不受信任的输入,并记录 Claude 发出的代码。

读取控制台和网络活动

read_console 返回标签页的控制台条目,read_network 返回其网络请求,均为文本形式,自上次读取该标签页以来累积的每个条目占一行。控制台行携带日志、警告或错误条目;网络行携带方法、URL、状态、MIME 类型和计时。条目仅从您的浏览器自动化附加到该标签页的那一刻起存在,因此空结果并不意味着一个已经打开的标签页没有流量。

这些成员让 Claude 无需反复截图即可诊断行为异常的页面(加载指示器背后失败的请求、失效按钮背后的脚本错误)。控制台和网络条目由页面控制,并且经常包含机密信息,例如请求 URL 中的令牌,因此请在返回之前对您不希望出现在 Claude 上下文中的类似凭据的值进行脱敏,并截断非常长的条目。

使用 browser_state 跟踪标签页

Claude 通过 tab_id 来指定标签页,您的应用程序是哪些标签页存在的权威来源,您在一个 browser_state 内容块中报告该状态,而 Claude 永远不会直接看到该内容块:API 会渲染 Claude 从中读取的文本。

{
  "type": "browser_state",
  "tabs": [
    {
      "tab_id": "tab-1",
      "title": "Documentation",
      "url": "https://example.com/docs",
      "active": true
    },
    { "tab_id": "tab-2", "title": "Pricing", "url": "https://example.com/pricing" }
  ]
}
  • tabs 是调用之后所有已打开标签页的完整清单,而不是增量。它可以为空;只要它不为空,就必须恰好有一个条目带有 "active": true
  • state_changes(此处未展示)报告调用的副作用:对于调用打开的、且在调用结束时仍处于打开状态的每个标签页,都有一个 tab_opened 条目,其 tab_id 也必须出现在 tabs 中;此外还有下载事件。当没有内容需要报告时请省略该字段;空数组会被拒绝。
  • 仅在回应浏览器成员调用的结果上发送该内容块,每个 tool_result 最多发送一次,并且绝不要在带有 is_error: true 的结果上发送。您通过省略该内容块来表达"没有标签页状态需要报告"。
  • API 会按照接下来两节所描述的方式将 tabs 渲染为供 Claude 阅读的文本;state_changes 中的下载条目会被校验,但不会被渲染。

tab_id 的值由您分配。 任何稳定的字符串都可以,例如您的自动化库的页面标识符或您自己的计数器,只要您不在某个标签页仍在较早的结果中被列为打开状态时重复使用该 tab_id 即可。API 对该内容块强制执行以下限制:

  • 每个 tab_idtitleurl 最多 4,096 个字符,tab_id 必须非空,并且它们都不得包含控制字符(包括换行符)或 Unicode 行分隔符或段落分隔符。
  • 一个内容块最多可列出 100 个标签页和 200 个状态变更。
  • 同样的限制也适用于 Claude 传递给 switch_tabclose_tabtab_id,因为 API 会将其渲染到结果文本中,因此对于 tab_id 违反这些限制的调用,请以错误结果而非 browser_state 内容块来回应。

标签页管理结果

对于 new_tabswitch_tabclose_tablist_tabs,成功结果的 content 恰好是一个 browser_state 内容块,不含文本或图像,由 API 写入 Claude 看到的文本。new_tab 结果的内容块还必须恰好携带一个 tab_opened 状态变更,其 tab_id 与标记为 active: true 的条目相匹配。

成员Claude 看到的文本
switch_tabSwitched to tab {tab_id},取自调用的 input.tab_id
close_tabClosed tab {tab_id},取自调用的 input.tab_id
new_tabCreated new tab with tab_id: {tab_id}, URL: {url}. It is now the current tab.,取自标记为 active: true 的条目
list_tabsAvailable tabs: 后跟每个标签页一行,或者当 tabs 为空时为 No tabs available

一个 list_tabs 结果,其内容块列出两个标签页且第一个处于活动状态,渲染结果如下,每行缩进两个空格,且仅在活动标签页后追加 (current)

Available tabs:
  • tab_id tab-1: "Documentation" (https://example.com/docs) (current)
  • tab_id tab-2: "Pricing" (https://example.com/pricing)

这些成员之一的错误结果则相反:content 中是普通的错误文本,is_error: true,并且没有 browser_state 内容块。

例如,当 Claude 调用 new_tab(其 input 为空)时,您的执行器打开该标签页,将其设为活动状态,并返回带有一个 tab_opened 条目的清单:

{
  "role": "user",
  "content": [
    {
      "type": "tool_result",
      "tool_use_id": "toolu_01WvHSbQVV9j5nWGvTmk4vNL",
      "toolset_name": "browser",
      "content": [
        {
          "type": "browser_state",
          "tabs": [
            { "tab_id": "tab-1", "title": "Documentation", "url": "https://example.com/docs" },
            { "tab_id": "tab-2", "title": "Pricing", "url": "https://example.com/pricing" },
            { "tab_id": "tab-3", "title": "", "url": "about:blank", "active": true }
          ],
          "state_changes": [{ "type": "tab_opened", "tab_id": "tab-3" }]
        }
      ]
    }
  ]
}

Claude 看到 Created new tab with tab_id: tab-3, URL: about:blank. It is now the current tab.。请像此处一样报告标签页打开时的 URL,而不是它之后重定向到的 URL;后续结果会报告该标签页届时的当前 URL。

其他结果上的标签页上下文

在所有其他成员上,该内容块是可选的:当已打开标签页的集合、活动标签页、或某个标签页的标题或 URL 发生变化时,或者当有 state_changes 需要报告时发送它,并且始终包含完整的 tabs 清单。当一个结果同时携带文本和 browser_state 内容块时,API 会在该结果的文本后追加一个 Tab Context 页脚,与您的文本之间以一个空行分隔,这样 Claude 无需单独调用 list_tabs 即可获得新状态:

Tab Context:
- Executed on tab_id: tab-1
- Available tabs:
  • tab_id tab-1: "Documentation" (https://example.com/docs)
  • tab_id tab-2: "Pricing" (https://example.com/pricing)

Executed on 指明调用运行所在的标签页,即存在 tab_id 输入时为该输入,否则为活动标签页,并且页脚中的标签页行不带 (current) 标记。不要自行追加此文本;请发送结构化内容块并让 API 来渲染它。页脚会被去重,因此相同的标签页状态不会在后续结果上再次渲染,大量填充该内容块不会产生任何成本。

有三种情况即使存在该内容块也不会渲染页脚:

  • 任何 zoom 结果。
  • 没有 text 内容块的结果(例如仅含图像的 screenshot 结果)。该结果不会渲染或记住任何内容;标签页上下文会出现在下一个同时携带文本和 browser_state 内容块的结果上,因此当您希望 Claude 在同一结果上看到标签页变化时,请在图像旁附带一个简短的文本内容块。
  • 在未携带 tab_id 的调用上,tabs 列表为空的结果,因为没有可指明的标签页。

例如,当 Claude 在本会话早些时候点击"Pricing"链接(ref_5)时,页面在一个 Claude 并未请求的新标签页中打开了它,如果没有报告,Claude 将不得不调用 list_tabs 才能发现它。请返回点击的确认信息,外加一个在 state_changes 中指明所打开标签页的内容块,并标记您的执行器保留为活动状态的那个标签页:

{
  "role": "user",
  "content": [
    {
      "type": "tool_result",
      "tool_use_id": "toolu_01EgTXj1FjE2FCTt2zNFWLao",
      "toolset_name": "browser",
      "content": [
        { "type": "text", "text": "Clicked element ref_5." },
        {
          "type": "browser_state",
          "tabs": [
            {
              "tab_id": "tab-1",
              "title": "Documentation",
              "url": "https://example.com/docs",
              "active": true
            },
            { "tab_id": "tab-2", "title": "Pricing", "url": "https://example.com/pricing" }
          ],
          "state_changes": [{ "type": "tab_opened", "tab_id": "tab-2" }]
        }
      ]
    }
  ]
}

Claude 看到 Clicked element ref_5.,后跟前面展示的 Tab Context 页脚。在失败的调用期间打开的标签页不会获得 tab_opened 条目,因为错误结果不携带 browser_state;它会改为出现在下一个成功结果的 tabs 清单中。在批处理中,请将该内容块附加到变化发生期间所对应调用的结果上,并为每个成功的标签页管理结果提供其自己的内容块,即使同一轮次中较早的结果已报告了相同的状态。

报告下载

当点击或导航启动文件下载时,请在下载发生期间所对应调用的结果上的 state_changes 中报告它,并通过您分配的 download_id 在各结果之间进行关联。下载是异步运行的,可能跨越多个结果,因此有三种事件类型:

type字段何时发送
download_starteddownload_idurl在下载开始期间所对应调用的结果上。url 是经过重定向后文件实际提供的最终 URL。
download_completeddownload_idurlpath?size_bytes?在下载完成时正在运行的任何后续调用的结果上。仅当同一环境中的另一个工具(例如 bash 工具file_upload)可以在该位置读取文件时才包含 path;否则 download_id 是该下载的唯一标识符。
download_faileddownload_idurlerror?当下载失败或被取消时,如果浏览器提供了原因,则在 error 中给出。

API 会校验这些条目,但不会将它们渲染为 Claude 看到的文本,因此当 Claude 需要对该文件进行操作时,还请在同一结果的 text 内容块中提及文件名或 path

例如,在 Pricing 标签页中点击"Download price list (CSV)"(ref_8)会启动一个下载,因此该点击的结果携带一个 download_started 条目,其 download_id"dl-1",并带有文件的 URL。下载在后续的 screenshot 调用运行期间完成,因此该结果的 content 包含图像、一个诸如 Screenshot captured. Download complete: /home/user/downloads/price-list.csv (48,213 bytes). 的文本内容块,以及这个在相同 download_id 下报告完成的 browser_state 内容块:

{
  "type": "browser_state",
  "tabs": [
    { "tab_id": "tab-1", "title": "Documentation", "url": "https://example.com/docs" },
    {
      "tab_id": "tab-2",
      "title": "Pricing",
      "url": "https://example.com/pricing",
      "active": true
    }
  ],
  "state_changes": [
    {
      "type": "download_completed",
      "download_id": "dl-1",
      "url": "https://example.com/pricing/price-list.csv",
      "path": "/home/user/downloads/price-list.csv",
      "size_bytes": 48213
    }
  ]
}

下载报告遵循以下规则:

  • 单个内容块中每个 download_id 最多一个条目,因此在同一调用期间开始并完成的下载仅报告 download_completed
  • 绝不要在 is_error: true 的结果上发送 state_changes;在失败调用期间发生的下载事件请在下一个成功结果上报告。
  • state_changes 不是进行中下载的清单;每个事件只报告一次。
  • 每个条目仅携带其 type 所声明的字段。size_bytes 是非负整数,download_id 非空,并且 download_idurlpatherror 各自最多 4,096 个字符,不含控制字符或 Unicode 行分隔符或段落分隔符。url 来自远程服务器,在重定向后通常携带已签名的查询字符串凭据,因此请剥离您不希望出现在 Claude 上下文中的查询参数,并在报告它或将其用于文件系统路径之前对其进行清理。

处理错误

将失败的调用作为普通错误结果报告给 Claude:is_error: true、说明出错原因的文本内容、回显的 toolset_name,并且没有 browser_state 内容块。

从您的执行器返回错误

请使错误文本具体明确,因为 Claude 会阅读它并做出调整:Error: Navigation to https://example.com/status timed out after 30 seconds. The page may be unavailable. 为 Claude 提供了可据以行动的信息,而简单的 Error: navigation failed 则没有。其他常见情况:

请求错误

API 会校验工具集条目以及对话中的每个成员 tool_usetool_result 内容块。当其中之一格式错误时,API 会在 Claude 运行之前返回 invalid_request_error。在下表中,左列指明您发送的内容。

请求失败原因及处理方法
工具集条目不接受的选项或组合,例如条目本身上的 namestrict: trueinput_examplesdefer_loading,不是成员名称的 configs 键,成员的 configs 值中除 enableddefer_loading 之外的字段(配置工具集),defer_loading 值不同的已启用成员(配置工具集),未留下任何已启用成员的 configsallowed_callers 中的代码执行调用方,请求上的旧版 fine-grained-tool-streaming-2025-05-14 beta 标头,类型为 tool 且指定 browser 或某个成员的 tool_choice,或者第二个浏览器工具集条目或另一个名为 browser 的工具客户端工具集不支持这些。请参阅客户端工具集了解每条规则及其替代方案。
回应成员调用的 tool_result 没有 "toolset_name": "browser" 或带有不同的值,或者在其调用并非成员调用的结果上带有 toolset_name在成员结果上准确回显 toolset_name,并且仅在成员结果上回显。
来自较早轮次的成员 tool_use 没有匹配的 tool_result回应每个成员调用,包括失败后您未运行的那些调用。
成员结果中除 textimagebrowser_state 之外的内容块成员结果仅接受这三种内容块类型。
违反使用 browser_state 跟踪标签页中规则的 browser_state 内容块,例如位于 is_error: true 结果上或位于不回应浏览器成员调用的结果上的内容块,一个结果中有多个内容块,非空的 tabs 没有恰好一个 active: true 条目,重复的 tab_id,空的 state_changes 数组,tab_id 不在 tabs 中的 tab_opened,同一 download_id 有两个状态变更或状态变更字段未被其 type 声明(报告下载),或者字段超出其限制修复该内容块。"没有内容需要报告"通过省略该内容块或 state_changes 字段来表达,绝不通过空值来表达。
成功的 new_tabswitch_tabclose_tablist_tabs 结果,其 content 不是恰好一个 browser_state 内容块,或者 new_tab 结果没有恰好一个与活动标签页匹配的 tab_openedAPI 根据该内容块渲染这些结果,并需要它具有该确切形态;请参阅标签页管理结果
结果中的 image 超出您的模型的图像大小限制,或者超出一旦请求包含超过 20 张图像(计入较早结果中的截图和 zoom 图像)时适用的更严格的单张图像限制API 不会缩小工具集图像。请在返回截图之前调整其大小(调整截图大小以符合图像限制)。
不支持 browser_toolset_20260801model请参阅兼容性了解支持的模型。

限制

  • 平台可用性: 浏览器使用在 Claude API 和 Google Cloud 上可用。
  • 仅支持整体输入流式传输: 当您进行流式传输时,每个成员的 input 作为一个完整的 input_json_delta 到达(客户端工具集)。
  • 元素引用是尽力而为的: 高度动态的页面(虚拟化列表、canvas 渲染的界面、滚动时重新渲染的页面)可能不会暴露稳定的引用,Claude 在这些情况下会回退到截图和坐标点击。
  • read_consoleread_network 依赖于您的浏览器自动化: 它们仅报告其能够捕获的内容,并且仅从其附加到标签页的那一刻起。
  • 通用智能体限制适用: 延迟、视觉准确性和提示注入风险从计算机使用延续而来(请参阅计算机使用工具的限制),并且其在通过提示优化模型性能管理截图历史遵循实现最佳实践(操作延迟、操作验证和日志记录)下的指导也适用于浏览器执行器。

定价和数据保留

浏览器使用遵循标准的工具使用定价。使用浏览器使用工具时:

工具集定义开销: 声明 browser_toolset_20260801 及其默认成员会为请求增加约 6,600 个输入令牌(在 Claude Fable 5、Claude Mythos 5、Claude Opus 5 和 Claude Opus 4.8 上约为 6,610 个,在 Claude Sonnet 5 上约为 6,670 个),其中涵盖成员工具定义和工具使用系统提示。启用全部四个可选成员会增加约 880 个令牌,而使用 configs 禁用成员则会减少令牌数量。请求的确切令牌数会在响应的 usage 中报告,您也可以使用令牌计数端点提前进行估算。

额外的令牌消耗:

  • 工具结果中返回的屏幕截图和缩放图像,按图像输入计费(请参阅视觉定价
  • 返回给 Claude 的文本工具结果,例如无障碍树、页面文本以及控制台或网络条目

浏览器会话、下载和上传的文件保留在您的环境中;您返回的截图、页面文本和标签页状态是您的 API 请求内容的一部分,遵循标准保留政策,或者如果您有 ZDR 安排则遵循该安排。浏览器使用工具符合 ZDR 资格;请参阅 API 和数据保留了解各功能的保留期限和资格。

后续步骤

当任务超出浏览器范围时,让 Claude 控制完整的桌面;其实现指导也适用于浏览器执行器。

格式化 tool_result 内容块,返回图像和错误,并继续对话。

浏览客户端工具集以及所有其他 Anthropic 提供的工具,包括其版本和参数。

Compatibility

Supported models
  • Fable 5 and 5.1
  • Mythos 5 and 5.1
  • Opus 4.8 and 5
  • Sonnet 5
Supported platforms
  • Claude API
  • Google Cloud

Was this page helpful?