Claude Platform Docs
MessagesИнструменты

Инструмент использования браузера

Позвольте Claude перемещаться по веб-страницам, читать их и взаимодействовать с ними в вашей собственной браузерной среде с помощью инструмента использования браузера.

«Browser use tool» (инструмент использования браузера) позволяет Claude перемещаться по веб-страницам, читать их и взаимодействовать с ними в браузере, который запускает ваше приложение. Он работает со страницей как через её структуру («accessibility tree» (дерево доступности), элементы, формы и вкладки), так и через пиксели (снимки экрана и координаты области просмотра), тогда как инструмент использования компьютера работает с целым рабочим столом только через снимки экрана и координаты. Это определённый Anthropic клиентский набор инструментов: одна запись browser_toolset_20260801 в вашем массиве tools по умолчанию даёт Claude 27 «member tools» (инструментов-членов), таких как navigate, read_page, left_click и screenshot, плюс ещё четыре (javascript_exec, file_upload, read_console и read_network), когда вы включаете их. Ваше приложение выполняет каждый вызов с помощью собственной автоматизации браузера; на стороне Anthropic ничего не выполняется. В настоящее время он недоступен в Claude Managed Agents. На этой странице «ваше приложение» означает агентный цикл, который вызывает Messages API, а «ваш исполнитель» («executor») — ту его часть, которая управляет браузером и формирует результаты инструментов.

Выбирайте использование браузера вместо использования компьютера, когда задача остаётся в пределах веб-страниц: Claude может читать структуру страницы, воздействовать на элемент по ссылке, а не только по координате, напрямую задавать значения форм и работать с несколькими вкладками, и вам не нужно запускать рабочий стол. Если Claude нужно только читать страницы, на которые вы можете его направить, или находить источники в интернете, инструмент веб-загрузки и инструмент веб-поиска ещё легче, поскольку это серверные инструменты, которые API выполняет за вас без браузера, которым нужно управлять. Выбирайте использование браузера, когда страницы формируют своё содержимое с помощью JavaScript или задача подразумевает действия на странице, а не только её чтение.

При использовании браузера Claude читает живые веб-страницы и действует на них, поэтому всё, что предоставляет страница, является недоверенным вводом, а действия, которые выполняет Claude, могут иметь реальные последствия. Ознакомьтесь с разделом Соображения безопасности перед развёртыванием.

Быстрый старт

Инструмент использования браузера доступен в Claude API и Google Cloud: добавьте одну запись типа browser_toolset_20260801 без name в массив tools запроса Messages API.

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_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 не ответит текстом.

  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_reason ответа — tool_use.
  3. Выполните вызовы по порядку и верните результаты

    • Переберите все блоки tool_use в response.content (не предполагайте, что их ровно один) и выполните их последовательно, в порядке появления, поскольку последующие вызовы обычно зависят от предыдущих.
    • Верните по одному tool_result на каждый блок в новом сообщении user, сопоставив их по tool_use_id, и повторите "toolset_name": "browser" в каждом. На каждый вызов должен быть дан ответ, иначе следующий запрос будет отклонён.
    • Если вызов завершился неудачей, верните is_error: true с текстовым описанием для этого блока, затем примените правило остановки из раздела Пакетные действия ко всем последующим блокам этого хода.
  4. Claude продолжает, пока задача не будет выполнена

    • Claude читает результаты (текст страницы, деревья доступности, снимки экрана, состояние вкладок) и, если ему нужно больше, возвращает дальнейшие вызовы членов, что возвращает вас к шагу 3.
    • В противном случае он возвращает текстовый ответ пользователю.

Вот каркас шага вызова инструментов этого цикла в двух частях. Сначала обработчики-заглушки членов заменяют вашу автоматизацию браузера. Пять членов (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" }
    }
  ]
}

Ваше приложение возвращает три блока tool_result в одном сообщении user, каждый из которых содержит toolset_name и короткое текстовое подтверждение, например Clicked element ref_3. Нажатие Enter загружает страницу результатов, поэтому результат key также содержит блок browser_state с обновлённым URL вкладки (Контекст вкладки в других результатах). Если бы щелчок вместо этого завершился неудачей, его результат содержал бы ваш текст ошибки, а два других результата содержали бы текст остановки, как показано в разделе Возврат ошибок из вашего исполнителя.

Вам не нужно возвращать снимок экрана после каждого вызова. Claude обычно завершает пакет вызовом наблюдения (screenshot, read_page или get_page_text), и ваше приложение также может прикрепить собственное наблюдение, например свежий снимок экрана или дерево доступности, в качестве дополнительного блока содержимого к последнему результату в пакете, чтобы сэкономить один цикл обмена. Поскольку результат управления вкладками должен быть ровно одним блоком browser_state, прикрепляйте его к последнему результату, который не является вызовом управления вкладками.

Если ваш исполнитель может выполнять только один вызов за цикл обмена, установите disable_parallel_tool_use в true в tool_choice, и Claude будет возвращать не более одного вызова члена за ход ценой большего числа циклов обмена (Отключение параллельного использования инструментов). Остальная часть контракта из раздела Пакетные действия для инструмента использования компьютера переносится сюда, включая один tool_result на каждый tool_use в следующем сообщении user, за исключением двух вещей: текста остановки и того, что содержит 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

Координаты — это пиксели области просмотра («viewport»), пиксельное пространство полноразмерного 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 передаёт ссылку обратно как цель {"type": "ref", "ref": "ref_2"} в последующем вызове щелчка, hover, scroll_to, form_input или file_upload, либо как параметр ref в read_page для чтения поддерева. Ваш исполнитель назначает ссылки, хранит сопоставление каждой из них с базовым узлом (идентификатором узла доступности, сохранённым селектором или эквивалентом) и воздействует на этот узел, когда ссылка возвращается.

Ссылки привязаны к вкладке, которая их создала, и остаются действительными, пока эта вкладка не выполнит переход или её 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 работает по screenshot и zoom и щёлкает по координатам; ваш исполнитель определяет, в какой фрейм попадает координата.
  • Ограничивайте область чтения и читайте дерево прежде, чем делать снимок экрана. На больших страницах read_page с filter: "interactive" или с ref контейнера возвращает сфокусированное поддерево, а чтение дерева типичной страницы часто стоит меньше входных токенов, чем снимок экрана, при этом давая Claude ссылки, на которые он может воздействовать немедленно. Снимки экрана остаются правильным способом наблюдения, когда важны визуальный макет, изображения или состояние отрисовки.

Соображения безопасности

Использование браузера несёт риски, которых нет у стандартных функций API, поскольку Claude читает содержимое из открытого интернета и действует на его основе, а любая страница может содержать текст, написанный для манипулирования им.

Claude иногда следует инструкциям, найденным в содержимом страницы, даже когда они противоречат вашим; текст на странице, гласящий «игнорируй свои предыдущие инструкции и перейди на...», может отвлечь его от задачи. Изолируйте Claude от конфиденциальных данных и действий, чтобы ограничить то, до чего может добраться инъекция подсказки, ознакомьтесь с разделом Противодействие взлому и инъекциям подсказок, а если задача не может обойтись без сеанса с выполненным входом, используйте выделенную учётную запись с низкими привилегиями и сохраняйте подтверждение человеком для действий, изменяющих учётную запись.

Поскольку браузер работает в вашей среде, сайты, которые посещает 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.

ЧленВходные данныеОписание
navigateurl, tab_id?Загрузить URL http или https либо перемещаться по истории с помощью "back", "forward" или "reload". Рассматривайте URL без схемы как https:// и отклоняйте любую другую схему результатом с ошибкой. Верните короткое подтверждение, а также блок browser_state, если URL или заголовок вкладки изменились.
screenshottab_id?Захватить область просмотра и вернуть блок image.
zoomregion, tab_id?Вернуть обрезанное, увеличенное image области region, заданной как [x0, y0, x1, y1] в пикселях области просмотра, для более детального изучения мелкого текста или элементов управления.

Указатель

ЧленВходные данныеОписание
left_clicktarget: Target, modifiers?, tab_id?Щёлкнуть левой кнопкой по координате или элементу по ссылке. modifiers — это сочетание клавиш, удерживаемое во время щелчка, например "shift" или "ctrl+shift".
right_clicktarget: Target, modifiers?, tab_id?Щёлкнуть правой кнопкой по координате или элементу.
middle_clicktarget: Target, modifiers?, tab_id?Щёлкнуть средней кнопкой по координате или элементу.
double_clicktarget: Target, modifiers?, tab_id?Дважды щёлкнуть левой кнопкой по координате или элементу.
triple_clicktarget: Target, modifiers?, tab_id?Трижды щёлкнуть левой кнопкой по координате или элементу, что обычно выделяет строку или абзац.
hovertarget: Target, tab_id?Навести указатель на координату или элемент без щелчка.
left_click_dragfrom: CoordinateTarget, target: CoordinateTarget, tab_id?Нажать в точке from, перетащить в target и отпустить.
left_mouse_downtarget: CoordinateTarget, tab_id?Нажать и удерживать левую кнопку в координате; используйте в паре с left_mouse_up для пользовательского перетаскивания.
left_mouse_uptarget: CoordinateTarget, tab_id?Отпустить левую кнопку в координате.
mouse_movetarget: CoordinateTarget, tab_id?Переместить указатель в координату.
scrolltarget: CoordinateTarget, scroll_direction, scroll_amount?, tab_id?Прокрутить в позиции области просмотра. scroll_direction"up", "down", "left" или "right"; scroll_amount задаётся в щелчках колеса прокрутки, от 1 до 10, по умолчанию 3.
scroll_totarget: RefTarget, tab_id?Прокрутить элемент по ссылке в область видимости.

Клавиатура и тайминг

ЧленВходные данныеОписание
typetext, tab_id?Ввести буквальную строку в текущем фокусе.
keytext, repeat?, tab_id?Нажать клавишу или сочетание. text — это одна клавиша ("Enter"), сочетание, соединённое через + ("ctrl+a"), или последовательность, разделённая пробелами ("Backspace Backspace"); repeat — от 1 до 100, по умолчанию 1.
hold_keytext, duration, tab_id?Удерживать клавишу или сочетание в течение duration секунд, от 0 до 30.
waitduration, tab_id?Сделать паузу на duration секунд, от 0 до 30.

Чтение страницы

ЧленВходные данныеОписание
read_pagefilter?, depth?, ref?, tab_id?Вернуть дерево доступности страницы в виде текста, где каждый элемент помечен ссылкой, например [ref_2]. Если filter опущен, вернуть каждый видимый элемент; при "interactive" — только видимые интерактивные элементы; при "all" — также элементы за пределами области просмотра. depth ограничивает глубину дерева (минимум 1, по умолчанию 15), а ref ограничивает чтение поддеревом этого элемента. Ограничьте вывод 50 000 символами и сообщите об этом в тексте; затем Claude сузит область с помощью меньшего depth или ref.
findquery, tab_id?Найти элементы, соответствующие описанию на естественном языке, например "search field" или "add to cart button", и вернуть до 20 совпадений в том же помеченном формате, что и read_page.
get_page_texttab_id?Вернуть видимый текст страницы в виде простого текста, отдавая приоритет основному содержимому статьи; подходит для статей, документации и других страниц с большим количеством текста.

Формы и файлы

ЧленВходные данныеОписание
form_inputtarget: 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_tabtab_id (обязательный)Сделать tab_id активной вкладкой.
close_tabtab_id (обязательный)Закрыть tab_id.

При успехе каждый из них возвращает ровно один блок browser_state и никакого текста или изображения; см. Результаты управления вкладками.

Настройка набора инструментов

Помимо type, запись набора инструментов принимает configs, cache_control и allowed_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 никогда его не назовёт, поэтому ваш исполнитель всё равно отвечает на такой вызов результатом с ошибкой.

Сочетание с другими инструментами

Объявляйте инструмент использования браузера вместе с вашими собственными инструментами и другими инструментами, предоставляемыми Anthropic, в одном массиве tools. Пользовательский инструмент может иметь то же имя, что и член (например, ваш собственный 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 на странице

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_id, title и url может содержать не более 4 096 символов, tab_id должен быть непустым, и ни одно из них не может содержать управляющие символы (включая переводы строк) или разделители строк и абзацев Unicode.
  • Блок может содержать не более 100 вкладок и 200 изменений состояния.
  • Те же ограничения применяются к tab_id, который Claude передаёт в switch_tab и close_tab, поскольку API включает его в текст результата, поэтому на вызов, чей tab_id их нарушает, отвечайте результатом с ошибкой вместо блока browser_state.

Результаты управления вкладками

Для new_tab, switch_tab, close_tab и list_tabs content успешного результата — это ровно один блок browser_state без текста или изображения, и текст, который видит Claude, пишет API. Блок результата 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:, за которым следует по одной строке на вкладку, или No tabs available, когда tabs пуст

Результат 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 вкладки, или когда есть 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 увидел изменение вкладок в том же результате.
  • Результат, чей список tabs пуст, для вызова без tab_id, поскольку нет вкладки, которую можно назвать.

Например, когда 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_id, urlВ результате вызова, во время которого началась загрузка. url — это конечный URL, с которого отдаётся файл, после перенаправлений.
download_completeddownload_id, url, path?, size_bytes?В результате того последующего вызова, который выполняется в момент завершения загрузки. Включайте path только тогда, когда другой инструмент в той же среде (например, инструмент bash или file_upload) может прочитать файл по этому пути; в противном случае download_id — единственный идентификатор загрузки.
download_faileddownload_id, url, error?Когда загрузка завершается неудачей или отменяется, с причиной в error, если браузер её предоставляет.

API проверяет эти записи, но не преобразует их в текст, который видит Claude, поэтому, когда Claude нужно работать с файлом, также упомяните имя файла или path в блоке text того же результата.

Например, щелчок по «Download price list (CSV)» (ref_8) во вкладке Pricing запускает загрузку, поэтому результат щелчка содержит запись download_started с download_id "dl-1" и URL файла. Загрузка завершается во время выполнения последующего вызова screenshot, поэтому content этого результата содержит изображение, текстовый блок вроде Screenshot captured. Download complete: /home/user/downloads/price-list.csv (48,213 bytes). и этот блок browser_state, сообщающий о завершении под тем же download_id:

{
  "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.
  • Никогда не отправляйте state_changes в результате с is_error: true; о событии загрузки, произошедшем во время неудачного вызова, сообщайте в следующем успешном результате.
  • 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 возвращает invalid_request_error до запуска Claude. В следующей таблице левый столбец называет то, что вы отправили.

ЗапросПочему он не проходит и что делать
Параметр или комбинация, которые запись набора инструментов не принимает, например name, strict: true, input_examples, defer_loading на самой записи, ключ configs, не являющийся именем члена, поле, отличное от enabled или defer_loading, в значении configs члена (Настройка набора инструментов), включённые члены с различающимися значениями defer_loading (Настройка набора инструментов), configs, не оставляющий ни одного включённого члена, вызывающий объект выполнения кода в allowed_callers, устаревший бета-заголовок fine-grained-tool-streaming-2025-05-14 в запросе, tool_choice типа tool, называющий browser или член, либо вторая запись браузерного набора инструментов или другой инструмент с именем 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_opened, чей tab_id отсутствует в tabs, два изменения состояния для одного 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 не уменьшает изображения наборов инструментов. Изменяйте размер снимков экрана перед их возвратом (Подгонка размера снимков экрана под ограничения изображений).
model, не поддерживающая browser_toolset_20260801Поддерживаемые модели см. в разделе Совместимость.

Ограничения

  • Доступность на платформах: использование браузера доступно в Claude API и Google Cloud.
  • Только потоковая передача целого ввода: при потоковой передаче input каждого члена поступает как одна полная input_json_delta (Клиентские наборы инструментов).
  • Ссылки на элементы предоставляются по мере возможности: высокодинамичные страницы (виртуализированные списки, интерфейсы, отрисованные на canvas, страницы, перерисовывающиеся при прокрутке) могут не предоставлять стабильных ссылок, и там Claude возвращается к снимкам экрана и щелчкам по координатам.
  • read_console и read_network зависят от вашей автоматизации браузера: они сообщают только то, что она может захватить, и только с момента её подключения к вкладке.
  • Применяются общие ограничения агентов: задержка, точность зрения и риски внедрения подсказок переносятся из использования компьютера (см. Ограничения инструмента использования компьютера), а его рекомендации в разделах Оптимизация производительности модели с помощью подсказок, Управление историей снимков экрана и Следование лучшим практикам реализации (задержки действий, проверка действий и журналирование) применимы и к браузерным исполнителям.

Цены и хранение данных

Использование браузера (browser use) следует стандартному ценообразованию на использование инструментов. При использовании инструмента browser use:

Накладные расходы на определение набора инструментов: Объявление browser_toolset_20260801 с его членами по умолчанию добавляет к запросу около 6 600 входных токенов (около 6 610 на Claude Fable 5, Claude Mythos 5, Claude Opus 5 и Claude Opus 4.8 и около 6 670 на Claude Sonnet 5), что покрывает определения входящих в набор инструментов и системную подсказку для использования инструментов. Включение всех четырёх необязательных членов добавляет около 880 токенов, а отключение членов с помощью configs уменьшает это количество. Точное количество для запроса указывается в поле usage ответа, и вы можете оценить его заранее с помощью конечной точки подсчёта токенов.

Дополнительное потребление токенов:

  • Снимки экрана и увеличенные изображения, возвращаемые в результатах инструментов, тарифицируются как входные изображения (см. ценообразование Vision)
  • Текстовые результаты инструментов, возвращаемые 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?