Tool Use в Claude: официальный курс · Урок 2
Первый простой инструмент
Пишем калькулятор, определяем tool schema в JSON Schema формате, передаём Claude и обрабатываем ответ с tool_use блоком.
Проблема: Claude плохо считает
response = client.messages.create(
model="claude-3-haiku-20240307",
messages=[{"role": "user", "content": "Multiply 1984135 by 9343116. Only respond with the result"}],
max_tokens=400
)
# Claude ответил: 18593367726060
# Правильный ответ: 18538003464660
# Ошибка на 55 миллионов!
Решение: даём Claude калькулятор
def calculator(operation, operand1, operand2):
if operation == "add":
return operand1 + operand2
elif operation == "subtract":
return operand1 - operand2
elif operation == "multiply":
return operand1 * operand2
elif operation == "divide":
if operand2 == 0:
raise ValueError("Cannot divide by zero.")
return operand1 / operand2
calculator_tool = {
"name": "calculator",
"description": "A simple calculator that performs basic arithmetic operations.",
"input_schema": {
"type": "object",
"properties": {
"operation": {
"type": "string",
"enum": ["add", "subtract", "multiply", "divide"],
"description": "The arithmetic operation to perform."
},
"operand1": {"type": "number", "description": "The first operand."},
"operand2": {"type": "number", "description": "The second operand."}
},
"required": ["operation", "operand1", "operand2"]
}
}
Полный цикл: извлекаем inputs и вызываем функцию
response = client.messages.create(
model="claude-3-haiku-20240307",
messages=[{"role": "user", "content": "Multiply 1984135 by 9343116. Only respond with the result"}],
max_tokens=300,
tools=[calculator_tool]
)
# response.stop_reason == "tool_use"
tool_name = response.content[0].name # "calculator"
tool_inputs = response.content[0].input # {"operation": "multiply", "operand1": 1984135, "operand2": 9343116}
result = calculator(tool_inputs["operation"], tool_inputs["operand1"], tool_inputs["operand2"])
# RESULT: 18538003464660 — верно!
Системный промпт против жадных инструментов
Если спросить "What color are emeralds?" с калькулятором — Claude может попытаться его вызвать. Фикс:
system="You have access to tools, but only use them when necessary."
Практическое задание
Что сделать после урока
Напишите инструмент temperature_converter с параметрами value (number) и unit ('celsius'|'fahrenheit'). Реализуйте функцию конвертации и полный цикл вызова через Claude.
Готовый промпт
Шаблон под задачу урока
Скопируйте и адаптируйте под свой контекст. Текст в треугольных скобках — то, что нужно заменить.
Я хочу дать Claude инструмент для <задача>.
Функция уже написана:
def my_tool(<params>):
# ...
Напиши для неё корректный tool definition в формате JSON Schema
с полями name, description, input_schema.
Объясни каждый параметр и почему он required или optional.Типичные ошибки
На чём чаще всего спотыкаются
- Забывают enum для строковых параметров с ограниченным набором значений.
- Путают response.content[0].text (текст) с response.content[0].input (tool inputs).
- Не проверяют stop_reason перед обработкой — Claude может ответить текстом.
Лайфхаки
Что работает, но в гайдах не пишут
- Используйте enum в input_schema — Claude точнее выбирает значения.
- Проверяйте tool_name перед вызовом — Claude мог выбрать другой инструмент.
- response.content[-1] — надёжнее для получения tool_use блока, если ответ содержит и текст, и tool_use.
Когда использовать
Точные вычисления, форматирование данных, любая детерминированная операция где Claude может ошибиться.
Когда не использовать
Простые факты, которые Claude знает достоверно — добавление инструмента без нужды замедляет ответ.
Официальные источники
Квиз — 3 вопроса
1.Вы определили tool с операцией enum: ['add', 'subtract', 'multiply', 'divide']. Claude прислал input с operation='modulo'. Что делать?
2.Какое поле tool definition наиболее влияет на то, решит ли Claude вызвать инструмент?
3.После вызова client.messages.create с tools=[calculator_tool] вы получаете response. Как получить имя инструмента, который хочет вызвать Claude?
Отвечено: 0 из 3