Как я заставил ИИ писать код по книжке: Clean Architecture + TDD на автопилоте

Как я заставил ИИ писать код по книжке: Clean Architecture + TDD на автопилоте

Это продолжение первой статьи про взрослый вайб-код для разработчиков, перешедших на тёмную сторону. Ради этой части, по сути, и писалась первая: меня попросили опубликовать свой ИИ-фреймворк, в котором сейчас создаётся 99% моего кода. Делюсь.

Меня зовут Саша Раковский. Работаю техлидом в расчётном центре одного из крупнейших банков РФ, где ежедневно проводятся миллионы платежей, а ошибка может стоить сотни миллионов рублей. Законченный фанат экстремального программирования — значит, DDD, TDD и всего, что с ним связано. Эти подходы редкие и сложные, поэтому делюсь опытом. Если интересно — добро пожаловать.

В прошлой статье я разобрал основы ИИ-разработки и сформулировал три ключевых тезиса:

  • На голых промптах далеко не уедешь. Нужен системный подход: управление контекстом, исправление повторяющихся ошибок, шаблоны. Без ИИ-фреймворка — никак.
  • Автотесты — центральный элемент ИИ-разработки. Софт — это совокупность поведения. Зелёный тест — единица поведения, фундаментальная частица кода.
  • Автономная ИИ-разработка — пока фантастика. Даже лучшие модели ошибаются непредсказуемо. Человеческое ревью обязательно.

Итог: нужен фреймворк, построенный вокруг автотестов и частого ревью. Чем меньше кода на каждом этапе — тем выше шанс заметить ошибку.

Из известных мне опенсорсных решений — только Superpowers. Это неплохой лёгкий фреймворк для тех, кто ценит дисциплину, но предпочитает минимализм. Однако он слишком лёгковесный, противоречит ATDD и плохо встраивается в структурированные процессы.

У меня же в процессе работы родилось собственное решение — заточенное под «книжный подход», принятый в нашей команде. Оно показало хорошие результаты, поэтому делюсь им по просьбам подписчиков.

Фреймворк проверен за 3,5 месяца, 4000 коммитов, 1500 тестов (из них ~350 e2e), 25 тыс. строк продакшн-кода (12k Java, 12k TS/TSX) и столько же тестового кода.

Концепция

Любой софт — это совокупность поведения. Каждое поведение должно быть покрыто тест-кейсом. Хороший софт — это совокупность зелёных тест-кейсов. Эта идея легла в основу фреймворка.

Верхнеуровнево процесс выглядит так:

  • Описание продукта + список пользовательских историй
  • Для каждой истории:
    • Этап спецификации: интервью, проектирование требований, генерация тест-кейсов
    • Этап реализации: TDD-цикл по каждому кейсу — красный тест → зелёный тест

Истории — это минимально независимые фичи, каждая из которых приносит отдельную ценность. Как говорил Кент Бек: «Tell me your story». Например: «Однажды я забыл пароль» → фича «Сброс пароля».

Разработка начинается с постановки требований: описание, критерии приёмки, API, макеты. На их основе формируется тест-план — главный артефакт для каждой истории.

Когда тест-план готов, фреймворк проходит по кейсам в TDD-стиле, реализуя их один за другим, с остановками на ревью. Когда все кейсы зелёные — история завершена.

Центральный скилл: /continue

Ключевой элемент — скилл /continue. Он анализирует текущее состояние проекта (список историй и их progress.md) и определяет следующий шаг.

Для демонстрации я подготовил пример — Kanban-доску с тремя историями в stories.md:

  1. Создать таску
  2. Передвинуть таску в другую колонку
  3. Изменить/удалить таску

Рассмотрим, как /continue работает с каждой:

  • История #3: не начата. /continue 3 стартует с интервью, проектирует API, создаёт макеты, генерирует тест-кейсы.
  • История #2: спека есть, разработка не начата. /continue 2 начнёт с написания acceptance-теста и пойдёт по TDD-циклу, останавливаясь на каждом шаге для ревью.
  • История #1: бэкенд готов, фронт частично сделан. /continue 1 продолжит с последнего незавершённого фронтового кейса.

Ограничение: фреймворк изначально заточен под серверные приложения. Для мобильных, десктопных, embedded-систем или игр может потребоваться адаптация через скилл /prompt-update.

progress.md

Каждая история имеет свой progress.md — чек-лист, фиксирующий прогресс. Он разбит на фазы:

  • Спецификация
  • Реализация:
    • Бэкенд
    • Интеграции
    • Фронтенд
    • Безопасность
    • Нагрузка
    • Инфраструктура

Спецификация включает: интервью, описание, макеты, API, тест-план.

После каждого шага /continue отмечает его в progress.md, делает коммит и ожидает ревью. После подтверждения — переходит к следующему.

Фаза реализации состоит из кейсов, сгенерированных на этапе спецификации. Каждый кейс разбивается на TDD-шаги. Фреймворк навязывает ATDD: большой TDD-цикл охватывает несколько маленьких.

Например, для бэкенда:

  • Красный acceptance-тест
  • Красный usecase-тест → зелёный usecase-тест
  • Красный адаптер-тест (например, контроллер) → зелёный
  • ... аналогично для других адаптеров
  • Зелёный acceptance-тест

После каждого шага — коммит. Это позволяет изолированно смотреть изменения.

Архитектурные правила

Фреймворк построен на Clean Architecture и гексагональной архитектуре с ATDD. Такой подход описан в книгах «Get Your Hands Dirty on Clean Architecture» (Tom Hombergs) и «Hexagonal Architecture Explained» (Alistair Cockburn).

Если вы используете другую архитектуру или стиль тестирования — потребуется адаптация через /prompt-update.

Quality gates

LLM учатся на разном по качеству коде. Чтобы сгладить типовые ошибки, я добавил контрольные точки — quality gates:

  • На красном шаге: ревью строгости тестов, архитектуры + рефакторинг
  • На зелёном шаге: рефакторинг + проверка покрытия тестами

Каждый gate включает чек-лист, по которому LLM обязана отчитаться: есть ли нарушение.

После gates — коммит. Человек смотрит diff, оставляет замечания. Если всё ок — сбрасывает контекст и запускает /continue. Фреймворк идёт дальше, а мы переходим к другому потоку.

Контекст-менеджмент

Каждый шаг разбит на два этапа: написание кода/теста и последующие gates. Чтобы активности не мешали друг другу, они запускаются в отдельных агентах.

Ещё один приём — progress.md. Он позволяет сбрасывать контекст после каждого шага и загружать только необходимое, повышая надёжность вывода.

Самоулучшение

Если сталкиваюсь с повторяющейся ошибкой — вызываю /prompt-update с описанием проблемы. После исправления проверяю, что фреймворк больше не делает эту ошибку.

Так, день за днём, фреймворк обрастает правилами, становится эффективнее — и порой менее послушным. Чем больше правил, тем выше шанс, что LLM что-то забудет.

Как попробовать

Я теперь пишу код только с этим фреймворком. Если хотите попробовать «взрослый» ИИ-процесс вместо хаотичного вайб-кодинга — у меня есть два репозитория:

  • Пример Kanban-доски на Java + React
  • Голый фреймворк без примеров

Рекомендую начать с первого.

Рекомендуемый сценарий

  1. У вас должна быть подписка на Claude или совместимую LLM (например, GLM5 от Z.ai).
  2. Склонируйте репозиторий с Kanban-доской. Лучше три копии — в трёх IDE (или через worktrees).
  3. В каждой IDE запустите /continue 1, /continue 2, /continue 3.
  4. В первой IDE: продолжится фронтенд-разработка (Selenium-тест).
  5. Во второй: начнётся бэкенд с acceptance-теста.
  6. В третьей: стартует с интервью — история ещё не начата.

Про параллелизацию

Один цикл /continue занимает от 5 до 20 минут. Иногда — до часа, если LLM перезапускает долгие тесты.

Это главный недостаток: цикл долгий. Но при достаточном числе задач можно запускать несколько потоков параллельно. Скорость разработки будет определяться не скоростью ИИ, а скоростью ревью.

Сейчас модели становятся быстрее — через полгода этот недостаток, вероятно, исчезнет.

Почему отдельные репозитории, а не worktree? Можно и worktree, но отдельные репы удобнее.

У меня — 6 параллельных IDE: 4–5 из них крутят /continue, остальные — техдолг, рефакторинги, оптимизация пайпов.

Чтобы избежать конфликтов портов, в репозиториях с суффиксами вроде continue-example1 фреймворк автоматически выставляет уникальные порты.

Как стартовать с нуля

Альтернатива — пустой фреймворк. Я потратил много времени, чтобы он мог из пустой репы доехать до MVP только через /continue и небольшие корректировки.

Как начать:

  1. Склонируйте пустой фреймворк.
  2. Заполните:
    • BriefProductDescription.md — описание продукта
    • ExpectedLoad.md — нагрузка
    • technology.md — стек
  3. Сгенерируйте список историй с помощью Claude и запишите в stories.md.
  4. Запускайте /continue — и идите пить чай.

Я отвязал фреймворк от Java и сделал шаблоны под 90% популярных технологий. Он работает, но может выдавать «культурный шок» — результат может не соответствовать стилю вашего языка. В этом случае — /prompt-update в помощь.

Полезные фишки

/prompt-update

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

Рядом — /prompt-refactor. Ищет слабые места во фреймворке. Но может предлагать ерунду, поэтому требует глубокого понимания контекста. Например: /prompt-refactor last commit.

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

/continue умеет работать и с тасками. Они хранятся в отдельной папке и после завершения мигрируют в /done. Использую не реже раза в день.

Ещё одно применение агентов — аналитика. Claude отлично ищет в документации, исследует API, проверяет через curl, делает локальные копии данных, даже скрейпит сайты, обходя антиботы.

Он справляется и с анализом больших данных: формулирует правила, ищет закономерности, делегирует вычисления в код.

Но результаты теряются после сессии, а контекст засоряется. Чтобы фиксировать находки — есть скилл /doc.

Портирование и ограничения

Фреймворк имеет ограничения:

  • Разработан под конкретный стек
  • Заточен под Clean Architecture, DDD, OOP, подходы из книги Martin Fowler
  • Ориентирован на ATDD и гексагональную архитектуру (adapter + application tests)
  • Поддерживает веб-приложения (бэк + фронт)
  • Использует английский для экономии токенов

От технологии я его частично отвязал, но от Clean Architecture и ATDD — нет и не планирую. Если они вам чужды — лучше попробовать SuperPowers.

Если решение понравилось — адаптируйте его через /prompt-update. Настройка займёт час-два.

Техника безопасности

  • ИИ не заменяет разработчика. Если баг пролезет на ревью — он уедет в прод.
  • Принцип «железо дешевле людей». Фреймворк экономит время, тратя токены. У меня $200 на Claude иногда не хватает при работе в 5 потоков.
  • LLM нарушают правила. Фреймворк может сойти с рельсов. Нужно подправлять — чаще всего повторным вызовом /refactor или /test-review на чистом контексте.
  • Разработан под один проект. На другом стеке, архитектуре или подходе может работать хуже.
  • Под вкус автора. Если у вас другие предпочтения — используйте /prompt-update или SuperPowers.
  • Молодой и неполный. Требует постоянной доработки через /prompt-update.

Приятной эксплуатации.

Читать оригинал