Привет, Хабр! Меня зовут Семен, руководитель команды разработки продукта, мы небольшая команда стартапа, которая занимается внедрением ИИ в бизнес-процессы. Как это часто бывает, пытаясь автоматизировать работу других, мы столкнулись с классической проблемой у себя дома: острой нехваткой времени и рабочих рук.
Недавно мы внедрили первую версию нашего продукта клиенту. И, как полагается, следом пошел фидбек: баги, пожелания, консультации. Принятие решения о починке даже мелкого бага стало для нас проблемой. Мы оказались на развилке: либо бросаем все силы на фиксы, либо продолжаем пилить продукт по своему плану, либо делаем кастомные доработки по желанию заказчика.
Масштабировать команду прямо сейчас не вариант. Это требует времени на онбординг и дополнительных бюджетов, а решение нам было нужно «еще вчера». И тут нас осенило: мы же внедряем агентов бизнесу, почему бы не внедрить их в собственную разработку?
В этой статье я расскажу, как мы пытались автоматизировать написание кода, почему отказались от популярных open-source решений, как боролись с «характерами» нейросетей и, главное, как пришли к собственной архитектуре «Менеджера Состояний», которая позволила нам снизить затраты на API в разы и избавиться от бесконечных циклов ошибок.
Изучая рынок, мы сразу отбросили тяжеловесные решения вроде Devin или Openhands. Это отличные инструменты, но на текущем этапе они казались нам перегруженными - это скорее следующая ступень эволюции.
Наш выбор пал на Aider, популярного CLI-агента. И поначалу это был восторг. Мы встроили его прямо в CI/CD: после каждого изменения в коде агент автоматически генерировал и обновлял документацию. Это сняло с нас гигантский пласт технического долга.
Но как только мы попытались переложить на Aider реальные процессы (Бэклог → ТЗ → Код → Тесты), система посыпалась. Мы столкнулись с двумя фатальными проблемами:
Отсутствие контроля инструментов. Мы оказались фактически отрезаны от интеграций с нашими системами управления проектами.
Проблема передачи результатов. Представьте: агент изучил репозиторий и написал отличное техническое задание. Куда он его написал? Как нам забрать этот артефакт и программно положить в базу данных? Можно, конечно, жестко прописывать пути до файлов в инструкциях и писать подсистемы-костыли для обмена информацией, но на практике такие костыли ломаются при малейшем отклонении.
Стало ясно: Aider хорош для точечных задач в терминале, но для построения непрерывного процесса разработки он нам не подходит. Решили делать инструмент под себя, благо в рамках нашего основного продукта у нас уже была написана легковесная библиотека для работы с агентами.
До этого мы создавали ИИ-поисковиков, работали с RAG и анализом документов. Но создать агента-программиста оказалось куда более нетривиальной задачей.
Мы попытались скопировать структуру человеческой команды и реализовали паттерн «Оркестратор + Программисты». Логика простая: Оркестратор получает ТЗ, составляет план и раздает поручения мелким агентам-кодерам. Звучит красиво, но на практике не работает.
Грабли №1: Разрыв ответственности.
Если первый агент-кодер не до конца выполнил свою задачу (например, забыл объявить процедуру), но радостно отчитался Оркестратору об успехе, система ломается. Оркестратор поручает второму агенту написать логику с использованием этой процедуры. Второй агент вечно пытается найти то, чего нет, падает в ошибки, а снежный ком галлюцинаций только растет.
Грабли №2: Аналитический паралич (циклы).
Агенты обожают изучать репозиторий. Они будут читать, анализировать, перепроверять файлы по кругу, но до последнего оттягивать момент внесения изменений в код. Им банально не хватает «решительности».
В процессе тестов мы сделали забавное, но важное наблюдение: у разных моделей есть свой ярко выраженный «характер» и стиль работы, который критически влияет на результат.
Gemini 3 pro - это уверенный, гиперактивный разработчик. Она очень автономна, но из-за своей самоуверенности часто отходит от ТЗ, считая, что «лучше знает, как надо реализовать эту фичу».
MiniMax M2.5 - полная противоположность. Это тревожный стажер. Модель будет строго придерживаться плана, но не решится написать и строчки кода, пока не прочитает половину файлов в проекте.
Claude Sonnet 4.6 - дорогой и опытный разработчик. Идеальный баланс автономности и следования инструкциям. Но его использование на каждом мелком шаге превращает разработку в финансовую черную дыру. Экономика стартапа с ним просто не сходится.
Нам нужно было найти способ использовать сильные стороны дорогих моделей, но при этом не разориться.
Наблюдая за ошибками, разбухающим контекстным окном (когда в промпт сыплются тысячи строк логов и ошибок) и тем самым «эффектом золотой рыбки», когда через 15 шагов агент забывает, зачем вообще начал писать код, мы пришли к новому подходу.
Мы вывели три правила, которые легли в основу нашей архитектуры.
Правило 1: Один ТЗ - один агент от А до Я
Мы отказались от микроменеджмента. Теперь один агент получает ТЗ, сам его выполняет и сам же исправляет ошибки. Только он знает все мельчайшие детали реализации от начала до конца. Никакого испорченного телефона.
Правило 2: Концепция «Рабочего стола» и памяти файлов
Агент не должен читать весь проект. Для работы ему обычно требуется 5-8 файлов. Мы жестко ограничили его «рабочий стол». Но главное: при закрытии файла агент обязан создать ячейку памяти и записать туда всю полезную информацию, ради которой он этот файл открывал. Таким образом, знания сохраняются в компактном виде, а не в виде простыни исходного кода.
Правило 3: Генеральный директор не делает холодные звонки (Ядро системы)
В индустрии популярен подход: используем дешевую модель для рутины и генерации саммари, а дорогую - для написания сложного кода. Мы поняли, что это в корне неверно.
Разве генеральный директор звонит клиентам по холодной базе, чтобы получить задачу от младшего менеджера? Нет. Один опытный руководитель может кратно поднять продуктивность десяти стажеров: он не работает за них руками, но бережет от типичных ошибок и спасает в сложные моменты.
Мы внедрили двухконтурную систему:
Воркер (дешевая и быстрая LLM): Выполняет рутину, пишет код, дергает инструменты, получает ошибки компилятора.
Менеджер Состояний (дорогая и умная LLM): Работает как диспетчер памяти, наставник и сборщик мусора. Он не пишет код руками. Он управляет «мозгом» Воркера.
Весь процесс управления Воркером строится на регулярных перехватах инициативы. Воркер делает несколько шагов (пишет код, получает ошибки компилятора, пытается их исправить) и копит логи. Как только он застревает или достигает лимита операций, система ставит его на паузу, и просыпается Менеджер Состояний.
Менеджер читает всю скопившуюся историю попыток Воркера и выполняет четыре ключевых действия:
Описывает проделанную работу: Анализирует логи и формирует краткую выжимку того, что уже реально сделано и работает.
Обновляет память: Добавляет в объект памяти новые знания. Это могут быть извлеченные из файлов переменные, удачные архитектурные решения или, наоборот, «минные флажки» - зафиксированные тупики (например, «библиотека X конфликтует с нашей версией, не используй ее»).
Принимает решение о целесообразности: Это важнейший этап. Менеджер оценивает ситуацию и решает, а нужно ли агенту вообще продолжать работу? Возможно, Воркер столкнулся с задачей, которую физически невозможно решить выданными ему инструментами. В таком случае Менеджер прерывает цикл, не давая системе бесконечно жечь токены на бессмысленные попытки.
Дает рекомендации на следующий шаг: Если работу можно продолжить, Менеджер формирует четкую директиву - как именно выполнить следующую часть задачи и как обойти возникшие ошибки.
И тут кроется наш главный технический хак.
Как заставить упрямую модель (Воркера) прислушаться к этим рекомендациям и не сбиться с пути?
Всё сформированное послание, за исключением самого блока памяти , мы подаем Воркеру в виде сообщения от лица пользователя.
Почему это критически важно? Языковые модели натренированы беспрекословно следовать прямым инструкциям пользователя. Если подать рекомендации Менеджера как системное сообщение или мысли самого ассистента, Воркер может начать с ними спорить, проигнорировать их или попытаться «додумать» свой вариант. Но сообщение от пользователя продвигает агента вперед и жестко возвращает его на нужные рельсы.
В этот же момент происходит «чистка» - мы программно стираем всю предыдущую историю переписки Воркера с его ошибками.
Воркер просыпается с абсолютно чистым контекстным окном, важными данными о прошлом, и рекомендациям по следующим шагам.
Воркер начинает новый цикл работы с ясным умом, четкой целью и без груза прошлых неудач.
Конечно, у любой архитектурной концепции есть свои уязвимости. Передавая контроль над памятью и целеполаганием Менеджеру Состояний, мы фактически создаем единую точку отказа.
Риск очевиден: если Менеджер вдруг «сломается», неправильно интерпретирует логи Воркера или сгаллюцинирует (например, запишет в жесткую память выдуманное название функции), то весь последующий процесс пойдет под откос. Поскольку Воркер слепо верит всему, что приходит от лица пользователя, он будет упорно пытаться использовать несуществующие данные, пока не исчерпает лимит попыток. Ошибка на уровне архитектора каскадом ломает работу исполнителя.
Мы закладывали этот риск при проектировании и внимательно следили за поведением системы. Однако практика показала интересную вещь: этот риск несоизмеримо ниже тех преимуществ, которые дает архитектура.
Когда мощная модель не пишет код сама, а работает исключительно в режиме аналитика и администратора памяти, вероятность ее галлюцинаций стремится к нулю. Моделям гораздо проще структурировать готовый текст и извлекать из него факты, чем генерировать сложную логику с нуля.
Да, иногда Менеджер может принять неоптимальное решение. Но в 99% случаев он успешно вытягивает Воркера из ямы бесконечных ошибок, экономит миллионы токенов на контексте и доводит задачу до конца. Те редкие сбои, которые все же случаются, отлавливаются нами на этапе финального ревью.
Переход от парадигмы «чат-бота» к жесткому управлению состоянием дал нам потрясающие результаты:
Мы сменили роли. Из программистов, которые сутками ищут баги, мы превратились в операторов и архитекторов. Решения, написанные агентами, остается только отладить на верхнем уровне и грамотно слить в релиз.
Минимизировали технический долг. Тесты и документация теперь идут в комплекте к каждой задаче по умолчанию. Нам больше не нужно заставлять себя это писать.
Снизили стоимость доработки. Мы добились стабильного контекстного окна без переполнения и обеспечили дешевую автономную работу агентов. Уже после первых релизов мы осознали, что инвестиции в этот внутренний инструмент позволяют нам давать клиентам цены на доработки продукта сильно ниже рынка, сохраняя при этом высокую маржинальность.
В следующей статье покажу примеры наших промптов с объектами памяти.
Источник


