Вызов инструментов
Спросите модель, сколько будет 1 984 135 × 9 343 116, и она, скорее всего, ошибётся в паре цифр: она предсказывает текст, а не считает. Но если дать ей калькулятор и объяснить, как им пользоваться, она попросит посчитать, получит результат и ответит верно. Это вызов инструментов — механизм, на котором стоят все агенты, MCP и коннекторы. В уроке — как он устроен и что в нём зависит от промпта.
Идея: модель просит, программа делает
Модель не может ничего выполнить сама. Вызов инструментов — это договорённость из трёх шагов:
- Модель пишет в ответе не текст для человека, а структурированную просьбу: «вызови инструмент такой-то с такими-то параметрами».
- Программа видит эту просьбу, выполняет настоящий вызов (считает, идёт в базу, дёргает API) и возвращает результат.
- Модель получает результат и продолжает: отвечает пользователю или просит вызвать ещё что-нибудь.
Это та же цепочка из прошлого урока, только в середину вставлена программа. В туториале так и сказано: вызов инструментов — это подстановка плюс цепочка.
Что можно дать модели в виде инструмента: калькулятор, поиск по базе, запрос к трекеру, отправку сообщения, запуск тестов, чтение файла. Всё, что умеет делать функция в коде.
Как это было и как стало
В оригинальном туториале инструменты описывались текстом в системном промпте: длинное объяснение «у тебя есть функции, вызывай их вот таким тегом», список инструментов в XML и стоп-последовательность, чтобы поймать момент вызова. Параметры вытаскивались из ответа регулярными выражениями. Это работало, но хрупко.
Сейчас всё это встроено в API. Вы передаёте инструменты отдельным параметром tools — имя, описание и схема параметров в формате JSON Schema. Модель отвечает специальным блоком tool_use с именем инструмента и заполненными параметрами; поле stop_reason сообщает, что модель ждёт результата. Вы выполняете вызов и возвращаете результат блоком tool_result. Никаких регулярных выражений.
import anthropic
client = anthropic.Anthropic()
MODEL = "claude-opus-5"
tools = [{
"name": "get_issue",
"description": (
"Возвращает задачу из трекера по ключу: заголовок, статус, "
"исполнителя и описание. Используй, когда пользователь ссылается "
"на задачу по ключу вида PROJ-123."
),
"input_schema": {
"type": "object",
"properties": {
"key": {"type": "string", "description": "Ключ задачи, например PROJ-1432"}
},
"required": ["key"],
},
}]
def get_issue(key):
# Здесь был бы настоящий запрос к трекеру
return {"key": key, "title": "Падает экспорт в PDF", "status": "Open",
"assignee": "—", "description": "Ошибка 500 при экспорте отчёта больше 50 страниц"}
messages = [{"role": "user", "content": "Что сейчас с PROJ-1432 и кому её отдать?"}]
response = client.messages.create(
model=MODEL, max_tokens=1000, tools=tools, messages=messages
)
while response.stop_reason == "tool_use":
tool_call = next(b for b in response.content if b.type == "tool_use")
result = get_issue(**tool_call.input)
messages += [
{"role": "assistant", "content": response.content},
{"role": "user", "content": [{
"type": "tool_result",
"tool_use_id": tool_call.id,
"content": str(result),
}]},
]
response = client.messages.create(
model=MODEL, max_tokens=1000, tools=tools, messages=messages
)
print(next(b.text for b in response.content if b.type == "text"))Цикл while — это и есть «агентский цикл»: модель просит, программа делает, пока модель не решит, что готова ответить. Точные имена полей и актуальные примеры — в документации по инструментам.
Если вы не пишете код, запомните главное: инструмент — это описание функции, которое модель читает, и программа, которая её выполняет. Модель выбирает инструмент по описанию. Значит, качество описания — это промпт-инжиниринг.
Описание инструмента — это промпт
Модель решает, вызывать ли инструмент и с какими параметрами, только по тому, что написано в описании. Отсюда правила, знакомые по всему курсу.
Ясно и подробно: что делает инструмент, что возвращает, когда его использовать и когда нет. «Получить задачу» — плохо. «Возвращает задачу из трекера по ключу: заголовок, статус, исполнителя и описание; используй, когда пользователь ссылается на задачу по ключу» — хорошо.
Описывайте каждый параметр: тип, формат, пример. «key: ключ задачи, например PROJ-1432» избавляет от вызовов с неправильным форматом.
Проверьте на противоположных запросах. В туториале после калькулятора модели задают «какая столица Франции?» — и она не вызывает калькулятор, потому что описание ясно говорит, что он для арифметики. Ваши инструменты должны проходить такую же проверку: на вопрос не по теме модель не должна их дёргать.
Если параметров не хватает, модель может либо спросить пользователя, либо угадать значение. Второе опасно. В описании или системном промпте стоит сказать: «если для вызова не хватает данных, спроси пользователя, а не предполагай».
Границу «вызывать или отвечать самому» можно сдвигать системным промптом: «используй инструменты, чтобы проверить, прежде чем отвечать» — больше вызовов; «используй инструменты только когда без них не обойтись» — меньше. Есть и жёсткий вариант через параметр tool_choice, когда вызов обязателен.
Инструменты в чате: коннекторы и MCP
В чате Claude и в Claude Code вы не описываете инструменты сами — их приносят коннекторы и MCP-серверы. Когда вы подключаете трекер или календарь, модель получает список инструментов с описаниями, ровно как в коде выше, и дальше сама решает, когда что вызвать. Курс «MCP: введение» как раз про это.
Отсюда практический вывод для всех: если модель вызывает не тот инструмент или не вызывает нужный, посмотрите на описания инструментов сервера — часто дело в них. А если вы пишете свой MCP-сервер, описания инструментов — самая важная его часть.
Пример из работы
Тестировщик собирает ассистента, который по описанию бага находит похожие задачи в трекере. Первый вариант описания инструмента поиска: «поиск задач». Модель вызывает его с запросом из одного слова и получает сотни результатов. Второй вариант: «Полнотекстовый поиск по задачам. Передавай запрос из 3–6 ключевых слов: компонент, симптом, действие. Возвращает до 10 задач с ключом, заголовком и статусом. Если результатов больше 10, уточни запрос». Модель начинает формулировать запросы осмысленно и уточнять их сама. Изменился только текст описания.
Попробуйте сами
10–15 мин на рабочем месте- Без кода, в чате: опишите Claude воображаемый инструмент («у тебя есть инструмент
create_taskс параметрами title, assignee, due_date; чтобы вызвать его, напиши JSON с именем и параметрами и остановись») и дайте несколько запросов: «заведи задачу Оле на пятницу — починить экспорт», «а какая сегодня погода?». Посмотрите, когда модель «вызывает» инструмент, а когда нет, и что делает при нехватке данных. - Напишите описания для трёх инструментов вашего рабочего сервиса (трекер, вики, календарь) по правилам урока: что делает, что возвращает, когда использовать, параметры с примерами. Покажите коллеге: понятно ли из описания, когда какой вызывать?
- Для разработчиков: запустите пример из урока с настоящим ключом API, заменив
get_issueна любую свою функцию. Затем задайте вопрос не по теме и убедитесь, что инструмент не вызывается.
Коротко
- Модель не выполняет действия, а просит программу: описание инструмента → блок
tool_use→ выполнение →tool_result→ ответ. - В современном API инструменты передаются параметром
toolsсо схемой; текстовые описания в системном промпте и регулярные выражения — прошлое. - Модель выбирает инструмент только по описанию: пишите, что делает, что возвращает, когда использовать, и описывайте каждый параметр.
- Проверяйте на запросах не по теме и на нехватке параметров: модель должна не вызывать и спрашивать, а не угадывать.
- В чате инструменты приносят коннекторы и MCP-серверы; их описания — тот же промпт-инжиниринг.
Видеоверсия
Сценарий озвучки · 472 слова, ≈ 4 мин
Спросите модель, сколько будет один миллион девятьсот восемьдесят четыре тысячи умножить на девять миллионов триста сорок три тысячи, и она, скорее всего, ошибётся в паре цифр. Она предсказывает текст, а не считает. Но дайте ей калькулятор и объясните, как им пользоваться — и она попросит посчитать, получит результат и ответит верно. Это вызов инструментов, механизм, на котором стоят все агенты и коннекторы.
Идея простая. Модель не может ничего выполнить сама. Вместо этого она пишет структурированную просьбу: «вызови такой-то инструмент с такими-то параметрами». Программа видит просьбу, выполняет настоящий вызов и возвращает результат. Модель получает результат и продолжает: отвечает пользователю или просит ещё что-нибудь. По сути это цепочка из прошлого урока, только в середину вставлена программа. Инструментом может быть калькулятор, поиск по базе, запрос к трекеру, отправка сообщения, запуск тестов — всё, что умеет функция в коде.
В оригинальном туториале инструменты описывались текстом в системном промпте, а параметры вытаскивались из ответа регулярными выражениями. Работало, но хрупко. Сейчас всё встроено в API: вы передаёте инструменты отдельным параметром с именем, описанием и схемой параметров. Модель отвечает специальным блоком «вызов инструмента», вы выполняете вызов и возвращаете результат отдельным блоком. Цикл «модель просит — программа делает» повторяется, пока модель не решит, что готова ответить. Это и есть агентский цикл.
Если вы не пишете код, запомните главное: инструмент — это описание функции, которое модель читает, и программа, которая её выполняет. Модель выбирает инструмент по описанию. Значит, качество описания — это промпт-инжиниринг, и все правила курса здесь работают. Пишите ясно и подробно: что делает инструмент, что возвращает, когда его использовать и когда нет. «Получить задачу» — плохо. «Возвращает задачу из трекера по ключу: заголовок, статус, исполнителя; используй, когда пользователь ссылается на задачу по ключу» — хорошо. Описывайте каждый параметр с примером. И проверяйте на противоположных запросах: в туториале после калькулятора модель спрашивают про столицу Франции, и она калькулятор не трогает. Ваши инструменты должны проходить такую же проверку.
Отдельно про нехватку данных. Если для вызова не хватает параметра, модель может спросить пользователя или угадать значение. Второе опасно. Скажите в системном промпте: «если не хватает данных, спроси, а не предполагай».
В чате Claude и в Claude Code вы не описываете инструменты сами — их приносят коннекторы и MCP-серверы. Подключили трекер — модель получила список инструментов с описаниями, ровно как в коде, и сама решает, когда что вызвать. Практический вывод: если модель вызывает не тот инструмент, посмотрите на описания — часто дело в них.
Пример из работы. Тестировщик собирает ассистента, который ищет похожие задачи в трекере. Описание «поиск задач» даёт запросы из одного слова и сотни результатов. Описание «полнотекстовый поиск, передавай три-шесть ключевых слов: компонент, симптом, действие; возвращает до десяти задач; если больше — уточни запрос» — и модель формулирует запросы осмысленно. Изменился только текст описания.
Попробуйте без кода: опишите Claude в чате воображаемый инструмент для создания задач и дайте несколько запросов, включая один не по теме. Посмотрите, когда модель «вызывает» инструмент и что делает при нехватке данных. В последнем уроке — поиск и извлечение данных.
