Программный вызов инструментов позволяет Claude писать код, который вызывает ваши инструменты программно в контейнере выполнения кода, вместо того чтобы требовать обратные проходы через модель для каждого вызова инструмента. Это снижает задержку для многоинструментальных рабочих процессов и уменьшает потребление токенов, позволяя Claude фильтровать или обрабатывать данные перед тем, как они попадут в контекстное окно модели.
Программный вызов инструментов в настоящее время находится в открытой бета-версии.
Чтобы использовать эту функцию, добавьте бета-заголовок "advanced-tool-use-2025-11-20" к вашим запросам API.
Эта функция требует включения инструмента выполнения кода.
Программный вызов инструментов доступен на следующих моделях:
| Модель | Версия инструмента |
|---|---|
Claude Opus 4.5 (claude-opus-4-5-20251101) | code_execution_20250825 |
Claude Sonnet 4.5 (claude-sonnet-4-5-20250929) | code_execution_20250825 |
Программный вызов инструментов доступен через Claude API и Microsoft Foundry.
Вот простой пример, где Claude программно запрашивает базу данных несколько раз и агрегирует результаты:
Когда вы настраиваете инструмент для вызова из выполнения кода и Claude решает использовать этот инструмент:
tool_useЭтот подход особенно полезен для:
Пользовательские инструменты преобразуются в асинхронные функции Python для поддержки параллельного вызова инструментов. Когда Claude пишет код, который вызывает ваши инструменты, он использует await (например, result = await query_database("<sql>")) и автоматически включает соответствующую асинхронную функцию-обертку.
Асинхронная обертка опущена из примеров кода в этой документации для ясности.
allowed_callersПоле allowed_callers указывает, какие контексты могут вызывать инструмент:
{
"name": "query_database",
"description": "Execute a SQL query against the database",
"input_schema": {...},
"allowed_callers": ["code_execution_20250825"]
}Возможные значения:
["direct"] - Только Claude может вызывать этот инструмент напрямую (по умолчанию, если опущено)["code_execution_20250825"] - Вызываемо только из выполнения кода["direct", "code_execution_20250825"] - Вызываемо как напрямую, так и из выполнения кодаМы рекомендуем выбирать либо ["direct"], либо ["code_execution_20250825"] для каждого инструмента, а не включать оба, так как это обеспечивает более четкое руководство Claude по использованию инструмента.
caller в ответахКаждый блок использования инструмента включает поле caller, указывающее, как он был вызван:
Прямой вызов (традиционное использование инструмента):
{
"type": "tool_use",
"id": "toolu_abc123",
"name": "query_database",
"input": {"sql": "\<sql\>"},
"caller": {"type": "direct"}
}Программный вызов:
{
"type": "tool_use",
"id": "toolu_xyz789",
"name": "query_database",
"input": {"sql": "\<sql\>"},
"caller": {
"type": "code_execution_20250825",
"tool_id": "srvtoolu_abc123"
}
}tool_id ссылается на инструмент выполнения кода, который сделал программный вызов.
Программный вызов инструментов использует те же контейнеры, что и выполнение кода:
containerКогда инструмент вызывается программно и контейнер ожидает результат вашего инструмента, вы должны ответить до истечения контейнера. Отслеживайте поле expires_at. Если контейнер истечет, Claude может рассматривать вызов инструмента как истекший по времени и повторить его.
Вот как работает полный поток программного вызова инструментов:
Отправьте запрос с выполнением кода и инструментом, который позволяет программный вызов. Чтобы включить программный вызов, добавьте поле allowed_callers к определению вашего инструмента.
Предоставьте подробные описания формата вывода вашего инструмента в описании инструмента. Если вы указываете, что инструмент возвращает JSON, Claude попытается десериализовать и обработать результат в коде. Чем больше деталей вы предоставите о схеме вывода, тем лучше Claude сможет обработать ответ программно.
Claude пишет код, который вызывает ваш инструмент. API приостанавливается и возвращает:
{
"role": "assistant",
"content": [
{
"type": "text",
"text": "I'll query the purchase history and analyze the results."
},
{
"type": "server_tool_use",
"id": "srvtoolu_abc123",
"name": "code_execution",
"input": {
"code": "results = await query_database('<sql>')\ntop_customers = sorted(results, key=lambda x: x['revenue'], reverse=True)[:5]\nprint(f'Top 5 customers: {top_customers}')"
}
},
{
"type": "tool_use",
"id": "toolu_def456",
"name": "query_database",
"input": {"sql": "\<sql\>"},
"caller": {
"type": "code_execution_20250825",
"tool_id": "srvtoolu_abc123"
}
}
],
"container": {
"id": "container_xyz789",
"expires_at": "2025-01-15T14:30:00Z"
},
"stop_reason": "tool_use"
}Включите полную историю разговора плюс результат вашего инструмента:
Выполнение кода продолжается и обрабатывает результаты. Если требуются дополнительные вызовы инструментов, повторите Шаг 3 до тех пор, пока все вызовы инструментов не будут удовлетворены.
После завершения выполнения кода Claude предоставляет окончательный ответ:
{
"content": [
{
"type": "code_execution_tool_result",
"tool_use_id": "srvtoolu_abc123",
"content": {
"type": "code_execution_result",
"stdout": "Top 5 customers by revenue:\n1. Customer C1: $45,000\n2. Customer C2: $38,000\n3. Customer C5: $32,000\n4. Customer C8: $28,500\n5. Customer C3: $24,000",
"stderr": "",
"return_code": 0,
"content": []
}
},
{
"type": "text",
"text": "I've analyzed the purchase history from last quarter. Your top 5 customers generated $167,500 in total revenue, with Customer C1 leading at $45,000."
}
],
"stop_reason": "end_turn"
}Claude может писать код, который эффективно обрабатывает несколько элементов:
# async wrapper omitted for clarity
regions = ["West", "East", "Central", "North", "South"]
results = {}
for region in regions:
data = await query_database(f"<sql for {region}>")
results[region] = sum(row["revenue"] for row in data)
# Process results programmatically
top_region = max(results.items(), key=lambda x: x[1])
print(f"Top region: {top_region[0]} with ${top_region[1]:,} in revenue")Этот паттерн:
Claude может остановить обработку, как только будут выполнены критерии успеха:
# async wrapper omitted for clarity
endpoints = ["us-east", "eu-west", "apac"]
for endpoint in endpoints:
status = await check_health(endpoint)
if status == "healthy":
print(f"Found healthy endpoint: {endpoint}")
break # Stop early, don't check remaining# async wrapper omitted for clarity
file_info = await get_file_info(path)
if file_info["size"] < 10000:
content = await read_full_file(path)
else:
content = await read_file_summary(path)
print(content)# async wrapper omitted for clarity
logs = await fetch_logs(server_id)
errors = [log for log in logs if "ERROR" in log]
print(f"Found {len(errors)} errors")
for error in errors[-10:]: # Only return last 10 errors
print(error)Когда выполнение кода вызывает инструмент:
{
"type": "tool_use",
"id": "toolu_abc123",
"name": "query_database",
"input": {"sql": "\<sql\>"},
"caller": {
"type": "code_execution_20250825",
"tool_id": "srvtoolu_xyz789"
}
}Результат вашего инструмента передается обратно в выполняющийся код:
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_abc123",
"content": "[{\"customer_id\": \"C1\", \"revenue\": 45000, \"orders\": 23}, {\"customer_id\": \"C2\", \"revenue\": 38000, \"orders\": 18}, ...]"
}
]
}Когда все вызовы инструментов удовлетворены и код завершается:
{
"type": "code_execution_tool_result",
"tool_use_id": "srvtoolu_xyz789",
"content": {
"type": "code_execution_result",
"stdout": "Analysis complete. Top 5 customers identified from 847 total records.",
"stderr": "",
"return_code": 0,
"content": []
}
}| Ошибка | Описание | Решение |
|---|---|---|
invalid_tool_input | Входные данные инструмента не соответствуют схеме | Проверьте input_schema вашего инструмента |
tool_not_allowed | Инструмент не позволяет запрашиваемый тип вызывающего | Проверьте, что allowed_callers включает правильные контексты |
missing_beta_header | Бета-заголовок PTC не предоставлен | Добавьте оба бета-заголовка к вашему запросу |
Если ваш инструмент слишком долго отвечает, выполнение кода получит TimeoutError. Claude видит это в stderr и обычно повторит попытку:
{
"type": "code_execution_tool_result",
"tool_use_id": "srvtoolu_abc123",
"content": {
"type": "code_execution_result",
"stdout": "",
"stderr": "TimeoutError: Calling tool ['query_database'] timed out.",
"return_code": 0,
"content": []
}
}Чтобы предотвратить истечение времени:
expires_at в ответахЕсли ваш инструмент возвращает ошибку:
# Provide error information in the tool result
{
"type": "tool_result",
"tool_use_id": "toolu_abc123",
"content": "Error: Query timeout - table lock exceeded 30 seconds"
}Код Claude получит эту ошибку и сможет обработать ее соответствующим образом.
strict: true не поддерживаются при программном вызовеtool_choicedisable_parallel_tool_use: true не поддерживается при программном вызовеСледующие инструменты в настоящее время не могут быть вызваны программно, но поддержка может быть добавлена в будущих версиях:
При ответе на программные вызовы инструментов существуют строгие требования к форматированию:
Ответы только с результатом инструмента: Если есть ожидающие программные вызовы инструментов, ожидающие результатов, ваше сообщение ответа должно содержать только блоки tool_result. Вы не можете включать никакое текстовое содержимое, даже после результатов инструментов.
// ❌ INVALID - Cannot include text when responding to programmatic tool calls
{
"role": "user",
"content": [
{"type": "tool_result", "tool_use_id": "toolu_01", "content": "[{\"customer_id\": \"C1\", \"revenue\": 45000}]"},
{"type": "text", "text": "What should I do next?"} // This will cause an error
]
}
// ✅ VALID - Only tool results when responding to programmatic tool calls
{
"role": "user",
"content": [
{"type": "tool_result", "tool_use_id": "toolu_01", "content": "[{\"customer_id\": \"C1\", \"revenue\": 45000}]"}
]
}Это ограничение применяется только при ответе на программные (выполнение кода) вызовы инструментов. Для обычных клиентских вызовов инструментов вы можете включать текстовое содержимое после результатов инструментов.
Программные вызовы инструментов подлежат тем же ограничениям скорости, что и обычные вызовы инструментов. Каждый вызов инструмента из выполнения кода считается отдельным вызовом.
При реализации пользовательских инструментов, которые будут вызваны программно:
Программный вызов инструментов может значительно снизить потребление токенов:
Например, прямой вызов 10 инструментов использует примерно в 10 раз больше токенов, чем их программный вызов и возврат сводки.
Программный вызов инструментов использует те же цены, что и выполнение кода. Подробнее см. в разделе цены выполнения кода.
Подсчет токенов для программных вызовов инструментов: Результаты инструментов из программных вызовов не учитываются в вашем использовании входных/выходных токенов. Учитываются только окончательный результат выполнения кода и ответ Claude.
Хорошие варианты использования:
Менее идеальные варианты использования:
Ошибка "Tool not allowed"
"allowed_callers": ["code_execution_20250825"]Истечение контейнера
expires_at в ответахПроблемы с бета-заголовком
"advanced-tool-use-2025-11-20"Результат инструмента не анализируется правильно
caller для подтверждения программного вызоваОбучение Claude включает обширное воздействие кода, что делает его эффективным в рассуждении и цепочке вызовов функций. Когда инструменты представлены как вызываемые функции в среде выполнения кода, Claude может использовать эту силу для:
Этот подход позволяет использовать рабочие процессы, которые были бы непрактичны при традиционном использовании инструментов — такие как обработка файлов размером более 1M токенов — позволяя Claude работать с данными программно, а не загружать все в контекст разговора.
Программный вызов инструментов — это обобщаемый паттерн, который можно реализовать вне управляемого выполнения кода Anthropic. Вот обзор подходов:
Предоставьте Claude инструмент выполнения кода и опишите, какие функции доступны в этой среде. Когда Claude вызывает инструмент с кодом, ваше приложение выполняет его локально, где определены эти функции.
Преимущества:
Недостатки:
Используйте когда: Ваше приложение может безопасно выполнять произвольный код, вы хотите простое решение, и управляемое предложение Anthropic не подходит вашим потребностям.
Тот же подход с точки зрения Claude, но код работает в изолированном контейнере с ограничениями безопасности (например, без исходящего сетевого трафика). Если ваши инструменты требуют внешних ресурсов, вам потребуется протокол для выполнения вызовов инструментов вне изолированной среды.
Преимущества:
Недостатки:
Используйте когда: Безопасность критична и управляемое решение Anthropic не подходит вашим требованиям.
Программный вызов инструментов Anthropic — это управляемая версия изолированного выполнения с предпочтительной средой Python, настроенной для Claude. Anthropic обрабатывает управление контейнерами, выполнение кода и безопасное взаимодействие вызова инструмента.
Преимущества:
Мы рекомендуем использовать управляемое решение Anthropic, если вы используете Claude API.
curl https://api.anthropic.com/v1/messages \
--header "x-api-key: $ANTHROPIC_API_KEY" \
--header "anthropic-version: 2023-06-01" \
--header "anthropic-beta: advanced-tool-use-2025-11-20" \
--header "content-type: application/json" \
--data '{
"model": "claude-sonnet-4-5",
"max_tokens": 4096,
"messages": [
{
"role": "user",
"content": "Query sales data for the West, East, and Central regions, then tell me which region had the highest revenue"
}
],
"tools": [
{
"type": "code_execution_20250825",
"name": "code_execution"
},
{
"name": "query_database",
"description": "Execute a SQL query against the sales database. Returns a list of rows as JSON objects.",
"input_schema": {
"type": "object",
"properties": {
"sql": {
"type": "string",
"description": "SQL query to execute"
}
},
"required": ["sql"]
},
"allowed_callers": ["code_execution_20250825"]
}
]
}'response = client.beta.messages.create(
model="claude-sonnet-4-5",
betas=["advanced-tool-use-2025-11-20"],
max_tokens=4096,
messages=[{
"role": "user",
"content": "Query customer purchase history from the last quarter and identify our top 5 customers by revenue"
}],
tools=[
{
"type": "code_execution_20250825",
"name": "code_execution"
},
{
"name": "query_database",
"description": "Execute a SQL query against the sales database. Returns a list of rows as JSON objects.",
"input_schema": {...},
"allowed_callers": ["code_execution_20250825"]
}
]
)response = client.beta.messages.create(
model="claude-sonnet-4-5",
betas=["advanced-tool-use-2025-11-20"],
max_tokens=4096,
container="container_xyz789", # Reuse the container
messages=[
{"role": "user", "content": "Query customer purchase history from the last quarter and identify our top 5 customers by revenue"},
{
"role": "assistant",
"content": [
{"type": "text", "text": "I'll query the purchase history and analyze the results."},
{
"type": "server_tool_use",
"id": "srvtoolu_abc123",
"name": "code_execution",
"input": {"code": "..."}
},
{
"type": "tool_use",
"id": "toolu_def456",
"name": "query_database",
"input": {"sql": "\<sql\>"},
"caller": {
"type": "code_execution_20250825",
"tool_id": "srvtoolu_abc123"
}
}
]
},
{
"role": "user",
"content": [
{
"type": "tool_result",
"tool_use_id": "toolu_def456",
"content": "[{\"customer_id\": \"C1\", \"revenue\": 45000}, {\"customer_id\": \"C2\", \"revenue\": 38000}, ...]"
}
]
}
],
tools=[...]
)Поймите основы использования инструментов с Claude.