Вы создали агента с рабочим вызовом инструментов (tool calling), но при замене модели на другую — вызовы начинают падать. Определение инструмента не менялось, но формат запроса и ответа изменился, так как каждый провайдер (OpenAI, Anthropic, Google) использует свою собственную структуру для определений инструментов, ответов и кодирования аргументов. Если в вашем стеке нет слоя трансляции между этими форматами, замена модели превращается в написание нового парсинга и появление новых ошибок.
Эта статья сравнивает, как шесть популярных агентных фреймворков определяют схемы инструментов и транслируют их между провайдерами, а также где именно происходит эта трансляция. Мы разберем технические детали, чтобы вы могли выбрать правильный стек для стабильной работы.
01Почему схемы tool-calling различаются у провайдеров
Все провайдеры согласны с базовой концепцией: инструмент имеет имя, описание и схему параметров. Однако "обертка" (wire format) для запроса и ответа у каждого своя, и они не взаимозаменяемы.
- OpenAI (Chat Completions API): Использует массив
tools, где каждый элемент имеетtype: "function"и объектfunctionс JSON Schema. Аргументы в ответе модели приходят как JSON-строка в полеargumentsвнутри массиваtool_calls. - Anthropic (Messages API): Использует более плоскую структуру с
input_schema. Ответ модели содержит блок контентаtool_useс уже распарсенным объектомinput. Цикл завершается сstop_reason: "tool_use". - Google (Gemini API): Определения инструментов вложены в массив
function_declarationsвнутри запросаgenerateContent. Ответ приходит как частьfunctionCallвнутри контента, а не как отдельное верхнеуровневое поле.
02Где должна жить трансляция схем
Существует три уровня, на котором можно решить проблему несовместимости форматов:
- В приложении: Вы вручную пишете маппинг запросов и ответов для каждого провайдера. Это требует постоянной поддержки при изменении API.
- Во фреймворке: Агентный фреймворк или клиент провайдера принимает одно определение инструмента и генерирует формат, нужный конкретному провайдеру.
- На уровне API (Gateway): Шлюз перед каждой моделью принимает один унифицированный формат и транслирует его на лету. Например, OpenRouter принимает стандартный массив
toolsв стиле OpenAI и возвращает стандартный ответtool_callsдля любой модели, поддерживающей вызовы инструментов.
03Разбор фреймворков: LangChain, CrewAI и SDK
LangChain и LangGraph
LangChain скрывает различия wire-форматов от кода приложения. Вы определяете инструмент один раз как Python-функцию с типами, используя декоратор @tool, и привязываете его к модели через bind_tools(). Интеграции чат-моделей LangChain самостоятельно транслируют определение в формат каждого провайдера.
Для работы с OpenRouter существует пакет langchain-openrouter, который позволяет выбирать любую модель через init_chat_model, оставляя трансляцию схем на сторону API OpenRouter. Также поддерживается MCP через MCPAdapter (требует langchain[mcp]>=1.4.0).
CrewAI
CrewAI организован вокруг ролей и задач. Сам фреймворк не реализует провайдер-специфичное форматирование схем. Вся ответственность за обработку схем лежит на клиенте, к которому делегируется вызов.
Для популярных провайдеров (OpenAI, Anthropic, Google, Azure, AWS Bedrock) используются нативные SDK. Для всех остальных провайдеров CrewAI делегирует работу через LiteLLM. Это означает, что если вы используете редкую модель, совместимость схем зависит от качества адаптера LiteLLM, а не самого CrewAI.
OpenAI Agents SDK
Этот SDK заточен под формат OpenAI. Инструменты определяются через @function_tool, а JSON Schema генерируется из сигнатуры функции. SDK предоставляет лучшую поддержку на моделях OpenAI, включая хостинг инструментов на стороне OpenAI.
SDK поддерживает роутинг на другие провайдеры через три пути:
set_default_openai_client: настройка совместимого с OpenAI эндпоинта.ModelProvider: применение кастомного провайдера к конкретному запуску.Agent.model: установка модели для конкретного агента.
Важно: при роутинге через Chat Completions вместо Responses API SDK отбрасывает поля, специфичные для Responses. Документация предупреждает, что некоторые провайдеры не поддерживают структурированный вывод JSON Schema. Чем дальше вы от моделей OpenAI, тем больше вы зависите от слоев совместимости (например, LiteLLM), а не от нативной поддержки.
Claude Agent SDK
Это агентная оболочка для Claude Code. В отличие от базового API Anthropic, SDK запускает цикл выполнения инструментов самостоятельно, управляя контекстом, разрешениями и под-агентами. Пользовательские инструменты определяются через @tool (Python) или tool() (TypeScript). SDK также имеет встроенную поддержку MCP для подключения к серверам инструментов.
04Нормализация на уровне API
Самый надежный способ избежать проблем с миграцией моделей — нормализовать вызовы инструментов на уровне API-шлюза. OpenRouter принимает стандартный массив tools в стиле OpenAI и возвращает стандартный ответ tool_calls для любой модели, поддерживающей вызовы инструментов. Это означает, что переключение модели становится просто изменением строки модели в конфигурации, без переписывания логики парсинга.
05Кому подойдёт / что запустится
- Для максимальной совместимости: Используйте LangChain или OpenRouter API напрямую. Они лучше всего справляются с трансляцией схем между разными провайдерами, позволяя вам писать код один раз и запускать его на OpenAI, Anthropic или Google моделях без изменений.
- Для специфичных задач с Claude: Claude Agent SDK предлагает лучший опыт работы с контекстом и под-агентами, но требует привязки к экосистеме Anthropic. Для других моделей потребуется адаптация.
- Для ролевого моделирования: CrewAI удобен для сложных многоагентных сценариев, но помните, что обработка схем инструментов делегируется LiteLLM или нативным SDK. Тестируйте конкретную модель, которую планируете использовать в продакшене.
- Для нативной интеграции с OpenAI: OpenAI Agents SDK дает лучший доступ к функциям OpenAI (включая Responses API), но при использовании сторонних моделей вы столкнетесь с ограничениями совместимости и необходимостью использовать бета-адаптеры.
Источник: OpenRouter ↗
