Введение: Завершение цикла использования инструментов Claude
Добро пожаловать в урок, посвященный завершающему этапу взаимодействия с инструментами Claude! В предыдущих разделах мы узнали, как Claude может определять необходимость использования внешних функций для выполнения задач, выходящих за рамки его собственных знаний. Теперь мы рассмотрим критически важный следующий шаг: как ваша система должна выполнить запрошенную функцию и, что не менее важно, как правильно отправить результаты обратно Claude.
Этот процесс является ключевым для успешного использования инструментов, поскольку он предоставляет Claude необходимую информацию для формирования окончательного, точного и полезного ответа пользователю. Без этого этапа Claude не сможет завершить свою задачу, оставив пользователя без решения.
Извлечение параметров и выполнение функции инструмента
Когда Claude определяет, что ему необходимо использовать инструмент, он немедленно сообщает об этом в своем ответе. Вместо обычного текстового сообщения вы получите специальный блок, который мы называем tool_use_block. Этот блок содержит всю информацию, необходимую для вызова вашей функции.
Ваша задача начинается с извлечения этой информации. Типичный ответ Claude, требующий использования инструмента, будет содержать структуру, из которой вы можете получить доступ к tool_use_block. Например, если это первый блок в ответе, вы можете получить к нему доступ следующим образом:
tool_use_block = response.content[1]
Внутри этого блока находится объект input, который содержит параметры, которые Claude хочет передать вашей функции. Вы можете извлечь их так:
input_params = tool_use_block.input
После того как вы получили input_params, которые обычно представляют собой словарь, вы можете вызвать свою функцию. Если ваша функция ожидает именованные аргументы, вы можете использовать оператор двойной звездочки (**) для распаковки словаря в эти аргументы. Например, если у вас есть функция get_current_datetime, которая не принимает аргументов или принимает их опционально:
result = get_current_datetime(**input_params)
Важно помнить, что функция get_current_datetime (или любая другая функция, которую вызывает Claude) должна быть реализована вами в вашей системе. Claude лишь запрашивает ее выполнение, но не выполняет ее сам.
Отправка результатов обратно Claude с помощью tool_result_block
После успешного выполнения вашей функции и получения результата, следующим шагом является отправка этого результата обратно Claude. Для этого используется специальный блок, называемый tool_result_block. Этот блок является частью вашего последующего запроса к Claude и имеет несколько важных свойств:
tool_use_id: Это свойство является критически важным. Оно должно точно соответствоватьID, который Claude предоставил в оригинальномtool_use_block. Это позволяет Claude однозначно сопоставить результат с конкретным запросом на использование инструмента.content: Здесь вы размещаете фактический результат выполнения вашей функции. Важно, чтобы этот результат был преобразован в строку, так как Claude обрабатывает его как текстовую информацию.is_error: Это логическое значение (TrueилиFalse), которое указывает, произошла ли ошибка во время выполнения вашей функции. Если ваша функция завершилась с ошибкой, установите это значение вTrueи, по возможности, включите сообщение об ошибке вcontent. Это позволяет Claude понять, что инструмент не смог выполнить свою задачу, и, возможно, попробовать альтернативный подход или сообщить об ошибке пользователю.
Правильное формирование tool_result_block гарантирует, что Claude получит всю необходимую информацию для продолжения диалога и формирования окончательного ответа.
Обработка нескольких вызовов инструментов
Claude — это мощный LLM, способный обрабатывать сложные запросы. В некоторых случаях, особенно когда пользователь задает вопрос, требующий нескольких независимых действий, Claude может запросить выполнение нескольких инструментов в одном ответе. Например, если пользователь спросит: "Сколько будет 10 + 10 и сколько будет 30 + 30?", Claude может ответить двумя отдельными tool_use_block, каждый из которых будет вызывать функцию калькулятора.
В таких сценариях каждый tool_use_block будет иметь свой уникальный ID. Ваша система должна обработать каждый из этих блоков, выполнить соответствующие функции и затем отправить результаты обратно Claude, используя tool_result_block для каждого из них. Ключевым моментом здесь является точное сопоставление tool_use_id. Эта система идентификаторов гарантирует, что Claude может корректно связать каждый полученный результат с соответствующим запросом, даже если результаты возвращаются в другом порядке из-за асинхронного выполнения функций.
Формирование последующего запроса к Claude
После того как вы выполнили функцию инструмента и подготовили tool_result_block, вам необходимо отправить его обратно Claude. Это делается путем добавления tool_result_block в историю сообщений (messages) и отправки нового запроса к Claude. Важно, чтобы этот последующий запрос включал полную историю разговора до текущего момента, а также новый tool_result_block.
Пример того, как tool_result_block добавляется в историю сообщений:
messages.append({
"role": "user",
"content": [{
"type": "tool_result",
"tool_use_id": response.content[1].id, // ID из оригинального tool_use_block
"content": result, // Результат вашей функции
"is_error": False // Указываем, была ли ошибка
}]
})
Обратите внимание, что role для tool_result устанавливается как "user". Это потому, что вы, как система, сообщаете Claude о результате действия, которое он запросил. Вы выступаете в роли "пользователя", который предоставляет информацию Claude.
Также очень важно включить схему инструмента (tool schema) в ваш последующий запрос, даже если Claude, вероятно, не будет снова вызывать инструменты в этом конкретном шаге. Claude нуждается в схеме инструмента для того, чтобы правильно понимать ссылки на инструменты в истории разговора и поддерживать контекст.
Полный рабочий процесс использования инструментов
Давайте подытожим весь процесс взаимодействия с инструментами Claude:
- Пользователь задает вопрос, который требует использования внешнего инструмента (например, "Какая сейчас дата и время?").
- Claude анализирует запрос и определяет, что ему нужен инструмент. Он отвечает
tool_use_block, указывая, какой инструмент вызвать и с какими параметрами. - Ваша система извлекает параметры из
tool_use_blockи выполняет запрошенную функцию инструмента (например, вызывает вашу функциюget_current_datetime()). - Вы формируете
tool_result_blockс результатом выполнения функции (или информацией об ошибке) и отправляете последующий запрос к Claude. Этот запрос включает полную историю сообщений,tool_result_blockи схему инструмента. - Claude получает результат, обрабатывает его и предоставляет окончательный текстовый ответ пользователю, используя информацию, полученную от инструмента.
Этот цикл обеспечивает бесшовное взаимодействие между Claude и вашими внешними функциями, позволяя Claude расширять свои возможности и предоставлять более полные и точные ответы на широкий круг запросов.