14. Экосистема и Фреймворки¶
Зачем это нужно?¶
При создании AI-агентов вы сталкиваетесь с выбором: писать всё с нуля или использовать фреймворк? Оба подхода имеют плюсы и минусы, и понимание того, когда что выбирать, критично для долгосрочного успеха.
Эта глава поможет принимать архитектурные решения, избегать vendor lock-in и использовать готовые решения там, где они реально подходят.
Реальный кейс¶
Ситуация: Вам нужно создать DevOps-агента. Вы можете:
- Использовать популярный фреймворк, который предоставляет всё из коробки
- Построить собственный runtime, адаптированный под ваши нужды
Проблема:
- Подход с фреймворком: Быстрый старт, но вы заперты в их абстракциях. Когда нужна кастомная логика, вы боретесь с фреймворком.
- Кастомный подход: Полный контроль, но вы изобретаете велосипед. Каждая функция (tool execution, memory, planning) требует реализации.
Решение: Понять компромиссы. Выбирайте фреймворк, когда важна скорость и требования стандартные. Выбирайте кастом, когда нужен специфический контроль или есть уникальные ограничения.
Теория простыми словами¶
Что такое фреймворки для агентов?¶
Фреймворки для агентов — это библиотеки или платформы, которые предоставляют:
- Инфраструктуру выполнения инструментов — обработка function calling, валидация, обработка ошибок
- Управление памятью — контекстные окна, саммаризация, сохранение состояния
- Паттерны планирования — ReAct циклы, оркестрация workflow, декомпозиция задач
- Координация multi-agent — supervisor паттерны, изоляция контекста, маршрутизация
Суть: Фреймворки абстрагируют общие паттерны, но они также накладывают ограничения. Понимание этих ограничений помогает решить, когда использовать их, а когда строить кастом.
Кастомный Runtime vs Фреймворк¶
Кастомный Runtime:
- Полный контроль над каждым компонентом
- Нет vendor lock-in
- Оптимизирован под ваш конкретный use case
- Больше кода для написания и поддержки
- Нужно реализовывать общие паттерны самостоятельно
Фреймворк:
- Быстрая разработка, проверенные паттерны
- Поддержка сообщества и примеры
- Обрабатывает edge cases, которые вы можете пропустить
- Меньше гибкости, сложнее кастомизировать
- Потенциальный vendor lock-in
- Может включать функции, которые вам не нужны
Как выбирать?¶
Критерии решения¶
Выбирайте кастомный Runtime когда:
- Уникальные требования — Ваш use case не вписывается в стандартные паттерны
- Критична производительность — Нужен тонкий контроль над latency/cost
- Минимум зависимостей — Хотите избежать внешних зависимостей
- Цель обучения — Хотите глубоко понять внутренности
- Долгосрочный контроль — Нужно независимо поддерживать и развивать систему
Выбирайте фреймворк когда:
- Стандартный use case — Ваши требования соответствуют общим паттернам
- Скорость выхода на рынок — Нужно быстро запустить
- Знакомство команды — Ваша команда уже знает фреймворк
- Быстрое прототипирование — Исследуете идеи и нужны быстрые итерации
- Поддержка сообщества — Выигрываете от примеров и знаний сообщества
Соображения портабельности¶
Vendor lock-in в Go решается знакомым паттерном — драйверы провайдеров, регистрируемые blank-импортом, как в database/sql. Приложение зависит от маленького фасада (Client.Chat / Client.Stream), а конкретный провайдер подключается импортом драйвера и выбирается строкой-именем в конфигурации. Сменить провайдера — сменить одну строку, а не переписывать код.
Что ещё помогает не запереть себя:
- Стандартные протоколы — JSON Schema для tools (гл. 03), MCP/A2A для внешних интеграций (гл. 18), OpenTelemetry для observability
- Минимальная связь с фреймворком — если берёте фреймворк, держите бизнес-логику отдельно от оркестрации
- Постепенный путь миграции — проектируйте так, чтобы компоненты можно было менять позже
В реальном SDK. Коммерческие Go-SDK для LLM устроены ровно так: восемь драйверов протоколов (Anthropic, OpenAI, Google и другие), openai-compatible драйвер обслуживает сразу несколько провайдеров, а каталог моделей живёт отдельным пакетом. Приложение видит только фасад.
JSON Schema и инструменты¶
Схема инструмента — часть протокола function calling: LLM получает её в описании tool'а и по ней генерирует аргументы. Формат — стандартный JSON Schema (type, properties, required, enum); глава 03 показывает его целиком, здесь повторять не будем.
Практическое правило: не выписывайте схемы руками. SDK или ваш рантайм генерирует схему из Go-структуры параметров через reflection — структура остаётся единственным источником истины, рассинхрон схемы и кода невозможен:
type DeployParams struct {
Service string `json:"service" jsonschema:"description=Имя сервиса"`
Env string `json:"env" jsonschema:"enum=staging|production"`
}
// schema := reflector.Reflect(DeployParams{}) → готовый inputSchema для tool'а
Ручная валидация JSON Schema оправдана только на границе с внешними, недоверенными данными — например, когда аргументы приходят от чужого агента по сети. Для собственных tool'ов достаточно json.Unmarshal в Go-структуру: он сам сообщит о несоответствии типов и обязательных полей.
Общие паттерны во фреймворках¶
Все фреймворки под капотом реализуют одни и те же механизмы, которые вы уже построили в этом курсе:
| Паттерн | Что это | Где в курсе |
|---|---|---|
| Tool Registry | Словарь имя → инструмент + диспетчеризация вызовов |
Гл. 03 |
| Agent Loop | Цикл «LLM → tool call → результат → LLM» до финального ответа | Гл. 04 |
| История сообщений | Линейный список сообщений как память агента | Гл. 12 |
Отдельное предостережение — абстракция памяти (Memory с методами Store/Retrieve/Search), которую фреймворки нередко предлагают ради «портабельности». На практике это антипаттерн: память агента — это линейная история сообщений плюс condense при переполнении окна (гл. 12). Универсальный интерфейс памяти решает проблему смены фреймворка, которой у вас нет, и не решает проблему переполнения контекста, которая у вас есть. Если фреймворк навязывает такую абстракцию — проверьте его модель памяти до внедрения, а не после.
Фреймворки и экосистема¶
Обзор реальных фреймворков¶
Дисклеймер: агентные фреймворки эволюционируют быстро — мажорные релизы выходят раз в несколько месяцев, API ломается, сильные/слабые стороны меняются. Сводка ниже — ориентир на момент написания. Перед выбором проверяйте свежую документацию, последние релизы и реальные production-кейсы (issue tracker, downgrade-репорты).
LangGraph (Python, LangChain). Агенты на основе графов состояний: каждый шаг — узел графа, переходы определяются условиями. Подходит для сложных workflow с ветвлениями и циклами.
CrewAI (Python). Мульти-агентные системы: агенты объединяются в «команды» (crews) с ролями и задачами. Удобен для сценариев, где несколько агентов сотрудничают над общей целью.
AutoGen (Microsoft, Python). Мульти-агентные системы с упором на диалог между агентами. В v0.4 переписан с нуля (новое ядро + фреймворк AgentChat поверх него) — материалам и туториалам времён до v0.4 доверяйте с осторожностью: это фактически другой фреймворк.
Semantic Kernel (Microsoft, .NET/Python). Оркестратор, интегрирующий LLM с существующим кодом через «плагины». Ориентирован на enterprise и экосистему Microsoft.
OpenAI Agents SDK (Python/JS). Лёгкий SDK: агент как цикл с инструментами, handoff'ы между агентами, guardrails.
Google ADK (Python/Java). Agent Development Kit от Google, тесно связан с Vertex AI.
pydantic-ai (Python). Типизированные агенты: схемы инструментов генерируются из pydantic-моделей — та же идея, что генерация из Go-структуры в гл. 03.
Vercel AI SDK (TypeScript). Агентные примитивы для веб-стека.
Список не полный: рынок меняется быстрее книг — проверяйте актуальность на момент чтения.
Сравнительная таблица¶
| Фреймворк | Язык | Сильные стороны | Слабые стороны |
|---|---|---|---|
| LangGraph | Python | Граф-based workflow, гибкие состояния, стриминг | Сложный API, крутая кривая обучения |
| CrewAI | Python | Простая мульти-агентная координация, роли | Менее гибкий для нестандартных паттернов |
| AutoGen | Python | Диалоговые мульти-агентные системы, Microsoft backing | Тяжеловесный, сложная отладка; v0.4 — фактически новый фреймворк |
| Semantic Kernel | .NET, Python | Enterprise-ready, интеграция с Azure | Ориентирован на экосистему Microsoft |
А в Go?¶
Доминирующего агентного фреймворка в Go нет — и это нормально. Рабочий выбор большинства Go-команд: маленькие библиотеки-фасады для LLM-провайдеров (паттерн драйверов описан выше) плюс собственный цикл агента на 300–500 строк, который вы пишете в главе 04. Это скучное и проверяемое решение: весь код агента — ваш, отладка обычная, зависимостей минимум. Фреймворк оправдан, когда вам нужны именно его готовые паттерны оркестрации, а не «чтобы не писать цикл руками».
Экосистема MCP¶
MCP (Model Context Protocol) — открытый протокол подключения инструментов к LLM-агентам: один протокол, и любой MCP-сервер работает с любым MCP-клиентом. Экосистема готовых серверов (базы данных, файловые системы, API, браузеры) активно растёт. Разбор протокола — в Главе 18: Протоколы Инструментов и Tool Servers.
Экосистема A2A¶
A2A (Agent-to-Agent) — открытый протокол взаимодействия агентов друг с другом: каждый агент публикует discovery-документ со своими возможностями, остальные находят его и делегируют задачи через стандартный HTTP API. Подробности — в Главе 18.
Skills¶
Отдельный слой экосистемы — навыки (Skills, agentskills.io): пакеты знаний в формате SKILL.md с progressive disclosure — агент подгружает инструкцию, только когда задача её касается. Поддерживаются Cursor, Claude Code, VS Code и др. Подробно — в Главе 09: Анатомия Агента.
Почему этот курс учит с нуля¶
Этот курс строит агента с нуля по нескольким причинам:
-
Понимание фундамента. Фреймворк скрывает детали за абстракциями. Когда что-то ломается, вы не знаете, где искать. Написав agent loop, tool registry и историю сообщений своими руками, вы понимаете каждый компонент.
-
Осознанный выбор. После реализации с нуля вы точно знаете, какие проблемы решает фреймворк. Решение «использовать LangGraph» или «написать кастом» становится обоснованным, а не случайным.
-
Портабельность знаний. Фреймворки меняются. Знание принципов (agent loop, Function Calling, context management) переносится на любой фреймворк. Знание конкретного API — нет.
-
Go как явный язык. Большинство фреймворков написаны на Python. Этот курс использует Go, что заставляет реализовывать паттерны явно — без «магии» декораторов и метапрограммирования.
-
Простота вместо моды. Многие «продвинутые» паттерны из обзоров и постов про агентов на практике не нужны. Линейная история сообщений, один
condenseпри переполнении окна, фиксированный system prompt, лимит итераций, защита от повторов — этого достаточно для большинства задач (см. гл. 12, гл. 13). Многоуровневые сжатия, скоринг важности сообщений, динамические промпты, тяжёлые «фреймворки памяти» обычно решают не ту проблему: они дороги, ломают prompt cache и усложняют отладку, при этом редко окупаются на реальных нагрузках. Это не значит, что они вредны всегда — но прежде чем их внедрять, стоит проверить базовые механизмы и убедиться, что простого решения действительно не хватает. Когда вы пишете runtime сами, эту разницу видно сразу.
Типовые ошибки¶
Ошибка 1: Vendor Lock-In¶
Симптом: Ваш код тесно связан с API фреймворка. Смена фреймворка требует переписывания всего.
Причина: Использование типов фреймворка напрямую вместо определения своих интерфейсов.
Решение:
// ПЛОХО: Прямая зависимость от фреймворка
func processRequest(frameworkAgent *FrameworkAgent) {
result := frameworkAgent.Execute(userInput)
}
// ХОРОШО: На основе интерфейсов
type Agent interface {
Execute(input string) (string, error)
}
func processRequest(agent Agent, userInput string) (string, error) {
return agent.Execute(userInput)
}
// Адаптер фреймворка реализует ваш интерфейс
type FrameworkAdapter struct {
agent *FrameworkAgent
}
func (a *FrameworkAdapter) Execute(input string) (string, error) {
return a.agent.Execute(input)
}
Ошибка 2: Излишняя инженерия кастомного Runtime¶
Симптом: Вы тратите месяцы на построение функций, которые фреймворки предоставляют из коробки.
Причина: Не оцениваете, действительно ли нужна кастомная реализация.
Решение: Начните с фреймворка для прототипирования. Извлекайте в кастом только когда натыкаетесь на реальные ограничения.
Ошибка 3: Игнорирование ограничений фреймворка¶
Симптом: Вы постоянно боретесь с фреймворком, пытаясь заставить его делать то, для чего он не был предназначен.
Причина: Не понимаете дизайнерские решения и ограничения фреймворка.
Решение: Внимательно читайте документацию фреймворка. Если ограничения слишком сильные, рассмотрите кастомный runtime.
Ошибка 4: Нет пути миграции¶
Симптом: Вы заперты с фреймворком, даже когда он больше не подходит вашим нуждам.
Причина: Тесная связь делает миграцию невозможной без переписывания всего.
Решение: Проектируйте с интерфейсами с самого начала. Держите фреймворк как деталь реализации, а не основную зависимость.
Мини-упражнения¶
Упражнение 1: Интерфейс Tool¶
Определите интерфейс Tool, не зависящий от фреймворка. Схема генерируется из Go-структуры параметров — рукописный JSON не нужен:
type Tool interface {
Name() string
Description() string
Schema() json.RawMessage // сгенерирована из структуры параметров (reflection)
Execute(ctx context.Context, args map[string]any) (any, error)
}
type PingParams struct {
Host string `json:"host" jsonschema:"description=Hostname or IP"`
}
// Схема — из структуры; в Execute аргументы распаковываются в неё же через json.Unmarshal
Ожидаемый результат:
- Интерфейс не зависит от фреймворка; адаптер фреймворка может его реализовать
- Схема — из Go-структуры, а не рукописный JSON (единый источник истины)
- Валидация аргументов — через
json.Unmarshalв структуру параметров
Упражнение 2: Адаптер фреймворка¶
Создайте адаптер, который оборачивает систему инструментов фреймворка для реализации вашего интерфейса Tool:
type FrameworkToolAdapter struct {
frameworkTool FrameworkTool
}
func (a *FrameworkToolAdapter) Name() string {
// Адаптируем имя инструмента фреймворка
}
func (a *FrameworkToolAdapter) Execute(ctx context.Context, args map[string]any) (any, error) {
// Конвертируем ваш интерфейс в API фреймворка
}
Ожидаемый результат:
- Фреймворк становится деталью реализации
- Ваш код использует ваши интерфейсы
- Легко менять фреймворки позже
Упражнение 3: Матрица решений¶
Создайте матрицу решений для выбора между кастомным runtime и фреймворком:
| Критерий | Кастомный Runtime | Фреймворк |
|---|---|---|
| Скорость разработки | ? | ? |
| Гибкость | ? | ? |
| Бремя поддержки | ? | ? |
| Риск vendor lock-in | ? | ? |
Заполните матрицу на основе ваших конкретных требований.
Ожидаемый результат:
- Чёткое понимание компромиссов
- Обоснованное решение для вашего use case
Критерии сдачи / Чек-лист¶
Сдано:
- Понимаете, когда использовать фреймворки vs кастомный runtime.
- Знаете, как избежать vendor lock-in: фасад провайдера в стиле
database/sqlи свои интерфейсы (Tool). - Можете оценить фреймворк против ваших требований и спокойно отнестись к громким обещаниям про «революционные» паттерны.
- Понимаете общие паттерны, которые повторяются во всех фреймворках (Tool Registry, Agent Loop, история сообщений).
- При выборе фреймворка проверяете свежесть данных (релизы, issues, реальные production-отзывы).
Не сдано:
- Выбор фреймворка без оценки требований.
- Тесная связь с API фреймворка (типы фреймворка везде в бизнес-логике).
- Нет пути миграции, если фреймворк не подойдёт.
- Игнорирование ограничений фреймворка («заставлю его делать то, для чего он не предназначен»).
- Слепое копирование «продвинутых» паттернов из чужих репозиториев и блог-постов без понимания, какую конкретно проблему они решают.
Связь с другими главами¶
- Глава 09: Анатомия Агента — Понимание компонентов агента помогает оценить фреймворки.
- Глава 03: Инструменты и Function Calling — Интерфейсы инструментов — ключ к портабельности.
- Глава 10: Planning и Workflow-паттерны — Фреймворки часто предоставляют паттерны планирования.
- Глава 12: Системы Памяти Агента и Глава 13: Context Engineering — Простая модель памяти и контекста, к которой стоит примерять любой фреймворк, прежде чем брать его как «продвинутое» решение.
- Глава 18: Протоколы Инструментов и Tool Servers — Стандартные протоколы (MCP, A2A) уменьшают vendor lock-in.
- Agent Skills — Открытый формат навыков агента (
SKILL.md), поддерживаемый Cursor, Claude Code, VS Code и др. См. Главу 09: Анатомия Агента.
Что дальше?¶
После понимания экосистемы переходите к:
- 15. Кейсы из Реальной Практики — Изучите примеры реальных агентов