Архитектура для AI-driven разработки
Агенту, как и человеку, тяжело работать в системе, где всё связано со всем. Разбираю, как структура репозитория, документация, конвенции и границы автономии определяют, насколько эффективно AI-агент вообще способен помочь.
Почему архитектура теперь часть AI-workflow, а не только человеческого
Хорошая архитектура всегда облегчала работу человеку: понятная структура, явные границы модулей, предсказуемые конвенции. AI-агент читает тот же код и работает по тем же правилам, но с одной существенной разницей: у него нет многолетнего контекста работы именно с этой кодовой базой, который у человека накапливается сам собой просто от того, что он тут давно работает.
Это значит, что архитектурные решения, которые раньше были вопросом вкуса или постепенно усваивались новыми сотрудниками через месяцы работы, теперь напрямую влияют на то, насколько эффективно агент способен ориентироваться в системе с первой же сессии. Плохо структурированный репозиторий не станет менее рабочим, но станет заметно дороже и медленнее в работе с AI, потому что агенту придётся каждый раз заново разбираться в том, что человек мог бы держать в голове.
Показательное наблюдение: многие практики, которые считались "хорошим тоном", но которыми часто жертвовали ради скорости (явная документация решений, модульность вместо удобных, но связанных сокращений, последовательные конвенции именования), внезапно стали измеримо окупаться в конкретных цифрах: во времени, которое агент тратит на исследование контекста, и в стоимости токенов на это исследование. То, что раньше было вопросом инженерной культуры и личной дисциплины, теперь имеет прямое, легко посчитанное денежное выражение.
Это не означает, что нужно проектировать архитектуру специально под удобство работы AI-агентов в ущерб остальным соображениям. Хорошая архитектура для человека почти всегда оказывается хорошей архитектурой и для агента, потому что оба нуждаются в одном и том же: ясности, предсказуемости и отсутствии скрытых связей. Разница в том, что цена нарушения этих принципов теперь проявляется быстрее и заметнее, потому что агент сталкивается с ней в каждой сессии заново, а не постепенно, как человек, который со временем просто выучивает особенности конкретного проекта.
Полезно смотреть на это через простую метафору: архитектура — это среда, в которой работает и человек, и агент, и качество этой среды определяет, сколько усилий уходит на саму работу, а сколько на борьбу со средой вокруг неё. Плохо освещённая, неудобно спланированная мастерская замедляет любого мастера независимо от его квалификации, и агент в этом смысле ничем не отличается от человека: он тоже тратит часть своих "усилий" (токенов контекстного окна и количества итераций) на то, чтобы просто понять, где что лежит и как это работает, прежде чем взяться за саму задачу.
Масштаб применимости этих принципов не универсален. Небольшой личный проект с одним человеком у руля и коммерческая система с командой из пятнадцати разработчиков нуждаются в разной степени формализации архитектурных решений: то, что для первого случая избыточная бюрократия, для второго — необходимый минимум, без которого агент в разных сессиях от разных людей начинает предлагать взаимно противоречащие решения. Дальше в тексте речь в основном о принципах, применимых в обоих масштабах, с явными пометками там, где формализация оправдана только при определённом размере команды или системы.
Дальше разбираю конкретные архитектурные решения, которые определяют качество работы с AI-агентами: структуру репозитория, документацию, конвенции именования, границы автономии в продакшене и то, как избежать нового типа технического долга, специфичного именно для agentic-разработки.
Как структурировать репозиторий для эффективной работы AI-агентов
Структура репозитория определяет, сколько контекста агенту нужно восстанавливать в начале каждой сессии, прежде чем он вообще сможет приступить к задаче.
Практические принципы, которые снижают эту нагрузку. Явная граница между подпроектами в монорепозитории, а не размытая структура, где неясно, какой код к какой части системы относится. Один файл с инструкциями на верхнем уровне (CLAUDE.md, AGENTS.md или похожий), который агент читает автоматически, а не набор разрозненных README, разбросанных по подпапкам без единой точки входа. И предсказуемое расположение похожих сущностей: если обработчики запросов лежат в одной директории с говорящими именами файлов, агенту не нужно каждый раз искать нужный файл поиском по всему проекту.
Показательный пример из практики этого самого сайта: бэкенд организован по принципу "один файл на ресурс" внутри handlers/ — отдельный файл для блога, отдельный для проектов, отдельный для настроек. Это не оригинальное архитектурное решение само по себе, но именно предсказуемость такой структуры позволяет агенту почти всегда угадать, в каком файле искать логику для конкретной задачи, просто по названию сущности, без необходимости исследовать структуру заново.
Похожий принцип применим и к миграциям базы данных. В этом же проекте схема пересобирается идемпотентно при каждом старте приложения, а не через последовательность отдельных файлов миграций, как принято во многих других проектах. Это осознанное отступление от распространённого паттерна, и без явного объяснения в документации агент, скорее всего, попытается "исправить" это на более привычный подход, решив, что это упущение, а не намеренное архитектурное решение. Отсюда следует общее правило: если проект сознательно отступает от общепринятого паттерна, это отступление нужно явно задокументировать, потому что агент, как и новый разработчик, по умолчанию ожидает именно общепринятый вариант.
Ещё один практический приём для структуры репозитория: держать конфигурационные файлы и файлы с секретами явно отделёнными от остального кода, не только по соображениям безопасности (об этом отдельно в материале про AI-ассистентов), но и потому, что чёткое разделение "код" и "конфигурация" снижает риск, что агент перепутает одно с другим при автономной правке. Проект, где секреты, настройки окружения и бизнес-логика вперемешку лежат в одной директории, структурно провоцирует именно такие ошибки.
Отдельно стоит сказать про глубину директорий. Структура, где нужно спуститься на семь-восемь уровней вложенности, прежде чем добраться до реального файла с кодом, увеличивает нагрузку на контекст агента почти так же ощутимо, как избыточно длинная документация: каждый уровень пути — это дополнительная деталь, которую модель должна удержать при построении полного пути к файлу, и на глубоких структурах случайные ошибки в пути (лишний или пропущенный уровень) встречаются заметно чаще, чем на плоских. Разумный компромисс: группировать по предметной области, а не по формальной таксономии вроде "модели / контроллеры / утилиты" через всю систему, и получать за счёт этого более короткий и предсказуемый путь до конкретной задачи.
Модульная архитектура: почему маленькие модули работают лучше с AI
Маленькие, слабо связанные модули облегчают работу агенту по той же причине, по которой они облегчают работу человеку: задачу можно решить, держа в контексте только относящуюся к делу часть системы, а не весь проект целиком.
Разница с человеческой работой в масштабе эффекта. Человек может годами удерживать в голове неформальную карту связей между модулями проекта, даже если сама архитектура не идеальна. У агента такой накопленной интуиции нет, и каждая скрытая зависимость между формально независимыми модулями увеличивает риск, что правка в одном месте незаметно сломает что-то в другом, о существовании чего агент не знал и не мог знать без явного указания.
Практическое правило: если задача требует явно объяснять агенту, что модуль A связан с модулем B неочевидным образом, это сигнал, что сама архитектура несёт скрытую связанность, которую стоит либо сделать явной в документации, либо устранить рефакторингом. AI-driven разработка не создаёт новую потребность в модульности, она делает существовавшую всегда цену немодульности куда более заметной и куда более частой.
Конкретный ориентир размера модуля, который работает на практике: если объяснение назначения модуля агенту укладывается в два-три предложения без союза "и" через каждое слово, модуль, скорее всего, достаточно сфокусирован. Если объяснение превращается в длинный список разнородных обязанностей, это обычно означает, что модуль отвечает за слишком многое одновременно, и именно такие модули чаще всего становятся источником непредвиденных побочных эффектов при автономных правках, потому что агент, трогая одну часть модуля, не всегда понимает, что заодно затрагивает и остальные, формально не связанные с задачей.
Есть и обратная ошибка, в которую легко впасть, увлёкшись идеей маленьких модулей: чрезмерное дробление, при котором простая логическая операция разбита на пять крошечных файлов, связанных цепочкой импортов. Формально каждый файл маленький и сфокусированный, но чтобы понять полный путь выполнения одной операции, агенту приходится открывать все пять файлов подряд и удерживать в контексте связи между ними, что по факту создаёт ту же нагрузку, что и один большой модуль, только распределённую по файловой системе. Здоровый ориентир — "маленькая, но цельная единица ответственности" вместо просто "маленький файл", даже если для её реализации требуется полторы сотни строк в одном месте.
Глубина вложенности абстракций тоже имеет значение. Слишком много промежуточных слоёв между точкой входа и реальной бизнес-логикой заставляет агента (и человека) проходить длинную цепочку вызовов, прежде чем добраться до сути, и в длинных цепочках сильно растёт вероятность того, что модель упустит один из промежуточных шагов. Разумная плоская структура, где путь от запроса до результата прослеживается за три-четыре шага, а не за десять, снижает эту вероятность просто за счёт меньшего объёма контекста, который нужно удерживать одновременно.
Документация как код: как AI использует контекст проекта
Документация, которую раньше читали редко и которая быстро устаревала, получает новую практическую роль: это основной источник контекста, который агент подгружает в начале каждой сессии, и качество этого источника напрямую определяет качество результата.
Разница между документацией для людей и документацией для агента в приоритетах. Документация для человека может позволить себе общие описания, потому что человек способен задать уточняющий вопрос коллеге или методом проб разобраться самостоятельно. Документация для агента должна содержать именно те детали, которые неочевидны из самого кода: почему выбрана конкретная структура данных, какие ограничения не отражены в типах, какие команды использовать для конкретных операций, а не только общее описание, "что" делает система.
Практика, которая снижает риск устаревания: держать документацию для агента рядом с кодом, к которому она относится, а не в отдельной вики, оторванной от репозитория. Файл в корне проекта, который правится в том же pull request, что и код, устаревает заметно медленнее, чем документация, живущая в отдельной системе, до которой у команды физически не доходят руки при каждом изменении.
Полезная практика для команд: включать обновление документации агента в определение готовности задачи (definition of done), точно так же как обновление тестов. Pull request, который меняет архитектурно значимое поведение, но не затрагивает документацию для агента, формально может быть полным с точки зрения кода и полностью устаревшим с точки зрения контекста, который получит следующая сессия работы с этой частью системы.
Есть и обратная крайность, которую стоит явно избегать: чрезмерно подробная документация, пытающаяся описать вообще всё в проекте. Такой файл сам становится трудным для поддержания в актуальном состоянии, и агент, читающий избыточно длинную инструкцию, тратит часть контекстного окна на детали, не относящиеся к текущей задаче. Разумный ориентир: документировать то, что нельзя надёжно вывести из самого кода, и не дублировать то, что и так очевидно из структуры файлов и их содержимого.
CLAUDE.md, AGENTS.md и конвенции для AI-агентов: стандарты
Файлы с инструкциями проекта постепенно превращаются в отраслевой стандарт, аналогичный .gitignore или README.md: конкретное имя файла зависит от инструмента, но сама практика явного описания контекста для агента становится общепринятой.
Рабочая структура такого файла, которая масштабируется от маленького проекта до крупной системы: архитектурный обзор верхнего уровня (из каких частей состоит система и что за что отвечает), команды для типовых операций (сборка, тесты, локальный запуск), явные конвенции проекта, которые не следуют из самого кода, и список того, что агенту делать не следует без явного разрешения. Для монорепозитория с несколькими подсистемами имеет смысл отдельный раздел на каждую часть, а не один общий раздел на всё сразу, чтобы задача в одной подсистеме не тянула за собой не относящийся к делу контекст других.
Важный организационный момент, который часто упускают: файл с инструкциями для агента должен проходить тот же процесс ревью, что и код, а не обновляться произвольно кем угодно без согласования. Устаревшая или противоречивая инструкция хуже отсутствующей, потому что уводит агента в неправильную сторону с той же уверенностью, с какой правильная инструкция ведёт в верную.
Для команд с несколькими разработчиками отдельного внимания заслуживает вопрос личных, недекларируемых конвенций. Инструкция уровня репозитория работает только тогда, когда она отражает то, о чём команда реально договорилась, а не личные предпочтения одного человека, который её изначально написал. Периодическая совместная ревизия файла (например, раз в квартал или при заметном росте проекта) помогает поддерживать его актуальность и командное согласие с зафиксированными в нём правилами, а не превращает его в артефакт, который де-факто соблюдает только автор.
Соглашения об именовании для AI-читаемого кода
Хорошее именование давно было признаком качественного кода, но с приходом AI-агентов оно получило дополнительную, вполне измеримую ценность: осмысленное имя функции или переменной — это контекст, который агент получает бесплатно, без необходимости читать всю реализацию целиком.
Функция calculateShippingCostForRegion сообщает агенту своё назначение мгновенно. Функция calc или process заставляет либо читать всю реализацию, либо строить предположения, которые могут оказаться неверными. Разница особенно заметна в крупных кодовых базах, где агент физически не может держать в контексте каждую реализацию сразу и вынужден полагаться на имена как на компактное резюме поведения.
Это не призыв к длинным именам ради длины: избыточно многословное имя так же вредно для читаемости, как и слишком короткое. Практический ориентир: имя должно однозначно отвечать на вопрос "что это делает" без необходимости заглядывать внутрь, и этот же критерий одинаково хорошо работает и для человека, который придёт в проект через год, и для агента, который читает код впервые в этой сессии.
Отдельная категория проблем с именованием, специфичная именно для agentic-разработки: несогласованность между похожими сущностями, возникающая из-за того, что разные сессии работы с агентом порождали код независимо друг от друга. Один эндпоинт называет параметр userId, другой в том же проекте user_id, третий вообще id без уточнения. По отдельности каждое из этих решений может быть разумным, но вместе они создают путаницу, которая заставляет и агента, и человека каждый раз перепроверять точное имя параметра вместо того, чтобы полагаться на выработанную интуицию. Периодическая проверка согласованности именования по всему проекту, а не только в рамках одной задачи, ловит подобные расхождения раньше, чем они закрепятся окончательно.
Ещё одна практическая деталь: сокращения и аббревиатуры, которые для человека, давно работающего в предметной области, кажутся самоочевидными, для агента без дополнительного контекста неоднозначны. Переменная qty почти наверняка означает количество, но crf или dlt без явного пояснения в документации агент вынужден либо угадывать по контексту использования, либо додумывать значение, которое может не совпадать с изначальным замыслом. Практическое правило простое: если сокращение не входит в общепринятый отраслевой набор (id, url, api и подобные), стоит либо писать полное слово, либо явно задокументировать расшифровку рядом с первым использованием.
Как проектировать API, понятные и человеку, и AI
Внутренние и внешние API страдают от одной и той же проблемы неявных контрактов: поведение, которое не задокументировано и не следует напрямую из сигнатуры, регулярно приводит к тому, что агент (как и новый разработчик) делает неверные предположения об использовании.
Практики, которые снижают эту неопределённость. Явные типы вместо расплывчатых универсальных структур: конкретный тип ответа с именованными полями сообщает больше, чем словарь произвольной формы, который приходится разгадывать по примерам использования. Явные ошибки вместо тихих отказов: функция, которая явно возвращает описанную ошибку, понятнее агенту, чем функция, которая молча возвращает пустое значение при любой проблеме. И консистентность между похожими эндпоинтами: если один ресурс поддерживает пагинацию через параметр page, а другой через offset без явной причины для различия, агент (и человек) будет регулярно путать эти два паттерна между собой.
Ещё один архитектурный принцип, который стоит применять сознательно: API должен явно описывать не только успешный сценарий, но и все ожидаемые состояния ошибки как часть контракта, а не как то, что выясняется только через чтение реализации. Если публичный API возвращает разные коды ошибок в разных ситуациях, но это нигде не описано явно (ни в типах, ни в документации), агент, реализующий клиентский код для этого API, будет вынужден либо угадывать, либо читать реализацию сервера, если у него вообще есть к ней доступ. Явный, задокументированный контракт ошибок убирает эту неопределённость для обеих сторон интеграции.
Полезная практика при проектировании нового API: попросить агента самого попробовать описать, как он будет использовать этот API, до того как реализация будет завершена. Если агент задаёт много уточняющих вопросов о том, что произойдёт в конкретных пограничных случаях, это хороший сигнал, что сам контракт спроектирован недостаточно явно, и стоит его доработать заранее, а не после того, как на этом контракте уже построена клиентская логика.
Версионирование API заслуживает отдельного внимания в этом же контексте. Изменение существующего эндпоинта без версионирования вынуждает агента при каждой правке заново выяснять, какие клиенты используют старое поведение и не сломает ли им что-то новое. Явная версия в пути или в заголовке запроса снимает эту неопределённость: агент может безопасно менять поведение новой версии, зная, что старые клиенты продолжают получать прежний контракт, и ему не нужно вручную прослеживать все места использования эндпоинта по всей кодовой базе, чтобы оценить риск правки.
Тестовое покрытие как страховка для AI-driven разработки
Роль тестов в agentic-разработке разобрана подробно в материале про AI-ассистентов; здесь разберём архитектурный аспект этого вопроса: тестовое покрытие — это не только страховка от регрессий, но и единственный объективный способ проверить, что автономная правка агента не нарушила предположения, о которых сам агент не знал.
Архитектурное следствие этого принципа: критичные, легко нарушаемые инварианты системы (уникальность идентификаторов, согласованность связанных данных, порядок операций там, где он важен) стоит защищать явными тестами до того, как в проекте начинает активно работать агент с широкой автономией, а не после первого инцидента. Тестовое покрытие в этом смысле функционирует как архитектурная граница: то, что покрыто тестами, можно смело доверять автономной правке. То, что не покрыто, требует более осторожного, пошагового подхода независимо от того, насколько тривиальной кажется задача.
Практическое следствие для планирования работы: прежде чем расширять автономию агента на новую часть системы, разумно сначала инвестировать время именно в тестовое покрытие этой части, а не сразу давать задачу с широкими полномочиями поверх непроверенного кода. Это меняет порядок работы по сравнению с привычным "сначала фича, тесты потом, если останется время": для agentic-разработки тесты выгоднее писать заранее, потому что именно они определяют, насколько широкую автономию вообще можно безопасно дать.
Отдельно стоит различать тесты, которые проверяют поведение (что система делает при определённом вводе), и тесты, которые проверяют реализацию (что конкретная функция вызывается определённым образом). Первые остаются полезными при рефакторинге, потому что не зависят от внутреннего устройства кода. Вторые ломаются при любом изменении реализации, даже если поведение системы не изменилось, и создают ложное ощущение регрессии там, где её на самом деле нет. Для agentic-разработки, где рефакторинг происходит чаще и агентом, а не только человеком, тесты поведения оказываются существенно надёжнее ориентиром, чем тесты реализации.
Практический вопрос, который стоит держать в голове при построении тестового покрытия именно под agentic-разработку: что произойдёт, если агент напишет тест, который проходит, но проверяет не то, что нужно. Такой сценарий встречается на практике чаще, чем кажется: агент, получивший задачу написать тест для конкретной функции, иногда пишет тест, подогнанный под текущее (возможно, ошибочное) поведение функции, вместо теста, проверяющего ожидаемое поведение. Практическая защита — периодически, для критичных модулей, явно проверять человеком не только то, что тест проходит, но и то, что он действительно упал бы при правдоподобной ошибке в реализации: временно внести такую ошибку и убедиться, что тест её ловит.
Фича-флаги и AI-driven разработка: как снижать риск
Фича-флаги, давно используемые для постепенного раскатывания изменений, получают дополнительную ценность в контексте работы с AI-агентами: они дают способ включить сгенерированный агентом код в продакшен постепенно и обратимо, не полагаясь на то, что ревью перед мёржем поймало абсолютно всё.
Практический паттерн: значительные изменения, сделанные с высокой автономией агента, стоит выкатывать за флагом, включённым сначала для небольшой доли трафика или для внутреннего тестирования, и только потом расширять на всех пользователей. Это превращает потенциальную ошибку в быстро обнаруживаемый и легко откатываемый инцидент, а не в полноценный сбой продакшена, который приходится откатывать через полноценный релиз. Особенно оправдан этот подход для задач, где агенту дали больше автономии, чем обычно, именно потому что независимая проверка была не такой тщательной, как для критичных участков системы.
Практическая деталь, о которой часто забывают: сам механизм фича-флагов тоже нуждается в архитектурном порядке, иначе он превращается в дополнительный источник сложности вместо снижения риска. Флаги, которые никто не убирает после полного раскатывания изменения, накапливаются в коде и создают комбинаторное разрастание состояний системы, которые почти никто не тестирует явно. Разумная дисциплина: у каждого флага должен быть явный владелец и срок жизни, после которого флаг либо убирается вместе с веткой кода для отключённого состояния, либо осознанно остаётся постоянным переключателем, а не временной мерой предосторожности, забытой навсегда.
Микросервисы vs монолит в эпоху AI-агентов
Вечный архитектурный спор о микросервисах и монолите приобретает новый практический аргумент в контексте agentic-разработки, хотя и не отменяет остальные, уже известные соображения.
Монолит с хорошей внутренней модульностью даёт агенту преимущество полного контекста: вся система доступна для чтения и анализа в рамках одного репозитория, и агент может проследить путь данных от входной точки до конца, не переключаясь между разными кодовыми базами. Микросервисная архитектура даёт преимущество изоляции: агент, работающий над одним сервисом, физически не может случайно затронуть код другого сервиса, потому что тот просто не находится в его рабочем контексте.
Практический вывод не в пользу одного подхода: выбор между монолитом и микросервисами по-прежнему должен определяться теми же соображениями, что и раньше (масштаб команды, требования к независимому деплою, реальная организационная структура), а не соображениями об удобстве работы с AI-агентами как таковыми. Но если выбран монолит, особенно важна внутренняя модульность, о которой шла речь выше, потому что именно она компенсирует отсутствие физической изоляции между частями системы.
Есть и промежуточный вариант, который часто недооценивают: модульный монолит с чёткими внутренними границами, оформленными на уровне языка (отдельные пакеты или модули с явно ограниченным публичным интерфейсом), а не только на уровне соглашений между разработчиками. Такая структура даёт агенту то же преимущество изоляции, что и микросервисы (не может случайно затронуть внутренние детали чужого модуля, если это ограничено на уровне компилятора или системы модулей языка), но без операционных издержек полноценной микросервисной архитектуры: сетевых вызовов, распределённого мониторинга, согласования версий между сервисами. Для проектов небольшого и среднего масштаба это часто оказывается разумным компромиссом между двумя крайностями.
AI-driven разработка и техдолг: как не накопить его быстрее
Технический долг, специфичный для AI-кода, разобран подробно в общем материале про AI для разработки; здесь разберём архитектурные меры профилактики, которые работают на уровне структуры проекта, а не отдельной задачи.
Периодический архитектурный аудит специально под этот тип долга: целевой поиск дублирующихся реализаций одной и той же логики, а не общее ревью корректности, возникающих потому, что агент в разных сессиях решал похожую задачу заново вместо переиспользования существующего кода. Явная, поддерживаемая карта основных модулей и их назначения в документации проекта, которая позволяет быстро проверить перед началом новой задачи, нет ли уже готового решения для похожей проблемы. И регулярный пересмотр самих инструкций для агента, потому что накопление противоречивых или устаревших указаний в CLAUDE.md со временем создаёт архитектурный долг не в коде, а в самом контексте, который агент получает.
Отдельная разновидность этого долга, специфичная именно для agentic-разработки: накопление "почти правильных" решений, каждое из которых по отдельности приемлемо, но которые вместе создают неоднородность, заметно снижающую предсказуемость системы. Один обработчик ошибок реализован через явные коды возврата, другой через исключения, третий через комбинацию того и другого, потому что каждый писался в отдельной сессии без сверки с остальными. По отдельности каждое решение рабочее. Вместе они превращают простую задачу "обработай ошибку так же, как везде в проекте" в задачу, требующую сначала разобраться, а как здесь вообще принято, которой раньше не существовало, потому что человек, писавший весь код сам, интуитивно держал в голове единый стиль.
Практическая мера профилактики: с определённой периодичностью или при достижении заметного объёма изменений, а не после каждой отдельной задачи, прогонять по проекту целенаправленный запрос на поиск именно таких расхождений в подходах к типовым задачам: обработка ошибок, валидация ввода, логирование. Раннее обнаружение и унификация обходится заметно дешевле, чем попытка навести порядок после того, как несколько разных подходов уже глубоко укоренились в разных частях системы.
Наблюдаемость: как отслеживать, что сделал агент
Наблюдаемость системы (логи, метрики, трейсинг) традиционно нужна была для диагностики проблем в продакшене. В контексте agentic-разработки у неё появляется дополнительная функция: возможность проследить, что конкретно изменил агент и как это повлияло на поведение системы, отдельно от общих изменений кода.
Практика, которая окупается: связывать значимые изменения, сделанные с высокой автономией агента, с явными метками в системе логирования или трейсинга, чтобы при появлении аномалии в продакшене можно было быстро сопоставить её с конкретным изменением, а не перебирать весь недавний код вручную. Это не требует специального инструментария сверх уже существующей практики хорошего логирования, но требует сознательной дисциплины: явно помечать, какие изменения прошли с большей автономией и, соответственно, заслуживают более пристального наблюдения в первое время после деплоя.
Полезный практический паттерн: временно повышенный уровень логирования вокруг участков кода, недавно изменённых с высокой автономией, который возвращается к обычному уровню через определённый период после деплоя, если аномалий не обнаружено. Это даёт больше сигнала именно в тот момент, когда риск неожиданного поведения максимален, не создавая постоянной избыточной нагрузки на систему логирования после того, как изменение доказало свою стабильность на практике.
Ещё один аспект наблюдаемости, специфичный для agentic-разработки: отслеживание не только поведения системы в продакшене, но и самого процесса работы агента, если инструмент это позволяет. Сохранённая история того, какие файлы агент читал и менял при выполнении конкретной задачи, превращается в полезный артефакт для последующего разбора, если что-то пошло не так: не нужно гадать, что именно происходило, достаточно посмотреть на зафиксированный след действий.
Полезно также отслеживать метрики самого процесса работы с агентом отдельно от метрик системы: сколько итераций правки потребовалось на задачу, сколько раз агент возвращался к уже изменённому файлу в рамках одной сессии, насколько часто предложенное решение отклонялось на ревью. Эти цифры не заменяют обычный мониторинг продакшена, но со временем складываются в картину того, какие типы задач агент решает уверенно с первой попытки, а какие систематически требуют нескольких итераций или прямого вмешательства человека, что полезно знать заранее при планировании следующей задачи похожего типа.
Как выстроить CI/CD для команды, где часть коммитов от AI
Пайплайн непрерывной интеграции, рассчитанный исключительно на человеческий темп коммитов, начинает работать иначе, когда значительная часть изменений приходит от агента, способного генерировать pull request заметно быстрее человека.
Практические корректировки, которые стоит внести. Более строгие автоматические проверки перед мёржем, потому что объём кода, проходящего через пайплайн, растёт, а внимание человека к каждому отдельному pull request пропорционально не растёт. Явное разделение уровней автоматического одобрения: изменения с низкой ценой ошибки (документация, мелкий рефакторинг с полным покрытием тестами) могут проходить более лёгкий процесс, чем изменения в критичных частях системы, независимо от того, кто их сделал, человек или агент. И отдельный мониторинг скорости мёржа как метрики: если pull request от агента систематически ждут ревью дольше, чем от людей, потому что ревьюеры относятся к ним настороженнее, это стоит либо явно принять как политику, либо целенаправленно исправить.
Стоит также пересмотреть, кто и как получает уведомления о новых pull request. Если объём изменений вырос заметно с внедрением agentic-разработки, а число ревьюеров осталось прежним, полезно ввести приоритизацию: критичные по области изменения (авторизация, платежи, миграции данных) должны быть заметны и назначены на ревью в первую очередь, а не тонуть в общем потоке наравне с мелкими правками документации. Простая маркировка pull request по категории риска, синхронизированная с уровнями автономии из соответствующего раздела CLAUDE.md, решает эту проблему без сложной дополнительной инфраструктуры.
Отдельного упоминания заслуживает вопрос скорости самого пайплайна. Пока сборка и тесты проходили за несколько минут, а pull request от человека появлялся раз в час, длительность прогона почти не влияла на общий темп работы команды. Когда агент способен подготовить несколько pull request за то же время, медленный пайплайн превращается в узкое место, которое ограничивает пропускную способность всей команды сильнее, чем скорость самой разработки. Это делает инвестицию в параллелизацию тестов и кеширование зависимостей сборки заметно более окупаемой, чем она была при исключительно человеческом темпе коммитов.
Границы автономии AI-агента в продакшн-системах
Вопрос о том, где заканчивается разумная автономия агента, не имеет универсального ответа, но есть архитектурный принцип, который помогает провести эту границу осмысленно, а не интуитивно.
Принцип обратимости: чем легче откатить последствия изменения, тем выше автономия, которую разумно дать агенту. Изменение, которое можно откатить одним действием без остаточных эффектов (мелкий рефакторинг, обновление документации, генерация тестов), допускает высокую автономию. Изменение, которое затрагивает уже сохранённые данные, внешние интеграции или необратимые операции (списание средств, отправка уведомлений пользователям, изменение схемы данных без пути отката), требует минимальной автономии независимо от того, насколько тривиальной кажется сама правка кода.
Практический механизм, который реализует этот принцип на уровне архитектуры, а не только процесса: явное разделение уровней доступа для агента, синхронизированное с этим же критерием обратимости. Прямой доступ к продакшн-базе данных не должен быть доступен агенту без явного, разового разрешения в конкретной сессии, даже если в остальном автономия высокая, просто потому что цена ошибки в этой конкретной области принципиально выше, чем в большинстве остальных задач.
Стоит явно проговорить границу между автономией на уровне кода и автономией на уровне инфраструктуры, потому что их легко смешать при формулировании правил доступа. Агент, которому разрешено самостоятельно править бизнес-логику обработки заказа, необязательно должен иметь такое же право на изменение конфигурации продакшн-сервера или прав доступа к облачным ресурсам: это принципиально разные категории риска, и разрешение на одну не должно молчаливо подразумевать разрешение на другую. Явный, отдельный список прав для каждой категории (изменение кода, изменение инфраструктуры, доступ к секретам, доступ к продакшн-данным) избавляет от необходимости каждый раз заново решать эту границу в моменте, когда решение принимается под давлением срочной задачи.
Кейс: рефакторинг архитектуры под AI-агентов
Когда я только начал активно работать с Claude Code над этим сайтом, структура проекта была организована так, как я привык структурировать код для себя самого: удобно, но без явного описания, почему что устроено именно так. Первые недели агент регулярно предлагал архитектурные решения, которые технически работали, но не соответствовали уже существующим паттернам в других частях проекта, просто потому что этих паттернов нигде не было явно зафиксировано.
Переломный момент случился, когда я потратил один вечер на то, чтобы явно описать структуру каждой части проекта в CLAUDE.md: не общими словами, а конкретной таблицей директорий с описанием и портами, списком команд для каждой части, и явными пометками вроде "миграции пишутся идемпотентно через INSERT OR IGNORE, а не отдельными файлами". После этого качество предложений агента заметно выросло не потому, что модель стала умнее, а потому что ей больше не нужно было угадывать контекст, который раньше существовал только у меня в голове.
Практический вывод для себя: архитектурные решения, которые кажутся самоочевидными, потому что ты сам их принимал, самоочевидны только для тебя. Явная фиксация этих решений в документации, читаемой агентом, окупается почти сразу же, а не через абстрактную "экономию времени в будущем".
С тех пор у меня появилась привычка, которая изначально казалась избыточной, а на практике оказалась одной из самых окупаемых: каждый раз, когда я замечаю, что объясняю агенту в чате что-то, что явно не разовая деталь конкретной задачи, а общее правило проекта, я останавливаюсь и переношу это объяснение прямо в CLAUDE.md, вместо того чтобы просто продолжить работу с уже данным в чате пояснением. Занимает это минуту-две, но правило, зафиксированное в файле, больше не нужно объяснять заново в следующей сессии, а правило, оставшееся только в истории чата конкретного разговора, забывается вместе с этим разговором и всплывает снова только когда агент в очередной раз наступает на те же грабли.
Куда двигаться дальше
Архитектура — только одна часть картины того, как AI меняет инженерную работу в целом. AI для разработки: как нейросети меняют инженерную работу разбирает эту картину полностью, включая роль, найм, техдолг и другие изменившиеся процессы.
Если интересна именно практика повседневной работы с конкретным агентом (настройка, CLAUDE.md, ревью, границы автономии на уровне отдельной задачи, а не архитектуры целиком), AI-ассистенты в разработке разбирает это подробно и с личным опытом.
Заключение
- Архитектурные решения, которые раньше были вопросом удобства или постепенно усваивались новыми сотрудниками, теперь напрямую определяют, насколько эффективно AI-агент способен работать с проектом с первой сессии.
- Документация для агента (CLAUDE.md, AGENTS.md или аналог) требует конкретных, действенных деталей и должна обновляться в том же темпе, что и код, а не жить отдельно от него.
- Принцип обратимости — рабочий критерий для определения границ автономии агента: чем легче откатить последствия, тем больше автономии разумно дать.
- Архитектурные решения, самоочевидные для того, кто их принимал, не самоочевидны ни для нового человека в команде, ни для агента. Явная фиксация этих решений не бюрократия, а прямая инвестиция в качество результата.
Комментарии
Комментариев пока нет. Будь первым.