Инструменты, выполняемые на сервере, имеют общую механику: блок 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-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}],
)
# Проверяем, имеет ли ответ причину остановки 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:
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, вместо этого повторно отправляется как есть.
Базовые версии веб-поиска (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"]
}При использовании фильтров доменов:
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.
Версии _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?