"browser use tool"(浏览器使用工具)让 Claude 能够在您的应用程序所运行的浏览器中导航、读取网页并与网页交互。它既通过页面的结构("accessibility tree"(无障碍树)、元素、表单和标签页)也通过像素(屏幕截图和视口坐标)来处理页面,而计算机使用工具则仅通过屏幕截图和坐标来处理整个桌面。它是一个由 Anthropic 定义的客户端工具集:在您的 tools 数组中加入一个 browser_toolset_20260801 条目,默认即可为 Claude 提供 27 个成员工具,例如 navigate、read_page、left_click 和 screenshot,当您启用它们时还会再增加四个(javascript_exec、file_upload、read_console 和 read_network)。您的应用程序针对其自身的浏览器自动化运行每一次调用;没有任何内容在 Anthropic 一侧运行。它目前在 Claude Managed Agents 中不可用。本页用"您的应用程序"指代调用 Messages API 的"agent loop"(智能体循环),用"您的执行器"指代其中驱动浏览器并生成工具结果的部分。
当任务始终停留在网页内部时,请选择浏览器使用而非计算机使用:Claude 可以读取页面的结构,除了按坐标之外还可以按引用对元素执行操作,可以直接设置表单值,并且可以跨标签页工作,而您无需运行桌面。如果 Claude 只需要读取您可以指向的页面,或者在网络上查找来源,那么网页抓取工具和网页搜索工具更加轻量,因为它们是由 API 为您运行的服务器工具,无需操作浏览器。当页面使用 JavaScript 构建其内容,或者任务意味着要对页面执行操作而不仅仅是读取时,请改为选择浏览器使用。
使用浏览器使用时,Claude 会读取实时网页并对其执行操作,因此页面提供的一切都是不受信任的输入,而 Claude 采取的操作可能产生真实的影响。部署之前请参阅安全注意事项。
浏览器使用工具在 Claude API 上可用,无需 beta 标头:在 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":
{
"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_name。navigate 的结果在一个 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 以文本作答。
为 Claude 提供浏览器使用工具和用户提示
browser_toolset_20260801 条目(以及可选的其他工具)添加到您的 API 请求中。Claude 以成员工具调用作出响应
tool_use 块;一个轮次中的多个块构成一个批量操作,例如先 left_click,再 type,再 key。name 是成员名称,每个块都携带 "toolset_name": "browser",而 input 仅包含该成员的参数,没有 action 字段。响应的 stop_reason 为 tool_use。按顺序运行调用并返回结果
response.content 中的每个 tool_use 块(不要假设恰好只有一个),并按它们出现的顺序依次运行,因为后面的调用通常依赖于前面的调用。user 消息中为每个块返回一个 tool_result,通过 tool_use_id 匹配,并在每个结果上回显 "toolset_name": "browser"。每个调用都必须得到回应,否则下一个请求会被拒绝。is_error: true 及一段文本描述,然后对该轮次中之后的每个块应用批量操作中的中止规则。Claude 继续执行直到任务完成
下面是该循环中工具调用步骤的骨架,分为两部分。首先,存根成员处理程序代替您的浏览器自动化。五个成员(navigate、read_page、left_click、type 和 screenshot)返回将成为结果内容的文本(对于 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_name、name)这一对值而非仅根据 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 通常以一个观察调用(screenshot、read_page 或 get_page_text)结束一个批次,您的应用程序也可以将自己的观察结果(例如一张新的屏幕截图或无障碍树)作为额外的内容块附加到批次中最后一个结果上,以节省一次往返。由于标签页管理结果必须恰好是一个 browser_state 块,请将其附加到最后一个非标签页管理调用的结果上。
如果您的执行器每次往返只能运行一个调用,请在 tool_choice 中将 disable_parallel_tool_use 设置为 true,Claude 每轮最多返回一个成员调用,代价是更多的往返次数(禁用并行工具使用)。计算机使用工具的批量操作下的其余契约同样适用,包括在下一条 user 消息中为每个 tool_use 提供一个 tool_result,但有两点例外:中止文本以及成功结果的 content 所包含的内容。结果内容改为遵循本页的成员工具:new_tab、switch_tab、close_tab 或 list_tabs 的结果恰好是一个 browser_state 块,不含文本或图像(标签页管理结果),而任何其他成员的结果可以在其文本或图像之外添加一个 browser_state 块(其他结果上的标签页上下文)。批次内缓存断点在何处生效,在计算机使用工具的工具参数的 cache_control 行中有描述。
对某个位置执行操作的成员工具接受一个 target 对象,它要么是一个视口像素坐标,要么是对 read_page 或 find 返回的元素的引用。成员工具表格中用 Target 表示接受任一形状的参数。
| 形状 | target.type | 字段 | 接受者 |
|---|---|---|---|
CoordinateTarget | "coordinate" | x、y(整数,视口像素) | left_click、right_click、middle_click、double_click、triple_click、hover、left_click_drag(from 和 target)、left_mouse_down、left_mouse_up、mouse_move、scroll |
RefTarget | "ref" | ref(元素引用,例如 "ref_2") | left_click、right_click、middle_click、double_click、triple_click、hover、scroll_to、form_input、file_upload |
坐标是视口像素,即全视口 screenshot 的像素空间,原点位于渲染页面的左上角;没有周围的桌面或窗口边框。工具集不声明显示尺寸,Claude 从您返回的屏幕截图推断视口大小,因此请保持它们尺寸一致。zoom 不会改变坐标系,因此它的 region 以及 Claude 在看到放大图像后发出的任何坐标仍然是全视口像素。
屏幕截图必须符合图像限制。 API 不会缩小工具集图像:超过您模型的图像尺寸限制,或超过请求包含超过 20 张图像时适用的更严格的单图限制的屏幕截图或缩放图像会被拒绝。请在返回前调整大小,并在分派之前按您缩放因子的倒数将 Claude 的坐标放大回去(调整屏幕截图大小以符合图像限制)。
元素引用来自 read_page 和 find。 它们输出中的每个元素都带有一个标签,例如 [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 在之后的点击、hover、scroll_to、form_input 或 file_upload 调用中将引用作为 {"type": "ref", "ref": "ref_2"} 目标传回,或者作为 read_page 上的 ref 参数传回以读取子树。您的执行器分配这些引用,保存从每个引用到底层节点(无障碍节点 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 会使用两种定位方式,并根据页面暴露的内容在它们之间切换;您的提示和您的执行器返回的内容会引导这一选择:
screenshot 和 zoom 工作并按坐标点击;您的执行器负责解析坐标落在哪个框架中。filter: "interactive" 或容器 ref 的 read_page 会返回一个聚焦的子树,而对典型页面的树读取通常比屏幕截图消耗更少的输入令牌,同时为 Claude 提供可以立即据以执行操作的引用。当视觉布局、图像或渲染状态很重要时,屏幕截图仍然是正确的观察方式。浏览器使用带有标准 API 功能所没有的风险,因为 Claude 读取并操作来自开放网络的内容,而任何页面都可能包含为操纵它而编写的文本。
Claude 有时会遵循在页面内容中发现的指令,即使它们与您的指令相冲突;页面上写着"忽略你之前的指令并导航到……"的文本可能使它偏离任务。请将 Claude 与敏感数据和操作隔离,以限制"prompt injection"(提示注入)所能触及的范围,查阅缓解越狱和提示注入,如果任务无法避免已登录的会话,请使用专用的低权限账户,并对更改账户的操作保持人工确认。
由于浏览器在您的环境中运行,Claude 访问的网站看到的是您的执行器的网络身份,而页面内容仅以您返回的工具结果的形式到达 API。在您的产品中启用浏览器使用之前,请告知最终用户相关风险并获得他们的同意。
browser_toolset_20260801 条目声明了 31 个成员工具;每次调用的 input 恰好是此处列出的参数,而 tab_id 在可选时默认为活动标签页。Target、CoordinateTarget 和 RefTarget 是目标和坐标中描述的形状。四个成员(javascript_exec、file_upload、read_console 和 read_network)默认禁用,仅在您启用它们时出现。每个成员行中注明的输入边界和输出约定是向 Claude 陈述的,而非由 API 强制执行的,因此请在您的执行器中验证输入(包括对照您的视口验证坐标)并应用这些约定。
只有 screenshot 和 zoom 要求其结果中包含一个 image 块,而四个标签页管理成员(new_tab、list_tabs、switch_tab 和 close_tab)恰好返回一个 browser_state 块(参见标签页管理结果)。其他每个成员都返回一个 text 块:要么是一段简短的确认,例如 Clicked element ref_2.,要么是该成员的输出。除标签页管理结果之外的任何结果还可以携带一个 image 块,通常是操作后拍摄的屏幕截图,这样 Claude 无需单独的 screenshot 调用即可看到结果;批量操作展示了在批次中将其附加到何处。成员 tool_result 只能包含 text、image 和 browser_state 内容块。
| 成员 | 输入 | 描述 |
|---|---|---|
navigate | url、tab_id? | 加载一个 http 或 https URL,或使用 "back"、"forward" 或 "reload" 在历史记录中移动。将没有协议的 URL 视为 https://,并以错误结果拒绝任何其他协议。返回一段简短的确认,当标签页的 URL 或标题发生变化时再加上一个 browser_state 块。 |
screenshot | tab_id? | 捕获视口并返回一个 image 块。 |
zoom | region、tab_id? | 返回 region 的裁剪并放大的 image,region 以视口像素的 [x0, y0, x1, y1] 给出,用于更仔细地检查小文本或控件。 |
| 成员 | 输入 | 描述 |
|---|---|---|
left_click | target: Target、modifiers?、tab_id? | 左键点击一个坐标或被引用的元素。modifiers 是点击期间按住的组合键,例如 "shift" 或 "ctrl+shift"。 |
right_click | target: Target、modifiers?、tab_id? | 右键点击一个坐标或元素。 |
middle_click | target: Target、modifiers?、tab_id? | 中键点击一个坐标或元素。 |
double_click | target: Target、modifiers?、tab_id? | 左键双击一个坐标或元素。 |
triple_click | target: Target、modifiers?、tab_id? | 左键三击一个坐标或元素,通常会选中一行或一个段落。 |
hover | target: Target、tab_id? | 将指针移到一个坐标或元素上方而不点击。 |
left_click_drag | from: CoordinateTarget、target: CoordinateTarget、tab_id? | 在 from 处按下,拖动到 target,然后释放。 |
left_mouse_down | target: CoordinateTarget、tab_id? | 在一个坐标处按下并按住左键;与 left_mouse_up 配合实现自定义拖动。 |
left_mouse_up | target: CoordinateTarget、tab_id? | 在一个坐标处释放左键。 |
mouse_move | target: CoordinateTarget、tab_id? | 将指针移动到一个坐标。 |
scroll | target: CoordinateTarget、scroll_direction、scroll_amount?、tab_id? | 在一个视口位置滚动。scroll_direction 为 "up"、"down"、"left" 或 "right";scroll_amount 以滚轮刻度为单位,1 到 10,默认为 3。 |
scroll_to | target: RefTarget、tab_id? | 将被引用的元素滚动到视图中。 |
| 成员 | 输入 | 描述 |
|---|---|---|
type | text、tab_id? | 在当前焦点处输入一个字面字符串。 |
key | text、repeat?、tab_id? | 按下一个键或组合键。text 是单个键("Enter")、用 + 连接的组合键("ctrl+a")或以空格分隔的序列("Backspace Backspace");repeat 为 1 到 100,默认为 1。 |
hold_key | text、duration、tab_id? | 按住一个键或组合键 duration 秒,0 到 30。 |
wait | duration、tab_id? | 暂停 duration 秒,0 到 30。 |
| 成员 | 输入 | 描述 |
|---|---|---|
read_page | filter?、depth?、ref?、tab_id? | 以文本形式返回页面的无障碍树,每个元素都带有一个引用标签,例如 [ref_2]。省略 filter 时,返回每个可见元素;为 "interactive" 时,仅返回可见的交互元素;为 "all" 时,还包括视口之外的元素。depth 限制树的深度(最小为 1,默认为 15),ref 将读取范围限定为该元素的子树。将输出限制在 50,000 个字符以内并在文本中说明;Claude 随后会用更小的 depth 或一个 ref 来缩小范围。 |
find | query、tab_id? | 搜索与自然语言描述(例如 "search field" 或 "add to cart button")匹配的元素,并以与 read_page 相同的带标签格式返回最多 20 个匹配项。 |
get_page_text | tab_id? | 以纯文本形式返回页面的可见文本,优先返回主要文章内容;适用于文章、文档和其他以文本为主的页面。 |
| 成员 | 输入 | 描述 |
|---|---|---|
form_input | target: RefTarget、value、tab_id? | 直接设置表单元素的值。value 是 string、number 或 boolean;对复选框使用 boolean,对下拉选择框使用选项的值或可见文本。 |
file_upload(默认禁用) | target: RefTarget、paths?、document_ids?、tab_id? | 从执行器文件系统上的 paths、您的应用程序已暂存的 document_ids 或两者设置文件输入元素上的文件;至少需要其中之一。参见上传文件。 |
| 成员 | 输入 | 描述 |
|---|---|---|
read_console(默认禁用) | tab_id? | 返回该标签页自上次读取以来累积的控制台条目(日志、警告和错误行),每个条目一行。参见读取控制台和网络活动。 |
read_network(默认禁用) | tab_id? | 返回该标签页自上次读取以来的网络请求(方法、URL、状态、MIME 类型、计时),每个条目一行。 |
javascript_exec(默认禁用) | text、tab_id? | 在页面上下文中将 text 作为 JavaScript 运行,并以文本形式返回最后一个表达式的值。参见启用可选成员。 |
| 成员 | 输入 | 描述 |
|---|---|---|
new_tab | (无) | 打开一个标签页并使其成为活动标签页。 |
list_tabs | (无) | 报告标签页清单。 |
switch_tab | tab_id(必需) | 使 tab_id 成为活动标签页。 |
close_tab | tab_id(必需) | 关闭 tab_id。 |
成功时,这些成员中的每一个都恰好返回一个 browser_state 块,不含文本或图像;参见标签页管理结果。
除 type 之外,工具集条目还接受 configs、cache_control 和 allowed_callers;这些字段与计算机使用工具集共享的规则列在客户端工具集下,本节介绍浏览器特有的默认值。configs 是一个以成员名称为键的对象,每个成员的值接受两个字段:
| 字段 | 默认值 | 含义 |
|---|---|---|
enabled | true,但四个可选成员为 false | 该成员是否提供给 Claude。 |
defer_loading | false | 工具集的定义是否为工具搜索而延迟加载。必须在每个已启用的成员上解析为相同的值。在四个可选成员保持禁用的情况下,延迟加载工具集意味着在其他 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 对同名成员(例如 screenshot 或 key)的调用通过 toolset_name 加以区分。
四个成员工具默认禁用:javascript_exec 和 file_upload 是因为它们扩大了被操纵的页面可能让 Claude 做的事情的范围,而 read_console 和 read_network 是因为并非每个浏览器自动化栈都能提供这些日志,并且它们扩大了到达 Claude 的页面控制内容的范围。仅当您的执行器实现了某个成员且任务需要它时,才使用 configs 启用它(例如 "configs": {"file_upload": {"enabled": true}})。
file_upload 直接设置 <input type="file"> 元素上的文件,这比驱动原生文件选择器更可靠。它的 target 只能是引用,因为该调用需要元素的身份,并且它接受 paths、document_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_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 的结果上发送。您通过省略该块来表达"没有标签页状态需要报告"。tabs 渲染为供 Claude 阅读的文本;state_changes 中的下载条目会被验证但不会被渲染。由您分配 tab_id 值。 任何稳定的字符串都可以,例如您的自动化库的页面标识符或您自己的计数器,只要您不在某个标签页仍在先前结果中被列为打开状态时重复使用该 tab_id。API 对该块强制执行以下限制:
tab_id、title 和 url 最多 4,096 个字符,tab_id 必须非空,且都不得包含控制字符(包括换行符)或 Unicode 行分隔符或段落分隔符。switch_tab 和 close_tab 的 tab_id,因为 API 会将其渲染到结果文本中,因此对于 tab_id 违反这些限制的调用,请以错误结果而非 browser_state 块来回应。对于 new_tab、switch_tab、close_tab 和 list_tabs,成功结果的 content 恰好是一个 browser_state 块,不含文本或图像,由 API 写入 Claude 看到的文本。new_tab 结果的块还必须恰好带有一个 tab_opened 状态变更,其 tab_id 与标记为 active: true 的条目匹配。
| 成员 | Claude 看到的文本 |
|---|---|
switch_tab | Switched to tab {tab_id},取自调用的 input.tab_id |
close_tab | Closed tab {tab_id},取自调用的 input.tab_id |
new_tab | Created new tab with tab_id: {tab_id}, URL: {url}. It is now the current tab.,取自标记为 active: true 的条目 |
list_tabs | Available 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_started | download_id、url | 在下载开始期间所在调用的结果上。url 是重定向之后文件实际提供的最终 URL。 |
download_completed | download_id、url、path?、size_bytes? | 在下载完成时正在运行的任何后续调用的结果上。仅当同一环境中的另一个工具(例如 bash 工具或 file_upload)可以在该位置读取文件时才包含 path;否则 download_id 是该下载的唯一标识符。 |
download_failed | download_id、url、error? | 当下载失败或被取消时,如果浏览器提供了原因,则在 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_id、url、path 和 error 各自最多 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_use 和 tool_result 块。当其中一个格式错误时,API 会在 Claude 运行之前返回 invalid_request_error。在下表中,左列指明您发送的内容。
| 请求 | 失败原因及处理方法 |
|---|---|
工具集条目不接受的选项或组合,例如条目本身上的 name、strict: true、input_examples、defer_loading,不是成员名称的 configs 键,成员的 configs 值中除 enabled 或 defer_loading 之外的字段(配置工具集),defer_loading 值不同的已启用成员(配置工具集),未留下任何已启用成员的 configs,allowed_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 | 回应每个成员调用,包括失败后您未运行的那些调用。 |
成员结果中除 text、image 或 browser_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_tab、switch_tab、close_tab 或 list_tabs 结果,其 content 不是恰好一个 browser_state 块,或者 new_tab 结果没有恰好一个与活动标签页匹配的 tab_opened | API 根据该块渲染这些结果,并需要它具有该确切形状;请参阅标签页管理结果。 |
结果中的 image 超出您模型的图像大小限制,或超出一旦请求包含超过 20 张图像时适用的更严格的每张图像限制(计入较早结果中的截图和 zoom 图像) | API 不会缩小工具集图像。在返回截图之前调整其大小(调整截图大小以符合图像限制)。 |
不支持 browser_toolset_20260801 的 model | 请参阅兼容性了解支持的模型。 |
input 作为一个完整的 input_json_delta 到达(客户端工具集)。read_console 和 read_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 中报告,您也可以通过令牌计数端点提前进行估算。
额外的令牌消耗:
浏览器会话、下载和上传的文件保留在您的环境中;您返回的截图、页面文本和标签页状态是您 API 请求内容的一部分,遵循标准保留策略,或者如果您有 ZDR 安排则遵循该安排。浏览器使用工具符合 ZDR 资格;请参阅 API 和数据保留了解各功能的保留期限和资格。
当任务超出浏览器范围时,让 Claude 控制完整的桌面;其实现指导也适用于浏览器执行器。
格式化 tool_result 块,返回图像和错误,并继续对话。
浏览客户端工具集和所有其他 Anthropic 提供的工具,及其版本和参数。
| Supported models |
|
|---|---|
| Supported platforms |
|
Was this page helpful?