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

Серверные инструменты

Работа с инструментами, выполняемыми Anthropic: блоки server_tool_use, продолжение после pause_turn, ходы со смешанными серверными и клиентскими инструментами и фильтрация доменов.

Инструменты, выполняемые на сервере, имеют общую механику: блок server_tool_use, продолжение после pause_turn, ходы, в которых сочетаются серверные и клиентские инструменты, соответствие требованиям «Zero Data Retention» (нулевое хранение данных), или ZDR, и фильтрация доменов. Сведения об отдельных инструментах см. в справочнике по инструментам.

Блок server_tool_use

Блок server_tool_use появляется в ответе Claude, когда выполняется серверный инструмент. Его поле id использует префикс srvtoolu_, чтобы отличать его от вызовов клиентских инструментов:

{
  "type": "server_tool_use",
  "id": "srvtoolu_01A2B3C4D5E6F7G8H9",
  "name": "web_search",
  "input": { "query": "latest quantum computing breakthroughs" }
}

API выполняет инструмент внутренне. Вы видите вызов и его результат в ответе, но не занимаетесь выполнением. В отличие от клиентских блоков tool_use, вам не нужно отвечать блоком tool_result. Блок результата инструмента (например, web_search_tool_result для веб-поиска) следует за блоком server_tool_use в том же ходе ассистента и связан с ним по tool_use_id. Если Claude одновременно вызывает один из ваших клиентских инструментов, блок server_tool_use появляется без своего результата, а ответ завершается с stop_reason: "tool_use". API запускает инструмент, когда вы возвращаете клиентские блоки tool_result в следующем запросе.

Серверный цикл и pause_turn

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

Вот как обрабатывать причину остановки pause_turn:

client = anthropic.Anthropic()

# Первоначальный запрос с веб-поиском
response = client.messages.create(
    model="claude-opus-5",
    max_tokens=1024,
    messages=[
        {
            "role": "user",
            "content": "Search for comprehensive information about quantum computing breakthroughs in 2025",
        }
    ],
    tools=[{"type": "web_search_20250305", "name": "web_search", "max_uses": 10}],
)

# Проверяем, имеет ли ответ stop_reason со значением pause_turn
if response.stop_reason == "pause_turn":
    # Продолжаем разговор с приостановленным содержимым
    messages = [
        {
            "role": "user",
            "content": "Search for comprehensive information about quantum computing breakthroughs in 2025",
        },
        {"role": "assistant", "content": response.content},
    ]

    # Отправляем запрос на продолжение
    continuation = client.messages.create(
        model="claude-opus-5",
        max_tokens=1024,
        messages=messages,
        tools=[{"type": "web_search_20250305", "name": "web_search", "max_uses": 10}],
    )

    print(continuation)
else:
    print(response)

При обработке pause_turn:

  • Продолжайте разговор: передайте приостановленный ответ как есть в последующем запросе, чтобы Claude продолжил свой ход.
  • Сохраняйте состояние инструментов: включите те же инструменты в запрос на продолжение. Приостановленный ход может завершиться блоком server_tool_use, инструмент которого ещё не выполнялся, и API вернёт ошибку валидации, если этот инструмент отсутствует в запросе на продолжение.
  • Повторяйте по мере необходимости: продолженный ход может снова приостановиться. Проверяйте stop_reason в каждом ответе и продолжайте, пока не получите другую причину остановки, ограничивая число продолжений так же, как в любом цикле повторных попыток.

Другие значения stop_reason и общие шаблоны обработки см. в разделе Причины остановки и резервные варианты.

Сочетание серверных и клиентских инструментов в одном ходе

Claude может вызвать серверный и клиентский инструмент в одной группе параллельных вызовов инструментов, например web_fetch вместе с пользовательским инструментом. Клиентский инструмент — это любой инструмент, который выполняет ваш код и который порождает блок tool_use, будь то пользовательский инструмент или клиентский инструмент со схемой Anthropic, такой как инструмент Bash. Когда это происходит, API не запускает серверный инструмент. Он немедленно возвращает ответ, чтобы вы могли сначала выполнить клиентский инструмент:

  • stop_reason равен "tool_use", а не "pause_turn".
  • content содержит блок server_tool_use и клиентский блок tool_use, но не содержит блока результата для серверного инструмента: этот вызов не завершён.
  • Других маркеров нет. Определяйте это состояние по наличию блока server_tool_use, для id которого в ответе нет соответствующего блока результата. Блок mcp_tool_use от коннектора MCP ведёт себя так же. Вызовы серверных инструментов, у которых уже есть блок результата в том же ответе, завершены и ничего от вас не требуют.
{
  "stop_reason": "tool_use",
  "content": [
    {
      "type": "text",
      "text": "I'll fetch the article and check your system at the same time."
    },
    {
      "type": "server_tool_use",
      "id": "srvtoolu_01HxbWnMRmbWyMfUtJKC45rA",
      "name": "web_fetch",
      "input": { "url": "https://example.com/article" }
    },
    {
      "type": "tool_use",
      "id": "toolu_01PjgRJLbXrXEMZwDNYLnBqk",
      "name": "run_command",
      "input": { "command": "uname -a" }
    }
  ]
}

Чтобы продолжить ход, выполните клиентские инструменты и отправьте сообщение пользователя, содержимое которого состоит только из блоков tool_result — по одному на каждый блок tool_use в этом ответе. Сохраните тот же массив tools: запрос на возобновление, в котором больше не определён ожидающий серверный инструмент, завершается ошибкой 400, сообщение которой заканчивается на but no `web_fetch` tool was provided.

{
  "role": "user",
  "content": [
    {
      "type": "tool_result",
      "tool_use_id": "toolu_01PjgRJLbXrXEMZwDNYLnBqk",
      "content": "Linux demo-host 6.8.0-52-generic x86_64 GNU/Linux"
    }
  ]
}

API присоединяет ваши результаты к всё ещё открытому ходу ассистента, запускает отложенный серверный инструмент (для приостановленного выполнения кода — возобновляет его), а затем позволяет Claude продолжить. Для серверного инструмента, вызванного Claude напрямую, следующий ответ начинается с блока результата, отвечающего на id блока server_tool_use из предыдущего ответа, за которым следуют вновь сгенерированное содержимое и новый stop_reason:

{
  "stop_reason": "end_turn",
  "content": [
    {
      "type": "web_fetch_tool_result",
      "tool_use_id": "srvtoolu_01HxbWnMRmbWyMfUtJKC45rA",
      "content": {
        "type": "web_fetch_result",
        "url": "https://example.com/article",
        "content": {
          "type": "document",
          "source": {
            "type": "text",
            "media_type": "text/plain",
            "data": "Full text content of the article..."
          }
        }
      }
    },
    {
      "type": "text",
      "text": "The article argues that... and your machine is running Linux..."
    }
  ]
}

Блок server_tool_use и его блок результата связываются по tool_use_id, а не по позиции: в этом сценарии они приходят в двух разных ответах, и блок server_tool_use не повторяется во втором. В последующих запросах сохраняйте весь обмен в массиве messages по порядку: первый ответ как сообщение assistant, сообщение пользователя с tool_result, а затем следующий ответ как ещё одно сообщение assistant — так же, как вы накапливаете любой другой обмен с использованием инструментов.

Чем это отличается от pause_turn: ответ pause_turn также может завершаться блоком server_tool_use, который ещё не выполнялся, но он никогда не оставляет клиентский блок tool_use, ожидающий вас, поэтому вы продолжаете его, повторно отправляя содержимое ассистента как есть. Ответ, который оставляет клиентский блок tool_use, ожидающий вас, никогда не имеет stop_reason со значением pause_turn: когда Claude останавливается, чтобы вызвать ваши инструменты, stop_reason равен tool_use, и вы продолжаете его, отправляя клиентские блоки tool_result, а не повторно отправляя ответ. В обоих случаях API запускает ожидающий серверный инструмент в начале следующего запроса.

В следующем примере веб-загрузка включена вместе с пользовательским инструментом run_command, и обрабатывается смешанный ответ:

client = anthropic.Anthropic()

tools = [
    {"type": "web_fetch_20250910", "name": "web_fetch", "max_uses": 5},
    {
        "name": "run_command",
        "description": "Run a shell command on this computer and return its output.",
        "input_schema": {
            "type": "object",
            "properties": {
                "command": {"type": "string", "description": "The command to run"}
            },
            "required": ["command"],
        },
    },
]
messages = [
    {
        "role": "user",
        "content": "Summarize https://example.com/article and run uname -a to tell me what system this is on.",
    }
]

response = client.messages.create(
    model="claude-opus-4-8", max_tokens=1024, tools=tools, messages=messages
)

tool_results = [
    {
        "type": "tool_result",
        "tool_use_id": block.id,
        # Запустите здесь свой инструмент. В этом примере возвращается фиксированная строка.
        "content": "Linux demo-host 6.8.0-52-generic x86_64 GNU/Linux",
    }
    for block in response.content
    if block.type == "tool_use"
]

if response.stop_reason == "tool_use" and tool_results:
    # Блок server_tool_use без блока результата в этом ответе не завершён; его результат придёт в следующем ответе.
    # Отправьте обратно только клиентские блоки tool_result с теми же инструментами.
    continuation = client.messages.create(
        model="claude-opus-4-8",
        max_tokens=1024,
        tools=tools,
        messages=[
            *messages,
            {"role": "assistant", "content": response.content},
            {"role": "user", "content": tool_results},
        ],
    )
    # Если web_fetch был отложен, он выполняется в этом запросе, и его
    # web_fetch_tool_result будет первым блоком в continuation.content.
    print(continuation)
else:
    print(response)

Этот код также корректен, когда Claude не смешивает два вида вызовов. Ход, содержащий только клиентские блоки tool_use, проходит по тому же пути продолжения, а ход, содержащий только вызовы серверных инструментов, не требует от вас клиентских блоков tool_result: его блоки результатов обычно уже присутствуют, а ход, вернувшийся приостановленным, например ответ pause_turn, вместо этого повторно отправляется как есть.

ZDR и allowed_callers

Базовые версии веб-поиска (web_search_20250305) и веб-загрузки (web_fetch_20250910) соответствуют требованиям Zero Data Retention (ZDR).

Версии _20260209 и более поздние с динамической фильтрацией по умолчанию не соответствуют требованиям ZDR, поскольку динамическая фильтрация внутренне опирается на выполнение кода.

Чтобы использовать серверный инструмент версии _20260209 или более поздней с ZDR, отключите динамическую фильтрацию, задав для инструмента "allowed_callers": ["direct"]:

{
  "type": "web_search_20260209",
  "name": "web_search",
  "allowed_callers": ["direct"]
}

Это ограничивает инструмент только прямым вызовом, минуя внутренний этап выполнения кода.

allowed_callers управляет тем, как может быть вызван инструмент: напрямую Claude ("direct"), изнутри контейнера выполнения кода (например, "code_execution_20260120") или обоими способами. Версии _20260209 веб-инструментов по умолчанию допускают только вызов из выполнения кода; более ранние версии по умолчанию используют ["direct"]. На моделях, не поддерживающих программный вызов инструментов, эти версии требуют allowed_callers: ["direct"]; без этого API возвращает ошибку валидации с указанием задать это значение.

Фильтрация доменов

Серверные инструменты, обращающиеся к вебу, принимают параметры allowed_domains и blocked_domains для управления тем, к каким доменам Claude может обращаться. Оба являются полями объекта инструмента:

{
  "type": "web_search_20250305",
  "name": "web_search",
  "allowed_domains": ["example.com", "docs.python.org"]
}

При использовании фильтров доменов:

  • Домены не должны включать схему HTTP/HTTPS (используйте example.com вместо https://example.com).
  • Поддомены включаются автоматически (example.com охватывает docs.example.com).
  • Конкретные поддомены ограничивают результаты только этим поддоменом (docs.example.com возвращает результаты только с этого поддомена, а не с example.com или api.example.com).
  • Подпути поддерживаются для веб-поиска и соответствуют всему, что следует после пути (example.com/blog соответствует example.com/blog/post-1).
  • Веб-загрузка сопоставляет только домен: запись, включающая путь, никогда не соответствует URL веб-загрузки.
  • Вы можете использовать либо allowed_domains, либо blocked_domains, но не оба параметра в одном запросе.

Поддержка подстановочных знаков:

  • Подстановочные знаки (*) не допускаются в самом домене, только в пути после него.
  • Допустимо: example.com/*, example.com/*/articles
  • Недопустимо: *.example.com, ex*.com

Недопустимые форматы доменов отклоняются во время запроса с ошибкой 400 invalid_request_error.

Claude Managed Agents использует те же поля allowed_domains и blocked_domains в записях web_search и web_fetch набора инструментов агента. В Managed Agents каждый список содержит не более 64 записей, домены, указанные для web_fetch, не могут включать путь, а поля, специфичные для инструментов Messages API, такие как max_uses, citations и cache_control, недоступны. Полные правила см. в разделе Ограничение доменов веб-поиска и веб-загрузки.

Настройки веб-поиска и веб-загрузки на уровне организации в Claude Console применяются только к запросам Messages API; они не применяются к сеансам Managed Agents, которые используют только списки для отдельных инструментов в наборе инструментов агента.

Динамическая фильтрация с выполнением кода

Версии _20260209 и более поздние веб-поиска и веб-загрузки внутренне используют выполнение кода для применения динамических фильтров к результатам поиска.

Потоковая передача событий серверных инструментов

События серверных инструментов передаются в рамках обычного потока «server-sent events» (события, отправляемые сервером), или SSE. Блок server_tool_use, который Claude вызывает напрямую, передаётся потоком так же, как клиентский блок tool_use: событие content_block_start, за которым следуют события input_json_delta. Блок результата приходит целиком в одном событии content_block_start, без дельт.

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

Пакетные запросы

Все серверные инструменты поддерживают пакетную обработку. В пакете агентный цикл работает так же, как и для синхронных запросов, но с более высоким лимитом итераций на ход. Если цикл достигает этого лимита, ответ завершается с stop_reason: "pause_turn"; вы можете продолжить его, отправив последующий запрос с возвращённым содержимым. Подробности см. в разделе Серверные инструменты и агентный цикл.

Типичные пакетные нагрузки включают обогащение набора данных информацией из веба, проверку большого набора документов по актуальным источникам и выполнение аналитического кода над множеством файлов.

Следующие шаги

Исправьте наиболее распространённые ошибки использования инструментов с помощью диагностических таблиц «симптом — решение».

Ищите в вебе и цитируйте результаты.

Загружайте и читайте содержимое по конкретным URL, чтобы дополнить контекст Claude актуальным веб-содержимым.

Запускайте код на Python и bash в изолированном контейнере для анализа данных, создания файлов и итеративной работы над решениями.

Находите и загружайте инструменты по требованию.

Was this page helpful?