Инструменты, выполняемые на сервере, имеют общие механизмы: блок server_tool_use, продолжение pause_turn, ходы, сочетающие серверные и клиентские инструменты, соответствие требованиям «Zero Data Retention» (нулевое хранение данных), или ZDR, и фильтрацию доменов. Информацию об отдельных инструментах см. в справочнике по инструментам.
Блок 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 в следующем запросе.
При использовании серверных инструментов, таких как веб-поиск, API выполняет вызовы инструментов в серверном агентном цикле. Во время длительного хода API может приостановить этот цикл и вернуть причину остановки pause_turn.
Вот как обрабатывать причину остановки pause_turn:
client = anthropic.Anthropic()
# Первоначальный запрос с веб-поиском
response = client.messages.create(
model="claude-opus-4-8",
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-4-8",
max_tokens=1024,
messages=messages,
tools=[{"type": "web_search_20250305", "name": "web_search", "max_uses": 10}],
)
print(continuation)
else:
print(response)При обработке pause_turn:
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 ведёт себя так же. Вызовы серверных инструментов, у которых уже есть блок результата в том же ответе, завершены и не требуют от вас никаких действий.При программном вызове инструментов та же форма ответа означает нечто иное. Клиентский блок tool_use исходит от кода, выполняющегося в инструменте code_execution, а не напрямую от Claude, и его поле caller указывает на блок code_execution, который его вызвал. Этот код уже запущен: он приостановлен в ожидании ваших блоков tool_result, и их отправка возобновляет выполнение, а не запускает отложенный инструмент. Собственный блок результата блока code_execution приходит после завершения кода, что может занять более одного раунда результатов инструментов. Само последующее пользовательское сообщение одинаково в обоих случаях; при программном вызове инструментов также передайте обратно id из поля container ответа, как показано на той странице.
{
"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 — так же, как вы накапливаете любой другой обмен с использованием инструментов.
Последующее пользовательское сообщение не должно содержать ничего, кроме блоков tool_result. Блок, добавленный после результатов, например текст, сообщает API, что ход ассистента завершён. Для серверного инструмента, который Claude вызвал напрямую, это оставляет ход с неразрешённым вызовом серверного инструмента, и запрос завершается ошибкой 400 invalid_request_error:
`web_fetch` tool use with id `srvtoolu_01HxbWnMRmbWyMfUtJKC45rA` was found without a corresponding `web_fetch_tool_result` blockПоследующее сообщение, которое помещает содержимое перед результатами, отвечает только на часть идентификаторов клиентских tool_use или вообще не содержит блоков tool_result, завершается ошибкой раньше — с ошибкой клиентского инструмента, описанной в разделе Обработка вызовов инструментов:
`tool_use` ids were found without `tool_result` blocks immediately after: toolu_01PjgRJLbXrXEMZwDNYLnBqk. Each `tool_use` block must have a corresponding `tool_result` block in the next message.Чтобы передать Claude дополнительные входные данные, отправьте их отдельным пользовательским сообщением после завершения хода.
Чем это отличается от 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, вместо этого повторно отправляется как есть.
Базовые версии веб-поиска (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 возвращает ошибку валидации, указывающую на необходимость его установки.
Даже когда веб-загрузка используется в конфигурации, соответствующей требованиям ZDR, издатели веб-сайтов могут сохранять любые параметры, переданные в URL, если Claude загружает содержимое с их сайта.
Серверные инструменты, обращающиеся к веб-ресурсам, принимают параметры allowed_domains и blocked_domains для управления тем, к каким доменам Claude может обращаться. Оба являются полями объекта инструмента:
{
"type": "web_search_20250305",
"name": "web_search",
"allowed_domains": ["example.com", "docs.python.org"]
}При использовании фильтров доменов:
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).allowed_domains, либо blocked_domains, но не оба в одном запросе.Поддержка подстановочных знаков:
*) не допускаются в самом домене, только в пути после него.example.com/*, example.com/*/articles*.example.com, ex*.comНедопустимые форматы доменов отклоняются во время запроса с ошибкой 400 invalid_request_error.
Ограничения доменов на уровне запроса работают совместно с любыми ограничениями доменов на уровне организации, настроенными в Claude Console. allowed_domains на уровне запроса должны быть подмножеством списка разрешённых на уровне организации; записи вне его приводят к тому, что API возвращает ошибку валидации. Домены, заблокированные вашей организацией, удаляются из списка разрешённых на уровне запроса, а не вызывают ошибку.
Символы Unicode в доменных именах могут обходить фильтры доменов через омографические атаки: аmazon.com (с кириллической а) выглядит идентично amazon.com, но является другим доменом. Используйте только ASCII-символы в доменных именах в списках разрешённых и заблокированных доменов и проверяйте существующие записи на наличие не-ASCII символов.
Версии _20260209 и более поздние веб-поиска и веб-загрузки внутренне используют выполнение кода для применения динамических фильтров к результатам поиска.
Вам не нужно добавлять инструмент code_execution для этих версий: когда запускается динамическая фильтрация, API автоматически предоставляет выполнение кода для запроса, и оба инструмента используют один контейнер выполнения. Если вы всё же включаете его, используйте code_execution_20260120 или более позднюю версию; API отклоняет более старые версии выполнения кода вместе с этими версиями веб-инструментов.
События серверных инструментов передаются потоком как часть обычного потока «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?