Создание мультиагентной системы с CrewAI становится интереснее, когда разные агенты могут использовать разные модели.
Исследователю может быть полезна быстрая и экономичная модель, аналитику — более сильная в рассуждениях, а автору — модель, оптимизированная для высококачественной длинной генерации. Традиционно подключение этих агентов к разным провайдерам означает управление отдельными учетными данными API, конечными точками, SDK, системами биллинга и конфигурацией, зависящей от провайдера.
Более чистая архитектура — позволить CrewAI управлять агентами и рабочим процессом, а CometAPI — доступом к моделям.
CometAPI предоставляет совместимую с OpenAI конечную точку по адресу https://api.cometapi.com/v1, поэтому приложения могут направлять запросы к моделям от нескольких провайдеров через общий интерфейс API. В текущей документации по быстрому старту также поддерживается использование стандартного Python SDK OpenAI при изменении ключа API и базового URL.
В этом руководстве вы построите рабочий процесс CrewAI из трех агентов с:
- Gemini 3.7 Flash для исследований
- Claude Opus 5 для анализа
- GPT-5.6 для финального написания
- Один API-ключ CometAPI
- Один базовый URL API
- Конфигурация модели на уровне агента
- Ограниченный фолбэк для временных сбоев
- Чекпойнтинг CrewAI для восстановления в проде
- Отслеживание использования токенов и исполнения
- Серверная валидация моделей
Важная архитектурная граница проста:
CrewAI управляет оркестрацией агентов. CometAPI управляет доступом к моделям. Маршрутизация определяется идентификаторами моделей.
Что такое маршрутизация моделей в мультиагентной CrewAI?
CrewAI — это Python-фреймворк для создания агентов, задач, команд и мультиагентных рабочих процессов. Каждый агент может иметь собственную конфигурацию LLM, в то время как Crew координирует, как эти агенты выполняют задачи и обмениваются контекстом.
Текущая конфигурация LLM в CrewAI поддерживает явные параметры model, api_key и base_url, включая пользовательские конечные точки, совместимые с OpenAI.
Это делает многомодельную архитектуру прямолинейной:
CometAPI │ https://api.cometapi.com/v1 │ ┌───────────────────┼───────────────────┐ │ │ │ Researcher Analyst Writer │ │ │ Gemini 3.7 Flash Claude Opus 5 GPT-5.6
Агенты остаются логически раздельными, но доступ к моделям централизован.
Это не означает, что все модели взаимозаменяемы. Совместимый с OpenAI API предоставляет общий интерфейс запросов; он не гарантирует одинаковые ограничения контекста, поддержку инструментов, настройки рассуждений, поведение вывода, задержку или цены.
Это различие важно при проектировании продакшен-маршрутизации.
Зачем использовать CometAPI с CrewAI?
Главное преимущество не в том, что CrewAI внезапно становится мультипровайдерным фреймворком. CrewAI уже поддерживает несколько провайдеров LLM.
Преимущество в том, что доступ к моделям можно консолидировать за одним слоем API.
Без единого слоя API рабочий процесс из трех агентов может выглядеть так:
| Агент | Провайдер | Учетные данные | Интеграция |
|---|---|---|---|
| Researcher | ключ API Google | Зависит от провайдера | |
| Analyst | Anthropic | ключ API Anthropic | Зависит от провайдера |
| Writer | OpenAI | ключ API OpenAI | Зависит от провайдера |
С CometAPI:
| Агент | Модель | Учетные данные | Конечная точка |
|---|---|---|---|
| Researcher | Gemini 3.7 Flash | ключ CometAPI | CometAPI |
| Analyst | Claude Opus 5 | ключ CometAPI | CometAPI |
| Writer | GPT-5.6 | ключ CometAPI | CometAPI |
Текущая документация по быстрому старту CometAPI описывает свою конечную точку как заменяющую базовый URL OpenAI API и перечисляет модели от нескольких провайдеров через один и тот же сервис.
Это дает приложению полезное разделение:
CrewAI
- Определяет роли агентов
- Определяет задачи
- Передает контекст
- Контролирует исполнение
- Управляет итерациями агентов
- Обрабатывает оркестрацию на уровне команды
CometAPI
- Предоставляет общий слой доступа к моделям
- Централизует аутентификацию API
- Даёт маршрутизацию по идентификаторам моделей
- Предоставляет одноуровневую конечную точку API
- Дает централизованную видимость использования и биллинга
Что построит этот рабочий процесс CrewAI?
Пример создает трех последовательных агентов.
| Агент CrewAI | Основная модель | Фолбэк | Роль |
|---|---|---|---|
| Исследователь рынка | gemini-3.7-flash | gpt-5.6 | Сбор фактов и исследований |
| Продуктовый аналитик | claude-opus-5 | gpt-5.6 | Синтез доказательств и компромиссов |
| Технический автор | gpt-5.6 | gemini-3.7-flash | Подготовка финальной служебной записки |
Это пример политики маршрутизации, а не рейтинг производительности.
Правильная модель для вашего агента зависит от:
- сложности задачи
- требуемой длины контекста
- использования инструментов
- требований к структурированному выводу
- задержки
- надежности
- стоимости токенов
- качества вывода
- результатов оценки, специфичных для приложения
Полезное правило:
Выбирайте модель под задачу агента, а не просто по провайдеру.
Какую модель должен использовать каждый агент CrewAI?
В этом примере назначение моделей следует простой стратегии соотношения стоимости и возможностей.
Исследователь: Gemini 3.7 Flash
Исследование часто включает обработку относительно больших объемов информации и выдачу компактного промежуточного результата.
Быстрая модель может быть полезна для высокообъемных исследовательских задач.
"researcher": "gemini-3.7-flash"
Аналитик: Claude Opus 5
У аналитика более узкая, но требующая рассуждений роль. Он получает результаты исследования и превращает их в рекомендацию.
"analyst": "claude-opus-5"
Автор: GPT-5.6
Финальный агент превращает исследование и анализ в техническую служебную записку для разработчиков.
"writer": "gpt-5.6"
Важно не конкретно это назначение трех моделей. Ваше приложение должно оценить кандидатные модели на типичных задачах перед закреплением политики маршрутизации.
Что нужно перед началом?
Нужно:
- Python 3.10+
- CrewAI
- Совместимость с Python SDK OpenAI
python-dotenv- Ключ API CometAPI
- Идентификаторы моделей, которые вы планируете использовать
Текущая интеграция CometAPI для Python поддерживает API, совместимый с OpenAI, а официальный пакет CometAPI для Python использует COMETAPI_KEY и COMETAPI_BASE_URL как параметры конфигурации из окружения.
Стандартная конечная точка:
https://api.cometapi.com/v1
Перед деплоем убедитесь, что выбранные вами идентификаторы моделей доступны и поддерживают конечную точку и параметры, необходимые вашему рабочему процессу CrewAI. Каталоги моделей и цены могут меняться.
Как установить CrewAI и зависимости?
Создайте новое окружение Python:
python -m venv .venv
Активируйте его:
source .venv/bin/activate
В Windows:
.venv\Scripts\Activate.ps1
Затем установите зависимости:
pip install "crewai[openai]" openai python-dotenv
Явное использование openai намеренно, поскольку реализация фолбэка ниже напрямую импортирует классы исключений SDK OpenAI.
В проде закрепляйте версии, которые вы тестируете, а не надейтесь на постоянно «последние».
Например:
crewai==YOUR_TESTED_VERSIONopenai==YOUR_TESTED_VERSIONpython-dotenv==YOUR_TESTED_VERSION
Слой LLM в CrewAI активно развивается, поэтому точный конструктор и конфигурация провайдера должны проверяться относительно версии CrewAI, используемой вашим приложением. Текущая документация CrewAI поддерживает настройку LLM с пользовательским base_url и ключом API.
Как настроить ключ API CometAPI?
Создайте файл .env:
COMETAPI_KEY=your_cometapi_keyCOMETAPI_BASE_URL=https://api.cometapi.com/v1
Загрузите эти значения в Python:
import osfrom dotenv import load_dotenvload_dotenv()COMETAPI_KEY = os.environ["COMETAPI_KEY"]COMETAPI_BASE_URL = os.getenv( "COMETAPI_BASE_URL", "https://api.cometapi.com/v1",)
Никогда не коммитьте .env в Git.
Добавьте его в .gitignore:
.env.venv/__pycache__/
Ключ API должен оставаться серверным секретом. Текущие рекомендации по быстрому старту CometAPI также советуют хранить ключ в переменных окружения, а не в исходниках.
Как подключить CrewAI к CometAPI?
Объект LLM в CrewAI может получать имя модели, ключ API и пользовательский базовый URL.
Создайте вспомогательную функцию:
from crewai import LLMdef cometapi_llm(model_id: str) -> LLM: return LLM( model=model_id, base_url=COMETAPI_BASE_URL, api_key=COMETAPI_KEY, timeout=60.0, max_retries=0, )
Это предпочтительнее, чем дублировать одну и ту же конфигурацию в каждом агенте.
Теперь каждому агенту нужен только идентификатор модели:
research_llm = cometapi_llm("gemini-3.7-flash")analysis_llm = cometapi_llm("claude-opus-5")writing_llm = cometapi_llm("gpt-5.6")
Зачем устанавливать max_retries=0?
Причина — контроль фолбэка.
Если клиент LLM автоматически повторяет попытки, а ваше приложение тоже реализует фолбэк, один сбой может превратиться в несколько скрытых запросов до того, как логика фолбэка сработает.
Для учебного примера с явной маршрутизацией чище позволить приложению решать, когда повторять или переключать модель.
Как определить политику маршрутизации моделей?
Держите маршрутизацию вне промптов:
PRIMARY_MODELS = { "researcher": "gemini-3.7-flash", "analyst": "claude-opus-5", "writer": "gpt-5.6",}FALLBACK_MODELS = { "researcher": "gpt-5.6", "analyst": "gpt-5.6", "writer": "gemini-3.7-flash",}
Это создает четкую конфигурационную границу.
Позже вы сможете перенести ту же карту в:
- конфигурацию окружения
- YAML
- JSON
- базу данных
- фича-флаги
- внутренний сервис маршрутизации моделей
без переписывания промптов агентов.
Как собрать трех агентов CrewAI?
Создайте по одному объекту LLM на агента.
from crewai import Agentdef build_agents(model_map: dict[str, str]): researcher = Agent( role="Исследователь рынка", goal="Соберите факты, необходимые для ответа на тему", backstory=( "Вы создаете краткие исследовательские сводки с указанием источников " "и четко отделяете факты от допущений." ), llm=cometapi_llm(model_map["researcher"]), max_iter=3, allow_delegation=False, ) analyst = Agent( role="Продуктовый аналитик", goal="Преобразуйте исследование в обоснованную рекомендацию", backstory=( "Вы выявляете доказательства, допущения, риски " "и компромиссы перед формированием рекомендаций." ), llm=cometapi_llm(model_map["analyst"]), max_iter=3, allow_delegation=False, ) writer = Agent( role="Технический автор", goal="Подготовьте краткую техническую служебную записку с решением", backstory=( "Вы пишете ясные технические объяснения " "без лишнего маркетингового языка." ), llm=cometapi_llm(model_map["writer"]), max_iter=3, allow_delegation=False, ) return researcher, analyst, writer
Назначение моделей теперь полностью независимо от определения роли агента.
Это и делает маршрутизацию моделей практичной.
Как связать агентов последовательными задачами?
Создайте три задачи:
from crewai import Taskdef build_tasks(researcher, analyst, writer): research_task = Task( description=( "Исследуйте тему: {topic}. " "Верните ключевые факты, неопределенности " "и релевантные источники, которые должен учесть аналитик." ), expected_output=( "Компактная исследовательская сводка, содержащая факты, " "неопределенности и ссылки на источники." ), agent=researcher, ) analysis_task = Task( description=( "Используя исследовательскую сводку, проанализируйте {topic}. " "Определите наиболее сильный вывод и объясните " "основные компромиссы." ), expected_output=( "Черновик решения с доказательствами, " "допущениями, рисками и компромиссами." ), agent=analyst, context=[research_task], ) writing_task = Task( description=( "Напишите краткую техническую служебную записку о {topic}. " "Сформулируйте рекомендацию в начале и сохраните " "важные оговорки." ), expected_output="Полированная техническая служебная записка в Markdown.", agent=writer, context=[research_task, analysis_task], ) return research_task, analysis_task, writing_task
Цепочка зависимостей:
Тема ↓Исследование ↓Анализ ↓Финальная записка
Аналитик получает вывод задачи исследования, а автор — и исследование, и анализ.
Как собрать Crew?
Объедините агентов и задачи:
from crewai import Crew, Processdef build_crew(model_map: dict[str, str]) -> Crew: researcher, analyst, writer = build_agents(model_map) research_task, analysis_task, writing_task = build_tasks( researcher, analyst, writer, ) return Crew( agents=[researcher, analyst, writer], tasks=[ research_task, analysis_task, writing_task, ], process=Process.sequential, verbose=True, )
Теперь маршрутизация моделей полностью управляется конфигурацией.
Замена:
"researcher": "gemini-3.7-flash"
на другую поддерживаемую модель не требует изменения промпта или определения задачи исследования.
Как должен работать фолбэк моделей в CrewAI?
Здесь продакшен-реализация требует больше внимания.
Распространенная ошибка:
Любая ошибка ↓Переключить модель
Это слишком агрессивно.
Например, следующие ошибки обычно не должны запускать фолбэк модели:
400 Bad Request401 Unauthorized403 Forbidden404 Not Found422 Validation Error
Переключение моделей не исправит неверный ключ API или некорректный запрос.
Фолбэк более уместен для временных сбоев, таких как:
408 Request Timeout429 Rate Limit500 Internal Server Error502 Bad Gateway503 Service Unavailable504 Gateway TimeoutОшибка соединенияТаймаут
Политика фолбэка должна быть следующей:
Повторяйте или переключайте модели только при ограниченных, временных сбоях и только когда фолбэк-модель поддерживает тот же контракт запроса.
Как обнаружить ошибки, подходящие для ретрая?
Можно использовать классы ошибок SDK OpenAI:
from collections.abc import Iteratorfrom openai import ( APIConnectionError, APIStatusError, APITimeoutError,)def exception_chain(error: BaseException) -> Iterator[BaseException]: current: BaseException | None = error seen: set[int] = set() while current is not None and id(current) not in seen: seen.add(id(current)) yield current current = ( current.__cause__ or current.__context__ )def should_fallback(error: BaseException) -> bool: for current in exception_chain(error): if isinstance( current, (APIConnectionError, APITimeoutError), ): return True if isinstance(current, APIStatusError): return ( current.status_code in {408, 429} or current.status_code >= 500 ) return False
Здесь намеренно исключены ошибки конфигурации на уровне 400, кроме 408 и 429.
Повторять весь Crew или только упавшего агента?
Есть две разные стратегии фолбэка.
Фолбэк на уровне Crew
Самая простая реализация:
Запуск crew ↓сбой ↓смена маршрута ↓повтор crew
Это легко понять, но может повторить уже завершенные задачи.
Например:
Исследование → завершеноАнализ → завершенАвтор → упал
Повтор kickoff() может выполнить:
Исследование → сноваАнализ → сноваАвтор → фолбэк
Это увеличивает:
- использование токенов
- задержку
- стоимость API
- потенциальные побочные эффекты
Восстановление на уровне задачи
В продакшене следует вместо этого чекпойнтить завершенную работу:
Исследование ↓чекпойнт ↓Анализ ↓чекпойнт ↓Автор падает ↓ретрай автора с фолбэком
CrewAI сейчас предоставляет чекпойнтинг, который сохраняет состояние выполнения и позволяет возобновить запуск после сбоя. Задокументированное поведение чекпойнтов пропускает завершенные задачи и продолжает работу по сохраненному состоянию.
Это лучшая архитектура для дорогих или побочно действующих процессов.
Как добавить чекпойнтинг CrewAI?
Для продакшена включите чекпойнтинг у команды:
crew = Crew( agents=[researcher, analyst, writer], tasks=[ research_task, analysis_task, writing_task, ], process=Process.sequential, checkpoint=True, verbose=True,)
Система чекпойнтов CrewAI может сохранять состояние выполнения после завершения задачи и восстанавливать команду из чекпойнта.
Например, восстановленный запуск может использовать:
from crewai import CheckpointConfigresult = crew.kickoff( from_checkpoint=CheckpointConfig( restore_from="./.checkpoints/checkpoint.json", ))
Точная конфигурация чекпойнтов должна соответствовать версии CrewAI, используемой в вашем проекте.
Важный архитектурный принцип:
Сначала чекпойнты, потом фолбэк.
Это предотвращает повторный запуск дорогой завершенной работы из-за временного сбоя модели.
Как реализовать простой ограниченный фолбэк?
Для учебного примера можно показать простой фолбэк на уровне всей команды.
def run_with_fallback(topic: str): routes = [ PRIMARY_MODELS, { **PRIMARY_MODELS, "writer": FALLBACK_MODELS["writer"], }, { **PRIMARY_MODELS, "analyst": FALLBACK_MODELS["analyst"], "writer": FALLBACK_MODELS["writer"], }, ] last_error = None for attempt, model_map in enumerate(routes, start=1): try: crew = build_crew(model_map) result = crew.kickoff( inputs={"topic": topic} ) return result, model_map except Exception as error: last_error = error if not should_fallback(error): raise if attempt == len(routes): raise print( f"Временный сбой при попытке {attempt}. " f"Пробуем ограниченный маршрут фолбэка.", flush=True, ) raise RuntimeError( "Выполнение команды завершилось неудачей после всех маршрутов фолбэка." ) from last_error
Обратите внимание на важное различие:
Здесь не утверждается, что сбойный агент был идентифицирован.
Это ограниченная стратегия фолбэка на уровне всей команды.
Для небольших без状態ных процессов это может быть приемлемо. Для продакшена с дорогими исследованиями, инструментами или побочными эффектами используйте восстановление на базе чекпойнтов.
Как отслеживать использование токенов в CrewAI?
Отслеживание использования должно быть частью уровня маршрутизации, а не постфактум.
В конце запуска проверьте результат CrewAI:
result, selected_models = run_with_fallback(topic)print("Выбранные модели:")print(selected_models)print("Финальный результат:")print(result.raw)print("Использование:")print(result.token_usage)
Точные поля использования зависят от версии CrewAI и пути выполнения, поэтому рассматривайте возвращаемый объект результата как источник истины для используемой версии.
Запись об использовании в продакшене желательно должна содержать:
job_idagentmodelinput_tokensoutput_tokenstotal_tokenslatency_msfallback_usedfallback_reasonstatuscreated_at
Это позволяет ответить на вопросы:
Какой агент потребляет большую часть бюджета?
Как часто аналитик уходит в фолбэк?
Какая модель имеет наибольшую задержку?
Сколько стоит каждый рабочий процесс?
Как контролировать стоимость на уровне агента?
Многомодельная маршрутизация наиболее полезна, когда отражает реальные различия нагрузки.
Например:
Исследователь→ большой объем→ более дешевая модельАналитик→ малый объем→ более сильная для рассуждений модельАвтор→ средний объем→ универсальная модель прод-уровня
Вы также можете ограничить стоимость через конфигурацию агента.
Например:
max_iter=3
ограничивает итерационный цикл агента. Это не следует трактовать как жесткий лимит ровно трех API-вызовов или трех бюджетов токенов.
Дополнительные меры:
- ограничение контекста задачи
- суммирование промежуточных результатов
- кэширование повторяемых исследований
- ограничение максимального размера входа
- ограничение максимума выходных токенов, где поддерживается
- ограничение вызовов инструментов
- установка бюджетов на пользователя
- установка бюджетов на рабочий процесс
- отслеживание частоты фолбэков
Как валидировать модели перед деплоем?
Не хардкодьте идентификаторы моделей навсегда.
Модель может стать:
- недоступной
- переименованной
- устаревшей
- ограниченной
- измененной по возможностям
- измененной по цене
- несовместимой с параметром, который использует ваше приложение
CometAPI предоставляет конечную точку каталога моделей, к которой можно обращаться программно, а его публичный каталог моделей можно использовать для ручного поиска.
Проверка перед деплоем может выглядеть так:
curl -s \ https://api.cometapi.com/api/models \ -H "Authorization: Bearer $COMETAPI_KEY"
Затем проверьте, что ваши настроенные идентификаторы моделей существуют до деплоя.
Например, ваш CI может верифицировать:
gemini-3.7-flash → availableclaude-opus-5 → availablegpt-5.6 → available
Не подменяйте проверки доступности тестированием приложения. Наличие модели в каталоге не означает, что каждый параметр, инструмент или формат вывода, используемый вашим агентом CrewAI, поддерживается.
Как выглядит полный пример CrewAI?
Ниже приведена консолидированная реализация:
import jsonimport osimport sysfrom collections.abc import Iteratorfrom dotenv import load_dotenvfrom openai import ( APIConnectionError, APIStatusError, APITimeoutError,)from crewai import Agent, Crew, LLM, Process, Taskload_dotenv()COMETAPI_KEY = os.environ["COMETAPI_KEY"]COMETAPI_BASE_URL = os.getenv( "COMETAPI_BASE_URL", "https://api.cometapi.com/v1",)PRIMARY_MODELS = { "researcher": "gemini-3.7-flash", "analyst": "claude-opus-5", "writer": "gpt-5.6",}FALLBACK_MODELS = { "researcher": "gpt-5.6", "analyst": "gpt-5.6", "writer": "gemini-3.7-flash",}def cometapi_llm(model_id: str) -> LLM: return LLM( model=model_id, base_url=COMETAPI_BASE_URL, api_key=COMETAPI_KEY, timeout=60.0, max_retries=0, )def build_crew(model_map: dict[str, str]) -> Crew: researcher = Agent( role="Исследователь рынка", goal="Соберите факты, необходимые для ответа на тему", backstory=( "Вы создаете краткие исследовательские сводки с указанием источников " "и отличаете факты от допущений." ), llm=cometapi_llm(model_map["researcher"]), max_iter=3, allow_delegation=False, ) analyst = Agent( role="Продуктовый аналитик", goal="Преобразуйте исследование в обоснованную рекомендацию", backstory=( "Вы оцениваете доказательства, допущения, риски " "и компромиссы." ), llm=cometapi_llm(model_map["analyst"]), max_iter=3, allow_delegation=False, ) writer = Agent( role="Технический автор", goal="Подготовьте краткую техническую служебную записку с решением", backstory=( "Вы пишете ясные технические объяснения " "без ненужного хайпа." ), llm=cometapi_llm(model_map["writer"]), max_iter=3, allow_delegation=False, ) research_task = Task( description=( "Исследуйте тему: {topic}. " "Верните ключевые факты, неопределенности " "и релевантные источники." ), expected_output=( "Краткая исследовательская сводка с фактами " "и открытыми вопросами." ), agent=researcher, ) analysis_task = Task( description=( "Используя исследовательскую сводку, проанализируйте {topic}. " "Определите наиболее сильный вывод и " "объясните основные компромиссы." ), expected_output=( "Черновик решения с доказательствами, " "допущениями, рисками и компромиссами." ), agent=analyst, context=[research_task], ) writing_task = Task( description=( "Напишите краткую техническую служебную записку " "о {topic}. Сформулируйте рекомендацию в начале " "и сохраните важные оговорки." ), expected_output=( "Полированная техническая служебная записка в Markdown." ), agent=writer, context=[ research_task, analysis_task, ], ) return Crew( agents=[ researcher, analyst, writer, ], tasks=[ research_task, analysis_task, writing_task, ], process=Process.sequential, verbose=True, )def exception_chain( error: BaseException,) -> Iterator[BaseException]: current = error seen: set[int] = set() while current is not None and id(current) not in seen: seen.add(id(current)) yield current current = ( current.__cause__ or current.__context__ )def should_fallback(error: BaseException) -> bool: for current in exception_chain(error): if isinstance( current, ( APIConnectionError, APITimeoutError, ), ): return True if isinstance(current, APIStatusError): return ( current.status_code in {408, 429} or current.status_code >= 500 ) return Falsedef run_with_fallback(topic: str): routes = [ PRIMARY_MODELS, { **PRIMARY_MODELS, "writer": FALLBACK_MODELS["writer"], }, { **PRIMARY_MODELS, "analyst": FALLBACK_MODELS["analyst"], "writer": FALLBACK_MODELS["writer"], }, ] last_error = None for attempt, model_map in enumerate( routes, start=1, ): try: crew = build_crew(model_map) result = crew.kickoff( inputs={ "topic": topic, } ) return result, model_map except Exception as error: last_error = error if not should_fallback(error): raise if attempt == len(routes): raise print( f"Временный сбой при попытке " f"{attempt}; пробуем фолбэк.", file=sys.stderr, ) raise RuntimeError( "Ни один маршрут моделей не завершил команду." ) from last_errordef main(): topic = ( sys.argv[1] if len(sys.argv) > 1 else ( "Стоит ли небольшому SaaS добавить " "AI‑генерируемые итоги встреч?" ) ) result, selected_models = ( run_with_fallback(topic) ) output = { "selected_models": selected_models, "raw": result.raw, "tasks_output": [ task.raw for task in result.tasks_output ], "token_usage": str( result.token_usage ), } print( json.dumps( output, indent=2, default=str, ) )if __name__ == "__main__": main()
Важное улучшение по сравнению с оригинальной версией в том, что код больше не создает ложное впечатление, будто исключение идентифицирует именно упавшего агента.
Это явно ограниченная реализация фолбэка на уровне всей команды.
В продакшене объедините ту же политику маршрутизации с чекпойнтингом CrewAI.
Как запустить рабочий процесс CrewAI?
Сохраните файл как:
crewai_multi_model.py
Затем запустите:
python crewai_multi_model.py \ "Стоит ли небольшому SaaS добавить AI‑генерируемые итоги встреч?"
Успешный ответ будет содержать информацию, похожую на:
{ "selected_models": { "researcher": "gemini-3.7-flash", "analyst": "claude-opus-5", "writer": "gpt-5.6" }, "raw": "<финальная служебная записка>", "tasks_output": [ "<результат исследования>", "<вывод анализа>", "<результат написания>" ], "token_usage": "<информация об использовании>"}
Точный ответ и значения использования зависят от входных данных, поведения модели, версии CrewAI и пути выполнения.
Если из-за повторяемой ошибки активируется маршрут фолбэка, объект selected_models покажет маршрут, использованный для данного запуска команды.
Как проектировать продакшен-маршрутизацию моделей?
Политика маршрутизации в продакшене должна учитывать больше, чем качество модели.
Полезная функция принятия решения:
Оценка модели =Качество+ Надежность+ Соответствие контексту+ Совместимость с инструментами- Стоимость- Задержка
Это можно реализовать на нескольких уровнях.
Маршрутизация по стоимости
Простая задача → экономичная модельСложная задача → премиальная модель
Маршрутизация по задержке
Интерактивный запрос → быстрая модельФоновый процесс → более качественная модель
Маршрутизация по надежности
Основная модель ↓временный сбой ↓фолбэк-модель
Маршрутизация по задаче
Исследование → Модель AАнализ → Модель BНаписание → Модель CКод → Модель D
Последний подход особенно естественен для CrewAI, поскольку фреймворк уже дает каждому агенту отдельную роль.
Как сделать фолбэк безопасным?
Надежная система фолбэка должна соблюдать четыре правила.
Не делайте фолбэк при ошибках аутентификации
Если ключ API недействителен:
401
смена модели проблему не решит.
Не делайте фолбэк при некорректных запросах
Если запрос некорректен:
400422
исправьте запрос.
Не делайте фолбэк бесконечно
Задайте жесткий лимит:
MAX_FALLBACK_ATTEMPTS = 2
Система фолбэка без лимита может превратиться в дорогую петлю повторов.
Делайте фолбэк-модели совместимыми с запросом
Фолбэк-модель должна поддерживать функции, требуемые вашим агентом.
Например, если первичному агенту нужен конкретный инструмент или поведение структурированного вывода, фолбэк должен поддерживать тот же контракт.
Совместимость с OpenAI не означает совместимость по возможностям.
Наиболее распространенные ошибки CrewAI + CometAPI
| Симптом | Вероятная причина | Исправление |
|---|---|---|
| 401 Unauthorized | Неверный или отсутствующий ключ | Проверьте COMETAPI_KEY; не делайте фолбэк |
| 400 Bad Request | Некорректные параметры запроса | Исправьте запрос |
| 404 Model Not Found | Устаревший ID модели | Проверьте актуальный каталог моделей |
| 408 Timeout | Временное истечение времени | Повторите в рамках ограниченной политики |
| 429 Rate Limited | Слишком много запросов | Сделайте бэкофф и повторите |
| 500–504 | Временный сбой сервера/шлюза | Используйте ограниченный фолбэк |
| Агент бесконечно ретраит | Скрытые ретраи SDK | Контролируйте max_retries |
| Завершенные задачи запускаются снова | Повтор всего crew | Используйте восстановление с чекпойнтов |
| Другая модель ведет себя иначе | Различаются возможности моделей | Тестируйте каждую модель отдельно |
| Неожиданная ошибка конструктора CrewAI | Несоответствие версии | Зафиксируйте и проверьте версию CrewAI |
Как отделить ошибки CrewAI от ошибок модели?
Это важно при отладке.
Ошибки конфигурации
Отсутствует ключ APIНедействительный ID моделиНеверный base URLНеподдерживаемый параметр
Они должны быстро падать.
Ошибки провайдера/API
401403404429500503
Для них нужен разный хендлинг в зависимости от статуса.
Ошибки приложения
Неверный вывод агентаИнструмент вернул некорректные данныеНе хватает контекста задачиСбой побочного эффекта
Они не обязательно решаются сменой модели.
Зрелая агентная система должна иметь отдельную обработку для:
конфигурации ↓транспорта API ↓исполнения модели ↓логики агента ↓выполнения инструментов ↓побочных эффектов приложения
Это намного безопаснее, чем общий:
except Exception: use_fallback()
Как защитить внешние побочные эффекты?
Фолбэк сильно усложняется, когда агенты делают больше, чем просто генерируют текст.
Например, представьте агента, который:
- создает запись в БД
- отправляет письмо
- вызывает внешний API
- обновляет CRM
Если модель уходит в таймаут после успешного внешнего действия, повторный запуск всей команды может продублировать действие.
Используйте:
- ключи идемпотентности
- чекпойнты задач
- границы транзакций
- ID исполнения
- устойчивое состояние задач
- явное подтверждение побочных эффектов
Например:
job_id = crew_run_123task_id = writer_456
Сохраняйте эти идентификаторы вместе с внешними операциями, чтобы ретрай мог определить, было ли действие уже выполнено.
Как мониторить мульти-модельные рабочие процессы CrewAI?
Минимум логируйте:
workflow_idagentmodeltaskstart_timeend_timelatencystatusfallback_usedfallback_reasoninput_tokensoutput_tokenstotal_tokens
Не логируйте:
ключи APIприватные учетные данныеполностью чувствительные промптыперсональные данныебез редактирования вывод модели
Для каждой модели мониторьте:
Надежность
доля успеховдоля таймаутовдоля 5xxчастота фолбэков
Производительность
p50 задержкап95 задержкап99 задержка
Стоимость
входные токенывыходные токеныстоимость на задачустоимость завершенного процесса
Качество
доля успешных задачоценка человекавалидность структурированного выводавыражение инструментов
Это превращает маршрутизацию моделей из жестко прописанного предпочтения в наблюдаемую инженерную систему.
Как выбрать между прямыми API провайдеров и CometAPI?
Выбор зависит от вашей архитектуры.
| Архитектура | Учетные данные | Переключение моделей | Интеграция с провайдерами | Централизованная маршрутизация |
|---|---|---|---|---|
| Прямые API провайдеров | Несколько | Кастомное | Высокая | Нет |
| Один провайдер | Один | Ограниченное | Низкая | Ограниченная |
| CrewAI + CometAPI | Один ключ CometAPI | По ID модели | Ниже | Да |
Если вашему приложению нужна только одна модель и ее нативные возможности, прямая интеграция может быть вполне разумной.
Если вашему приложению CrewAI нужны модели от нескольких провайдеров и вы хотите один слой доступа, CometAPI становится более привлекательным.
Важно, что CometAPI не заменяет CrewAI.
Вместо этого:
CrewAIОркестрация агентов ↓CometAPIДоступ к моделям ↓Несколько моделей
Каждый слой отвечает за свое.
Как масштабируется эта архитектура?
После отделения политики маршрутизации от определений агентов добавление новой модели не требует перестройки всего приложения.
Например:
PRIMARY_MODELS = { "researcher": "gemini-3.7-flash", "analyst": "claude-opus-5", "writer": "gpt-5.6", "coder": "YOUR_CODE_MODEL",}
Та же архитектура сможет поддерживать:
Агент-исследовательАгент-аналитикАгент-кодерАгент-ревьюерАгент-написанияАгент-фактчекер
Каждый агент может иметь свою модель, разделяя один и тот же слой доступа CometAPI.
Следующий шаг — сделать маршрутизацию динамичной.
Вместо:
"analyst": "claude-opus-5"
вы со временем можете использовать:
select_model( task="analysis", budget=budget, latency_target=latency_target,)
Система маршрутизации сможет выбирать из одобренных моделей на основе требований приложения.
Какая лучшая продакшен-архитектура для CrewAI + CometAPI?
Для небольшого процесса:
Ввод пользователя ↓CrewAI ↓CometAPI ↓Модели
Для продакшена:
┌───────────────┐ │ Каталог моделей │ └───────┬───────┘ │ ▼Пользователь → CrewAI → Политика маршрутизации → CometAPI │ │ │ │ │ ├── Gemini │ │ ├── Claude │ │ └── GPT │ │ │ ▼ │ Стоимость / Качество / │ Задержка / Политика │ ▼ Чекпойнты │ ▼ Трекинг использования
Ключевые продакшен-компоненты:
- Список разрешенных моделей
- Маршрутизация на уровне агента
- Ограниченные ретраи
- Чекпойнтинг задач
- Трекинг использования
- Контроль стоимости
- Тестирование совместимости моделей
- Наблюдаемость
- Идемпотентные побочные эффекты
Эта архитектура значительно надежнее, чем просто добавить try/except вокруг crew.kickoff().
Один ключ CometAPI, разные модели, более ясные роли агентов
Самый полезный способ мыслить о CrewAI и CometAPI — как о двух взаимодополняющих слоях.
CrewAI определяет, что делают агенты.
CometAPI определяет, как эти агенты получают доступ к моделям.
Это разделение позволяет назначить быструю модель агенту исследованию с большим объемом, более сильную в рассуждениях — аналитику, и универсальную — финальному автору, не поддерживая отдельные интеграции провайдеров внутри рабочего процесса.
Самая простая реализация использует один ключ CometAPI и один базовый URL, совместимый с OpenAI:
https://api.cometapi.com/v1
В продакшене сделайте архитектуру на шаг надежнее: держите маршрутизацию моделей в конфигурации, валидируйте доступность моделей до деплоя, используйте ограниченный фолбэк только для временных сбоев, чекпойнтьте завершенные задачи и записывайте метаданные о моделях и использовании для каждого запуска.
Это даст гораздо более устойчивую схему, чем просто подключить CrewAI к одной LLM:
CrewAI оркестрирует агентов. CometAPI централизует доступ к моделям. Идентификаторы моделей управляют маршрутизацией. Чекпойнты защищают завершенную работу. Трекинг использования контролирует стоимость.
Часто задаваемые вопросы
Может ли CrewAI использовать несколько ИИ-моделей в одной команде?
Да. Назначьте каждому агенту CrewAI отдельную конфигурацию LLM. Каждая конфигурация может указывать свою модель, используя тот же ключ API CometAPI и базовый URL.
Может ли CrewAI подключаться к API, совместимому с OpenAI?
Да. Конфигурация LLM в CrewAI поддерживает пользовательский base_url и ключ API для конечных точек, совместимых с OpenAI.
С CometAPI базовый URL:
https://api.cometapi.com/v1
Нужны ли отдельные ключи API для GPT, Claude и Gemini?
При доступе к этим моделям через CometAPI приложение может использовать учетные данные CometAPI и конечную точку, а не внедрять отдельные ключи провайдеров в каждом агенте CrewAI.
Означает ли один ключ API, что модели имеют идентичные возможности?
Нет. Интерфейс API может быть унифицирован, а возможности моделей — разными. Окна контекста, поддержка инструментов, параметры, поведение вывода, задержка и цены различаются по моделям.
Нужно ли ретраить весь рабочий процесс CrewAI, если одна модель падает?
Только для простых, без状態ных процессов. Повтор всего crew может заново выполнить завершенные задачи и повысить стоимость. Для продакшена чекпойнтьте завершенные задачи и возобновляйте с упавшей части, где это возможно.
Текущая функциональность чекпойнтов CrewAI предназначена для сохранения состояния выполнения и продолжения после сбоев.
Должно ли каждое исключение CrewAI запускать фолбэк модели?
Нет. Аутентификация, некорректные запросы, неверные ID моделей и неподдерживаемые параметры обычно требуют изменений конфигурации, а не смены модели.
Фолбэк лучше оставлять для ограниченных временных сбоев, таких как таймауты, лимиты скорости и временные ответы 5xx.
Как отслеживать стоимость каждого агента CrewAI?
Записывайте имя агента, ID модели, использование токенов, задержку, статус выполнения и информацию о фолбэке для каждой задачи. Используйте данные для расчета стоимости на агента и на процесс.
Можно ли динамически менять модель, назначенную агенту?
Да. Храните ID моделей в конфигурации маршрутизации, а не внедряйте их прямо в определения агентов. Ваше приложение сможет выбирать модели по стоимости, задержке, типу задачи или доступности.
Является ли CometAPI заменой CrewAI?
Нет. Это разные слои. CrewAI оркестрирует агентов и задачи, CometAPI предоставляет унифицированный слой доступа к моделям.
Где найти актуальные модели CometAPI?
Используйте каталог моделей CometAPI для ручного просмотра и API моделей для программной проверки. Текущая страница быстрого старта CometAPI перечисляет 500+ моделей по категориям текста, изображений, видео и аудио.
