Всем привет!

Есть ощущение, что за последние два года в профессии разработчика изменилось что-то фундаментальное. Не очередной фреймворк. Не новый язык. Не ещё один способ развернуть контейнер. Изменился сам процесс программирования. Я поймал себя на странной мысли: я почти перестал писать код руками. При этом программного обеспечения создаю, кажется, больше, чем раньше. Вместо написания кода я разговариваю с ИИ-агентами, ставлю им задачи, ограничиваю область изменений, проверяю архитектуру, смотрю diff, откатываю неудачные решения и пытаюсь организовать их работу так, чтобы несколько моделей могли одновременно работать над одним проектом и не разрушать его. И меня всё больше занимает вопрос: если код пишет ИИ, то чем в такой системе становится программист? Об этом и хочу поговорить.

Когда за ответом приходилось идти к людям

Когда-то всё было довольно просто. Программируешь, сталкиваешься с багом. Пробуешь исправить его так и эдак. Читаешь документацию. Гуглишь. Проверяешь ответы из Stack Overflow и тематических форумов. Ничего не помогает. И тогда наступает момент отчаяния: регистрируешься на форуме и задаёшь свой вопрос. Потом ждёшь. Кто-то отвечает. Ты уточняешь детали. Тебе объясняют, где ошибся. Иногда начинается спор. Иногда вместе находите решение, которого вообще нигде не было описано. Заодно узнаёшь что-нибудь новое. Так постепенно и рос профессионально.

Сегодня значительную часть этого диалога заменил искусственный интеллект. Он не просто помогает найти документацию. Он объясняет код, предлагает архитектуру, пишет тесты, ищет ошибку, рефакторит модуль и иногда самостоятельно проходит довольно длинную цепочку от задачи до работающего результата. Обращаться к людям приходится реже. И это немного странное ощущение.

Мир действительно изменился

Когда мне было семь лет, уроки информатики проходили на ЭВМ «Искра». В четырнадцать я получил свою первую корочку администратора MS-DOS 6.22 и Windows 95. В девяностые, когда я часами сидел за компьютером, мама могла погладить меня по голове и сказать:

Молодец, сынок. Изучай. Компьютеры — это дорога в будущее.

Сегодня вокруг компьютеров совсем другой разговор: родительский контроль, ограничения экранного времени, цифровой детокс. А ту самую «дорогу в будущее» я, похоже, действительно прошёл довольно далеко. В 2009 году я закончил АНХ, где занимался автоматизацией, и дальше много лет работал по специальности. За это время успел поработать с распределёнными системами, интеграциями, мобильной разработкой, базами данных и достаточно крупной инфраструктурой. Багов тоже видел немало. Один из них я особенно хорошо запомнил.

Ночь, 90 серверов и одно кольцо

После очередного обновления почти 90 серверов перезагрузились — и не вернулись в нормальное состояние. Каждый загружал одно ядро процессора на 100%. Само обновление при этом прошло штатно. Серверы получили новые версии, выполнили скрипты обновления баз данных, записали необходимые данные, обновили службы и запустили их снова. В dev всё работало. В test всё работало. А prod развалился. Причём сразу во всех регионах. Мы сидели в офисе далеко за полночь, перебирали версии и в какой-то момент я сказал коллегам: — Надо расходиться. Если сейчас не нашли причину, лучше поспать и утром посмотреть свежей головой. По регламенту время на устранение неисправности у нас ещё есть.

Утром причина нашлась. На уровне проверки прав отсутствовал прямой запрет на выбор вышестоящего структурного подразделения, если оно уже присутствовало ниже в организационной структуре. Пользователь смог создать данные, которые формально прошли проверки, но породили цикл. Эти изменения отсутствовали в дампе, который использовался для предварительного релиза, поэтому в тестовых средах ошибка не проявилась. Центральный сервер новые данные принял и распространил. Всё продолжало работать до команды сброса кэша организационной структуры. В структуре было несколько тысяч подразделений. И одно кольцо. При перестроении кэша система зависла. Мы исправили данные, добавили необходимые ограничения, восстановили работу и уложились в контрактные сроки.

Почему я вспоминаю об этой истории сейчас? Потому что тогда значительная часть профессии состояла именно в таком процессе: держать в голове устройство системы и искать причинно-следственную связь. Код был важен. Но написание кода было лишь частью работы. Сегодня это стало заметно ещё сильнее.

Я всё меньше программирую сам

За годы работы мне довелось заниматься распределёнными серверными системами, несколькими центрами обработки данных и системами, обслуживавшими десятки тысяч устройств и большое количество пользователей. Были интеграции через SOAP, REST, WebSocket, SIP и другие технологии. Позже я сменил стек на Java и Kotlin и с нуля участвовал в создании нескольких мобильных приложений для крупных организаций. Но сейчас мой рабочий процесс выглядит совсем иначе. Я активно использую несколько ИИ-инструментов: Codex, Claude Code, Gemini, Qwen Code и другие модели. С Claude, например, экспериментирую ещё со времён Claude 3 Sonnet в 2024 году. И постепенно возник парадокс. С одной стороны, мой опыт разработчика никуда не исчез. С другой — непосредственно писать код приходится всё меньше. Большую часть времени я:

  • формулирую задачу;

  • задаю архитектурные ограничения;

  • определяю область файлов, которые агент имеет право изменять;

  • проверяю результат;

  • запускаю тесты и аудит;

  • анализирую diff;

  • согласовываю работу нескольких агентов;

  • иногда откатываю всё, что агент успел сделать.

В какой-то момент мне стало интересно: можно ли построить архитектуру проекта специально под разработку ИИ-агентами? Не пытаться заставить модель работать с кодовой базой, созданной людьми для людей, а изменить саму организацию проекта. Так появилась SAMO.

Что такое SAMO

SAMO — это аббревиатура из четырёх идей:

  • S — SOLID

  • A — Atomic Design

  • M — Morphological Box

  • O — Orchestration

Это пока не стандарт, не академическая теория и не законченный фреймворк. Для меня это прежде всего экспериментальная методика организации исходного кода для AI-only / AI-first разработки. Главная гипотеза очень простая:

Чем меньше произвольных решений приходится принимать ИИ-агенту при поиске и изменении исходного кода, тем надёжнее он работает с большой кодовой базой.

Обычно разработчик может сам решить:

  • как назвать файл;

  • в какой каталог его положить;

  • где создать новый компонент;

  • как организовать зависимости;

  • где хранить тип;

  • куда вынести состояние;

  • создавать ли новый модуль.

Для человека эта свобода удобна. Для ИИ-агента она постепенно превращается в пространство возможных ошибок. Поэтому я попробовал эту свободу сильно ограничить.

Файловая система как часть архитектуры

В SAMO объект исходного кода получает достаточно строгий адрес: <domain>/<cluster>/<joint>/<family>/<file>, где domain определяет предметную область. Например: billing, auth, profile, typography, theme и т.п. Дальше идут уровни, набор которых ограничен правилами архитектуры. Например в качестве: cluster взяты варианты зарезервированных слов языка TypeScript: const, type, interface, class, function, component и data - данные в широком смысле слова. Внутри них допустимы только определённые подкатегории. Например, для компонентов используется структура Atomic Design: atom, molecule, organism, template, page. Получается примерно так: <domain>/component/atom/<family>/. При этом состав файлов внутри конечной папки тоже ограничен. Например:

index.ts
index.svelte
index.story.svelte
state.svelte.ts
test.svelte.ts

Не обязательно должны присутствовать все пять файлов. Но набор возможных имён заранее известен. Это важное отличие. Агенту не требуется каждый раз изобретать: ButtonHelpers.ts, ButtonUtils.ts, button-controller.ts, buttonLogic.ts или ещё какое-нибудь новое название. Он знает адрес объекта и знает допустимые файлы внутри этого адреса. Файловая система начинает работать почти как система типов.

Зачем понадобился морфологический ящик

Идея морфологического анализа интересовала меня давно. В 2019–2021 годах я дополнительно изучал системный и морфологический анализ, инженерно-психологическое проектирование, нейросети и ряд смежных дисциплин. Морфологический подход оказался неожиданно удобным именно для ИИ-разработки. В классическом морфологическом ящике сложный объект раскладывается на параметры и допустимые варианты значений этих параметров. В моём случае объектом стала структура исходного кода. То есть агенту разрешены не все возможные сочетания: domain × cluster × joint × family × file а только те, которые предусмотрены архитектурой. Некоторые комбинации существуют. Некоторые запрещены. А некоторые должны удовлетворять дополнительным правилам. В результате архитектура начинает определять не только то, как желательно писать код, но и то, какие структуры вообще могут существовать в проекте. Для ИИ это оказалось полезным ограничением.

AGENTS.md недостаточно

Сейчас во многих AI-first проектах появляется файл вроде AGENTS.md. В нём разработчик объясняет агенту:

  • как устроен проект;

  • какие команды запускать;

  • что можно менять;

  • что нельзя менять;

  • какие соглашения соблюдать.

Я тоже начинал примерно с этого. Но быстро выяснилось, что текстовой инструкции недостаточно. Если правило существует только в промпте, модель рано или поздно его нарушит. Поэтому часть методики я перенёс из инструкций в исполняемые ограничения. Появились:

  • AGENTS.md;

  • ADR-файлы;

  • индексаторы;

  • архитектурные аудиторы;

  • проверки файловой структуры;

  • скрипты оркестрации;

  • сборочный конвейер;

  • конечный автомат, задающий этапы выполнения задачи.

То есть я стараюсь сделать так, чтобы агент не просто знал правило, а физически получал обратную связь, когда его нарушает. На мой взгляд, это принципиальная разница.

Несколько агентов в одном проекте

Ещё одна причина появления такой структуры — параллельная работа. У меня есть возможность одновременно запускать большое количество моделей, и я экспериментировал в том числе со сценариями работы десятков агентов над одной кодовой базой. Обычно агенты разделяются по domain. Один работает с одной предметной областью, другой — с другой. Это сильно уменьшает количество конфликтов. И здесь неожиданно проявляется ещё одно преимущество строгой адресации. ИИ не нужно долго искать нужный файл по проекту. Если известна архитектурная сущность, достаточно определить её адрес. Условно: profile/component/atom/avatar/. Дальше набор возможных файлов уже известен. Для человека такая система может показаться избыточно строгой. Для нескольких агентов, одновременно изменяющих несколько тысяч файлов, эта строгость становится преимуществом.

Как ведут себя разные модели

За время экспериментов я использовал Codex, Claude Code, Gemini и Qwen Code. Сразу оговорюсь: это не бенчмарк моделей. Я не запускал одинаковый набор синтетических тестов в контролируемых условиях. Это статистика и наблюдения, накопленные в процессе реальной разработки одного проекта. Особенно показательным для меня оказалось случайное удаление файлов.

Модель

Случаев случайного удаления

Удалено файлов

Codex

0

0

Claude Code

1

555

Qwen Code

3

≈ 3 000

Gemini

8

> 10 000

Для меня это оказалось не мелочью, а одним из важных критериев работы с агентами. Когда модель изменяет несколько файлов, ошибку сравнительно легко заметить. Когда одновременно работают несколько агентов и один из них решает удалить целую ветку проекта, цена чрезмерной самостоятельности резко возрастает. При этом количество удалённых файлов само по себе ничего не говорит о «качестве модели вообще». Модели работали над разными задачами, в разных контекстах и получали разный объём работы. Но некоторые особенности поведения проявлялись достаточно устойчиво.

  • Codex в моих задачах оказался наиболее предсказуемым при самостоятельной работе с файловой системой. Он способен довольно далеко продвигаться по задаче и выполнять большие связанные изменения. Иногда его приходится останавливать не потому, что он делает мало, а наоборот — потому что он способен изменить значительно больше, чем от него первоначально ожидалось. При этом случаев случайного удаления файлов у меня не было.

  • Claude Code хорошо показывает себя при разборе архитектуры и больших связанных изменений. Отлично работает с регулярными выражениями и скриптами. Замечательные функции сравнения и внесения массовых изменений в кодовую базу. За всё время у меня был один случай случайного удаления — 555 файлов.

  • Gemini оказался полезен в задачах анализа и согласования решений между несколькими ИИ-агентами. Лучше всех выполняет функции Scrum-мастера и но одновременно оказался наиболее проблемным при операциях с файловой системой: восемь эпизодов случайного удаления и суммарно более 10 тысяч удалённых файлов.

  • Qwen Code мне нравится в исследовательских задачах и при работе с информацией, однако с ним также произошло три эпизода случайного удаления — в общей сложности почти 3 тысячи файлов. Именно такие ситуации заставили меня иначе посмотреть на проблему AI-разработки. Первоначально мне казалось, что главное — составить для агента хорошую инструкцию. Потом стало понятно:

Инструкция, которую агент может нарушить, — это не архитектурное ограничение.

Если двадцать восемь моделей потенциально могут работать с одной кодовой базой, надеяться только на аккуратность модели нельзя. Нужно ограничивать не только то, что агенту сказано делать, но и пространство того, что он вообще способен изменить. Отсюда появились разделение проекта по domain, строгая адресация файлов, архитектурный аудит, правила допустимых комбинаций и оркестрация агентов. И здесь я пришёл к, пожалуй, самому интересному выводу всего эксперимента: качество AI-разработки определяется не только качеством модели. Оно очень сильно зависит от архитектуры среды, в которую эту модель поместили. Один и тот же ИИ-агент в обычной кодовой базе и в системе со строгими границами изменений — это фактически два разных инструмента.

Библиотека как полигон

Параллельно с методикой я развиваю библиотеку визуальных компонентов stylist-svelte на TypeScript и Svelte 5. Она стала для меня своеобразным полигоном. Компонентов много, между ними возникают зависимости, нужны состояния, тесты, stories, документация, повторное использование и постоянный рефакторинг. То есть это достаточно удобная среда для проверки вопроса: может ли ИИ поддерживать большую кодовую базу в порядке, если архитектура специально спроектирована под его работу? Ответ скорее «да», чем «нет» и результаты мне кажутся достаточно интересными, чтобы продолжать эксперимент.

Возможно, мы неправильно понимаем AI-разработку

Сейчас разговор об ИИ в программировании часто сводится к сравнению:

человек написал код за час, а ИИ написал за пять минут.

Но мне кажется, что это довольно поверхностное сравнение. Если ИИ действительно способен выполнять всё большую часть непосредственной работы с исходным кодом, главным вопросом становится не скорость генерации функции. Главный вопрос — архитектура системы, в которой работает агент.

  • Как агент получает контекст?

  • Как определяет границы задачи?

  • Как понимает, какой файл нужно изменить?

  • Как проверяет собственные изменения?

  • Как взаимодействуют несколько агентов?

  • Кто принимает архитектурные решения?

  • Что должно быть описано естественным языком, а что должно контролироваться программно?

  • Как сделать так, чтобы ошибка одного агента не распространялась на весь проект?

  • И наконец: что остаётся человеку?

У меня пока получается примерно такой ответ. Человек постепенно перемещается на уровень выше. От написания строк кода — к проектированию пространства, в котором эти строки могут появляться. От реализации функции — к определению правил. От поиска конкретного файла — к проектированию структуры кодовой базы. От непосредственного программирования — к оркестрации. И мне пока совершенно не очевидно, хорошо это или плохо. Но мне очень интересно посмотреть, куда всё это приведёт.

Зачем я написал эту статью

Я начал текст с разговора о форумах не случайно. ИИ действительно решил огромное количество вопросов, которые раньше мы задавали другим разработчикам. Но есть вопросы, на которые мне как раз не хочется получать ответ от очередной модели. Мне интересно спросить людей.

  • Кто-нибудь из вас уже пришёл к похожему процессу разработки?

  • Пытаетесь ли вы менять архитектуру проектов специально под ИИ-агентов?

  • Как дела с многопоточностью, когда используете много агентов одновременно?

  • Нужна ли вообще строгая файловая типизация или это путь к архитектурной бюрократии?

  • И где, на ваш взгляд, проходит граница между разработчиком и оператором ИИ-системы?

Если тема окажется интересной, в следующей статье могу уже без длинного вступления разобрать SAMO технически:

  • структуру domain / cluster / joint / family;

  • допустимые и запрещённые комбинации;

  • устройство AGENTS.md;

  • ADR;

  • архитектурный аудит;

  • конечный автомат агента;

  • параллельную работу нескольких моделей;

  • и реальные примеры из stylist-svelte.

Пожалуй, именно ради такого разговора с сообществом я всё это и написал.