Интеграция Anthropic Tool Use Function Calling в приложение

Интеграция Anthropic Tool Use (Function Calling) в приложение

Направления AI-разработки

Часто задаваемые вопросы

Последние работы

  • image_website-b2b-advance_0.webp
    Разработка сайта компании B2B ADVANCE
    1441
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1301
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    998
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1267
  • image_logo-advance_0.webp
    Разработка логотипа компании B2B Advance
    713
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    1006

Интеграция Anthropic Tool Use (Function Calling) в приложение

Представьте: CRM-менеджер тратит 20–30 минут на сбор истории сделок, последних контактов и открытых задач перед встречей. При 50 менеджерах это 1000 часов в месяц, уходящих на рутину. Tool Use от Anthropic превращает Claude в ассистента, который за секунды выполняет поиск в CRM, отправляет email и создаёт задачи — без риска SQL-инъекций или доступа к коду. Клод не выполняет код, а возвращает структурированный JSON с именем инструмента и аргументами. Ваше приложение делает настоящую работу и возвращает результат. Это основа агентов, работающих с реальными данными.

Наши инженеры имеют более 5 лет коммерческой разработки AI-решений и 50+ успешных проектов с RAG и Function Calling. Мы гарантируем production-ready код с логированием, ретраями и мониторингом. Обратитесь к нам — внедрим Tool Use за 3 дня.

Какие проблемы решает Tool Use?

Без Tool Use модель ограничена генерацией текста. Чтобы получить данные из базы, нужно либо дать ей прямой доступ к SQL (опасно), либо вручную парсить её ответы и выполнять код. Tool Use решает обе проблемы:

  • Безопасность: модель возвращает только JSON, приложение контролирует выполнение.
  • Надёжность: JSON Schema задаёт формат аргументов, уменьшая ошибки.
  • Производительность: параллельные вызовы инструментов сокращают время ответа агента в 2–3 раза.

Дополнительно Tool Use снижает число галлюцинаций модели при работе с фактологическими данными — она опирается на реальные результаты выполнения, а не на свой внутренний knowledge cutoff.

Базовый цикл Tool Use

import anthropic import json from typing import Any client = anthropic.Anthropic() # Определение инструментов TOOLS = [ { "name": "search_database", "description": "Поиск клиентов в CRM по параметрам", "input_schema": { "type": "object", "properties": { "query": {"type": "string", "description": "Поисковый запрос"}, "limit": {"type": "integer", "description": "Количество результатов", "default": 10}, "status": { "type": "string", "enum": ["active", "churned", "trial"], "description": "Фильтр по статусу" } }, "required": ["query"] } }, { "name": "send_email", "description": "Отправить email клиенту", "input_schema": { "type": "object", "properties": { "to": {"type": "string"}, "subject": {"type": "string"}, "body": {"type": "string"}, }, "required": ["to", "subject", "body"] } } ] # Диспетчер инструментов def execute_tool(tool_name: str, tool_input: dict) -> Any: if tool_name == "search_database": return search_crm(**tool_input) elif tool_name == "send_email": return send_email_via_smtp(**tool_input) raise ValueError(f"Unknown tool: {tool_name}") def run_agent(user_message: str) -> str: """Полный agentic loop с tool use""" messages = [{"role": "user", "content": user_message}] while True: response = client.messages.create( model="claude-sonnet-4-5", max_tokens=4096, tools=TOOLS, messages=messages, ) # Нет вызовов инструментов — возвращаем финальный ответ if response.stop_reason == "end_turn": for block in response.content: if hasattr(block, "text"): return block.text return "" # Обрабатываем tool_use блоки tool_results = [] for block in response.content: if block.type == "tool_use": print(f"Calling tool: {block.name}({block.input})") result = execute_tool(block.name, block.input) tool_results.append({ "type": "tool_result", "tool_use_id": block.id, "content": json.dumps(result, ensure_ascii=False), }) messages.append({"role": "assistant", "content": response.content}) messages.append({"role": "user", "content": tool_results}) 

Почему стоит использовать параллельные вызовы?

Выполнение нескольких инструментов одновременно ускоряет агента. Когда модель возвращает несколько tool_use блоков в одном ответе, запустите их параллельно через asyncio. Это сокращает общее время до максимума среди всех инструментов. При трёх независимых инструментах со временем выполнения 0.5, 1.2 и 0.8 секунды синхронный подход займёт 2.5 секунды, асинхронный — 1.2 секунды. Выигрыш в 2-3 раза.

import asyncio async def execute_tool_async(tool_name: str, tool_input: dict) -> tuple[str, Any]: """Асинхронное выполнение инструмента""" result = await asyncio.to_thread(execute_tool, tool_name, tool_input) return tool_name, result async def run_agent_async(user_message: str) -> str: messages = [{"role": "user", "content": user_message}] while True: response = client.messages.create( model="claude-sonnet-4-5", max_tokens=4096, tools=TOOLS, messages=messages, ) if response.stop_reason == "end_turn": return next((b.text for b in response.content if hasattr(b, "text")), "") # Выполняем все инструменты параллельно tool_use_blocks = [b for b in response.content if b.type == "tool_use"] results = await asyncio.gather(*[ execute_tool_async(b.name, b.input) for b in tool_use_blocks ]) tool_results = [ { "type": "tool_result", "tool_use_id": block.id, "content": json.dumps(result, ensure_ascii=False), } for block, (_, result) in zip(tool_use_blocks, results) ] messages.append({"role": "assistant", "content": response.content}) messages.append({"role": "user", "content": tool_results}) 

Сравнение синхронного и асинхронного циклов

Характеристика Синхронный цикл Асинхронный цикл
Выполнение инструментов Последовательно один за другим Параллельно, все сразу
Задержка при N инструментах Сумма времён N Максимальное время одного инструмента
Сложность кода Низкая Средняя (asyncio)
Когда использовать Инструменты зависят друг от друга Инструменты независимы

Как принудительно вызвать инструмент?

# tool_choice="required" — Claude обязан вызвать хотя бы один инструмент # tool_choice={"type": "tool", "name": "..."} — вызвать конкретный response = client.messages.create( model="claude-sonnet-4-5", max_tokens=1024, tools=TOOLS, tool_choice={"type": "tool", "name": "search_database"}, messages=[{"role": "user", "content": "Найди клиентов с trial статусом"}], ) 

Принудительный вызов полезен, когда нужно гарантировать выполнение критичного действия — например, создать задачу или отправить уведомление. При этом модель может вернуть результат вызова без дополнительного текста.

Как обрабатывать ошибки инструментов?

Ошибки — неотъемлемая часть продакшена. Никогда не завершайте диалог при сбое выполнения. Вместо этого передайте описание ошибки обратно модели: она сможет выбрать другой инструмент или запросить уточнение. Пошаговый подход:

  1. Оберните вызов инструмента в try-except.
  2. При успехе добавьте результат в tool_results с type: "tool_result".
  3. При исключении добавьте блок с is_error: True и текстом ошибки.
  4. Отправьте tool_results модели и продолжите цикл.
# Передавайте ошибки обратно в модель — она адаптирует поведение try: result = execute_tool(block.name, block.input) tool_results.append({ "type": "tool_result", "tool_use_id": block.id, "content": json.dumps(result), }) except Exception as e: tool_results.append({ "type": "tool_result", "tool_use_id": block.id, "content": f"Error: {str(e)}", "is_error": True, # Модель знает об ошибке и может скорректировать }) 

Пример полного ответа с ошибкой:

{ "type": "tool_result", "tool_use_id": "toolu_abc123", "content": "Error: Connection timeout to database", "is_error": true } 

Модель Claude, получив такой результат, может предложить повторить попытку или использовать другой инструмент.

Практический кейс: CRM-ассистент

Из нашей практики: один из клиентов — крупная розничная сеть с отделом продаж из 50 менеджеров. На подготовку к встрече с клиентом уходило 20–30 минут: нужно было собрать историю сделок, последние контакты, открытые задачи. Мы развернули ассистента на Claude с инструментами:

  • get_customer_info — профиль клиента
  • get_deal_history — история сделок
  • get_recent_activities — последние действия
  • create_task — создать задачу
  • get_calendar — свободные слоты

Результат: подготовка к встрече — 2 минуты через диалог с ассистентом. Экономия времени составила 28 минут на встречу. При средней зарплате менеджера $30/час это даёт экономию $14 за встречу, а при 10 встречах в день — $140 ежедневно. Окупаемость проекта — 3 месяца за счёт экономии времени senior-менеджеров. Дополнительно снизилось число ошибок ввода данных на 75% — инструменты работают строго по схемам.

Что входит в работу

Этап Содержание Ориентировочный срок
Анализ Определение схем инструментов под бизнес-логику, согласование JSON Schema 1 день
Разработка Реализация диспетчера инструментов с типизацией, настройка параллельного выполнения через asyncio 2-3 дня
Тестирование Обработка ошибок и ретраи с передачей фидбека модели, unit-тесты 1 день
Документация Описание развертывания и поддержки, обучение команды (до 3 часов) 1 день

Сроки

  • Базовый tool use loop с 2–3 инструментами: 2–3 дня
  • Параллельные вызовы + обработка ошибок: 1–2 дня
  • Production-ready с логированием и retry: 1 неделя

Получите консультацию по интеграции — мы оценим ваш проект за 1 день и предложим оптимальную архитектуру. Наши сертифицированные ML-инженеры имеют опыт работы с OpenAI, Claude, Gemini и open-source моделями. Пишите — обсудим ваш сценарий.