Всё началось с любопытства: я нашёл на GitHub open-source каркас для AI-агента на n8n — по сути, обвязку вокруг LLM с инструментами, памятью и циклом планирования — и импортировал его в свой n8n на лабе просто чтобы посмотреть, как это устроено изнутри. Спустя несколько месяцев это превратилось в полноценную production-платформу, которая работает 24/7 и разбирает сообщения через мессенджер, отвечает на вопросы по базе знаний и умеет диагностировать мою собственную инфраструктуру.
От одного агента к маршрутизации
Первая версия была простой: один агент получал сообщение, решал, какой инструмент вызвать, и отвечал. Но по мере роста задач стало понятно, что один универсальный агент — плохая идея: промпт разрастается, модель путается в контексте, а ошибки в одной области (например, работа с базой знаний) начинают влиять на другую (диагностику инфраструктуры).
Решением стал переход к архитектуре с маршрутизацией: входящее сообщение сначала классифицируется (ключевые слова + LLM-классификатор для неочевидных случаев), а затем направляется одному из специализированных агентов — общему, DevOps-агенту с доступом к SSH-диагностике или агенту базы знаний с векторным поиском. У каждого — своя память диалога и свой набор инструментов.
Очереди, идемпотентность и dead-letter
Production-система, которая работает без присмотра, обязана переживать сбои. Сообщения идут через очередь в PostgreSQL с блокировкой на уровне строк (SELECT FOR UPDATE SKIP LOCKED), чтобы несколько параллельных обработчиков не хватали одно и то же сообщение дважды. Отдельные фоновые процессы — я называю их «уборщиками» — периодически возвращают зависшие сообщения обратно в очередь, а после нескольких неудачных попыток помечают их как окончательно проваленные вместо того, чтобы застревать навсегда.
Самый ценный урок здесь — заранее закладывать деградацию: у каждого агента есть детерминированный fallback-узел, который отправляет ответ пользователю независимо от того, вызвала ли модель нужный инструмент сама. Модели иногда «забывают» позвать функцию отправки — система не должна молчать в этом случае.
Память и база знаний
Каждый агент помнит контекст разговора через PostgreSQL, а для ответов по накопленным знаниям используется векторный поиск (pgvector) — входящие вопросы превращаются в эмбеддинги и сопоставляются с ранее сохранёнными фрагментами знаний. Это позволяет агенту отвечать не только «из головы» модели, но и опираясь на то, что я сам туда загрузил.
DevOps-агент как отдельная история
Отдельный агент специализируется на диагностике самой инфраструктуры: у него есть набор структурированных инструментов (проверка HTTP-эндпоинтов, проверка маршрутов реверс-прокси, резолвинг хостов по инвентарю) вместо вольного доступа к произвольным командам. Это осознанный компромисс — чуть менее гибко, зато предсказуемо и безопаснее для production-среды.
Чему это меня научило
- Специализация агентов работает лучше одного «универсального солдата» — как в командах разработки, так и в мультиагентных системах.
- Очереди без идемпотентности и dead-letter обработки — это вопрос времени до первого дублирующегося или потерянного сообщения.
- Детерминированные fallback-узлы важнее, чем кажется: нельзя полностью полагаться на то, что LLM всегда вызовет нужный инструмент.
- Наблюдаемость (логирование событий, аудит) должна закладываться с первой версии, а не добавляться после первого непонятного сбоя.
Эта же платформа стоит на self-hosted AI-шлюзе — о нём в следующем посте.
Комментарии