Последние полгода я почти не пишу код руками. И, пожалуй, это лучшее изменение в моём процессе разработки за последние годы.
Нет, я не перестал быть разработчиком. Просто моя работа изменилась. Раньше большую часть времени я писал код сам. Теперь я проектирую инженерную систему, внутри которой этот код пишет AI. Моя задача — не объяснить модели, что нужно сделать, а создать среду, в которой она физически не сможет принять неправильное решение.
В этой статье я покажу, как устроена моя система разработки и почему именно такой подход позволяет использовать AI в реальных проектах без потери качества.
Вы узнаете:
-
как Git превратился из системы контроля версий в источник контекста для AI;
-
зачем нужны Git Hooks, линтеры, тесты и CI, если код пишет AI;
-
почему я использую агентов, команды и skills вместо длинных промптов;
-
как организовать правила так, чтобы AI оставался исполнителем, а не принимал архитектурные решения;
-
почему воспроизводимая инфраструктура важнее, чем выбор конкретной модели.
Это не статья про очередной AI-инструмент и не набор «волшебных» промптов. Это рассказ о том, как я выстроил инженерную систему, в которой AI стал полноценной частью процесса разработки.
Проблема, которую многие не замечают
За последний год я много смотрел, как люди используют AI в разработке. Сценарий почти всегда одинаковый: открывается чат, формируется большой промпт, модель генерирует код, дальше идут итерации “поправь это”, “добавь вот это”, “сделай чуть иначе”.
На небольших задачах это выглядит впечатляюще. На уровне прототипа — почти магия.
Но если проект живёт дольше нескольких недель, начинает проявляться другая картина. Модель постепенно теряет согласованность решений. Появляются дублирующиеся абстракции, архитектурные решения начинают конфликтовать друг с другом, а кодовая база становится смесью разных стилей и логик.
И в какой-то момент возникает ощущение, что AI “перестал понимать проект”.
Но проблема здесь не в понимании.
Проблема в том, что у него нет устойчивой среды, которая ограничивает его поведение.
Мы пытаемся использовать модель как автономного разработчика, хотя на практике она гораздо стабильнее работает в роли исполнителя внутри заранее определённой системы правил.
Сдвиг в подходе: от промптов к системе
Я довольно быстро перестал верить в идею “идеального промпта”. Вместо этого я начал смещать фокус в другую сторону — не на формулировку запроса, а на проектирование среды выполнения.
Если упростить, то я начал относиться к AI не как к программисту, а как к компилятору с очень гибким входом. И если компилятор начинает выдавать хаотичный результат — проблему нужно решать не на уровне входных данных, а на уровне правил системы.
С этого момента проектирование инфраструктуры стало важнее написания кода.
Из чего состоит моя система разработки
Прежде чем AI вообще начинает писать код, в проекте уже должно существовать множество ограничений. Причём это не “рекомендации”, а реальные механизмы, которые физически не позволяют нарушать договорённости.
В моём случае система собирается как слоёный стек.
Поэтому каждый новый проект я начинаю не с написания кода, а с настройки инфраструктуры:
-
Git и соглашения по работе с репозиторием;
-
Git Hooks;
-
линтеры и статические анализаторы;
-
автотесты;
-
CI;
-
правила для Claude Code;
-
skills, агенты и команды.
Важно, что порядок здесь принципиален. Код не является отправной точкой. Он появляется последним слоем поверх уже готовой системы ограничений.
И именно это меняет поведение AI радикально.
Git — это уже не просто система контроля версий
Раньше Git для меня был довольно утилитарной вещью. Это был просто инструмент контроля версий.
С появлением AI его роль изменилась.
Я стал замечать, что Git начинает работать как источник контекста для модели. Не в абстрактном смысле “можно посмотреть историю”, а вполне практическом: через структуру коммитов и веток модель восстанавливает логику проекта.
И это оказалось критически важным.
Когда AI работает с кодовой базой, у него нет устойчивой памяти между задачами. Всё, что он “понимает” о проекте, он извлекает из текущего состояния репозитория. И если этот репозиторий устроен хаотично, модель начинает принимать решения в вакууме.
Поэтому я начал относиться к Git как к части архитектуры системы, а не как к инструменту разработчика.
Каждая задача в проекте у меня начинается не с кода, а с Issue. Это не формальность и не процесс ради процесса — это способ зафиксировать контекст в системе, которая будет потом интерпретироваться AI.
Под каждую задачу создаётся отдельная ветка, в названии которой обязательно присутствует номер Issue.
issues-123
Коммиты с номерами задач усиливают этот эффект. Они превращают историю проекта в последовательность осмысленных шагов, а не в набор разрозненных изменений.
issues-123 | add user registration
На практике такой подход даёт сразу несколько преимуществ.
Во-первых, история проекта становится понятной человеку. По номеру Issue всегда можно быстро найти обсуждение задачи, понять причины изменений и восстановить контекст.
Во-вторых, это помогает самому AI. Когда Claude Code работает с проектом, он анализирует историю репозитория и гораздо лучше понимает, к какой задаче относятся изменения и почему код выглядит именно так.
И наконец, это создаёт единообразие. Независимо от того, кто выполняет задачу — разработчик или AI, структура репозитория всегда остаётся одинаковой.
Git Hooks — первая линия защиты от ошибок AI
После того как структура Git настроена, следующий шаг — автоматические проверки.
Я придерживаюсь простого правила:
Если ошибку можно проверить автоматически, её не должен проверять человек.
Именно поэтому каждый мой проект содержит набор Git Hooks.
Мой набор скриптов для Git Hooks — https://github.com/prog-time/git-hooks
Они запускаются автоматически при создании коммита или перед отправкой изменений в удалённый репозиторий и проверяют всё, что можно проверить без участия разработчика.
Например:
-
корректность имени ветки;
-
формат сообщения коммита;
-
линтеры;
-
статический анализ;
-
unit-тесты;
-
интеграционные тесты;
-
форматирование кода.
Если хотя бы одна проверка завершается с ошибкой, коммит или push просто не выполняется.
Все проверки вынесены в отдельные Bash-скрипты, которые лежат внутри проекта в директории linting.
Проверка качества кода
Для каждого языка программирования используются собственные инструменты.
Например, в PHP-проектах это:
-
PHP CS Fixer — единый стиль оформления;
-
PHPStan — статический анализ;
-
Composer Validate — проверка composer.json.
Для JavaScript и TypeScript:
-
ESLint;
-
TypeScript Compiler.
Для HTML, CSS и SCSS:
-
Prettier;
-
Stylelint.
Локальная разработка и CI используют один и тот же механизм проверки качества. Это исключает ситуацию, когда код успешно проходит локальные проверки, но неожиданно падает после отправки в репозиторий.
Проверка конфигурации
Очень часто ошибки появляются вовсе не в коде.
Поэтому отдельно проверяются:
-
YAML и YML (yamllint);
-
GitHub Actions (actionlint);
-
composer.json;
-
package.json;
-
Docker Compose;
-
Shell-скрипты (shellcheck).
Проверка безопасности
AI, как и человек, может случайно добавить в репозиторий:
-
API-ключ;
-
токен;
-
пароль;
-
приватный сертификат.
Чтобы этого не произошло, перед каждым коммитом запускается проверка секретов (gitleaks).
Такие ошибки лучше обнаружить локально, чем после публикации репозитория.
Проверка документации
Документация — такая же часть проекта, как и исходный код.
Поэтому Markdown-файлы тоже проходят проверки.
Например:
-
корректность синтаксиса;
-
битые ссылки;
-
единый стиль оформления.
Сегодня существует огромное количество отличных линтеров и анализаторов.
Что в итоге делает этот слой
Все эти проверки работают одинаково как для меня, так и для Claude Code.
AI не нужно помнить десятки правил оформления кода или знать особенности каждого линтера. Его задача — написать решение, которое успешно пройдёт все проверки.
Именно поэтому я воспринимаю линтеры и статические анализаторы не как инструменты проверки качества, а как контракты, которые определяют правила разработки проекта.
Каждая новая автоматическая проверка делает поведение AI более предсказуемым и постепенно сокращает количество ошибок, которые приходится исправлять вручную.
CI — единый стандарт качества для всех проектов
Локальные проверки — это хорошо. Но доверять только им нельзя.
Разработчик может отключить Git Hooks, пропустить запуск тестов или случайно изменить конфигурацию. AI тоже не застрахован от подобных ошибок.
Именно поэтому финальное решение всегда остаётся за CI.
Ни один Pull Request в моих проектах не может быть объединён, пока не пройдут все обязательные проверки.
Причём я стараюсь придерживаться одного важного правила.
Локальные проверки и проверки в CI должны быть максимально одинаковыми.
Если локально запускаются линтеры, статический анализ и тесты, то абсолютно тот же набор проверок должен выполняться и в CI.
Это позволяет избежать классической ситуации:
«У меня всё работает.»
Если код не проходит CI, значит задача не выполнена.
За несколько лет у меня накопилась довольно большая библиотека GitHub Actions, которые я использую практически во всех своих проектах.
Вместо того чтобы каждый раз писать workflow с нуля, я вынес их в отдельный репозиторий и постоянно дорабатываю.
https://github.com/prog-time/workflows
Каждый новый проект использует уже готовые шаблоны.
Это даёт сразу несколько преимуществ:
-
одинаковые проверки во всех проектах;
-
единый стиль построения CI;
-
быстрое подключение нового проекта;
-
исправления автоматически переиспользуются в остальных репозиториях.
Но самое главное правило касается AI.
Claude Code не имеет права самостоятельно придумывать CI.
Все workflow считаются частью инфраструктуры проекта. Если нужно изменить пайплайн, AI должен использовать существующие шаблоны или доработать их, а не генерировать новые «магические» GitHub Actions.
Такой подход делает поведение AI предсказуемым.
Именно поэтому большую часть времени я трачу не на ревью кода, а на развитие самих проверок.
Каждая новая проверка уменьшает вероятность того, что одинаковая ошибка когда-нибудь повторится снова.
Правила для Claude Code
Когда я дошёл до этого слоя, стало понятно, что все предыдущие ограничения — Git, Hooks, CI — решают только одну часть проблемы. Они хорошо ловят ошибки и фиксируют качество результата.
Но они почти не влияют на то, как именно AI принимает решения внутри проекта.
И вот здесь начинается самая сложная часть: поведение агента в процессе работы.
Я перестал рассматривать Claude Code как “инструмент, который выполняет промпты”. В какой-то момент стало более точным думать о нём как о системе исполнения ролей внутри проекта.
И эти роли должны быть строго определены.
Сдвиг в мышлении: от инструкций к контрактам
Когда я только начал использовать Claude Code, очень быстро понял, что одной большой инструкции недостаточно.
Если AI одновременно создаёт задачи, пишет код, меняет CI, обновляет документацию и принимает архитектурные решения, его поведение становится непредсказуемым.
Поэтому я разделил ответственность на три уровня:
-
агенты отвечают за конкретную роль;
-
команды выполняют простые действия;
-
skills координируют несколько действий в единый процесс.
Такое разделение оказалось намного проще поддерживать и развивать.
Агенты
Агент — это аналог участника команды с чётко определённой зоной ответственности.
Каждый агент выполняет только свою работу и не выходит за её пределы.
У меня агенты бывают двух типов:
-
глобальные (
~/.claude) — содержат общие правила, не зависящие от языка или проекта; -
локальные (
.claudeвнутри проекта) — описывают особенности конкретного проекта: архитектуру, code style, типизацию, правила работы с фреймворком и другие соглашения.
Например, агент task-writer отвечает исключительно за создание задач.
Он:
-
получает информацию о репозитории из
origin; -
анализирует существующие Issues, чтобы избежать дублирования;
-
читает шаблоны проекта;
-
формирует описание задачи, критерии приёмки, связи между задачами, исполнителя и остальные поля.
После этого его работа заканчивается. Он не пишет код, не создаёт ветки и не занимается CI.
У каждого агента есть одна ответственность.
Именно поэтому их поведение остаётся предсказуемым.
Команды
Если агент — это роль, то команда — это конкретное действие.
Команда не принимает решений и не хранит контекст. Она просто описывает последовательность уже известных операций.
Например, команда создания задачи выглядит для меня как одна простая команда.
После её запуска Claude:
-
передаёт работу агенту
task-writer; -
сохраняет локальную копию задачи в каталоге
/tasks; -
публикует Issue в GitHub.
Можно спросить: зачем вообще нужны команды, если всё это умеет делать агент?
Причина проста.
Иногда мне нужно только подготовить описание задачи и обсудить его в чате, не публикуя Issue.
В этом случае я вызываю самого агента.
А когда задача должна пройти весь процесс целиком, использую готовую команду.
То есть агент — это исполнитель, а команда — удобная точка входа в его работу.
Скилы
Самый верхний уровень — skills.
Если команда выполняет одно действие, то skill описывает уже целый сценарий работы.
Сам skill ничего не делает. Он лишь координирует работу нескольких агентов и команд.
Например, skill ci-setup полностью автоматизирует настройку CI.
Последовательность выглядит так:
-
агент
tech_leadанализирует проект и определяет используемый стек; -
выбираются подходящие шаблоны из моего репозитория
prog-time/workflows; -
на их основе создаются файлы в
.github/workflows.
Ключевое ограничение здесь принципиально.
AI не имеет права самостоятельно придумывать новый CI. Он может использовать только уже существующие шаблоны, которые прошли проверку временем.
Именно поэтому каждый новый проект получает одинаковые проверки и одинаковые стандарты качества.
Почему это всё вообще работает
Когда смотришь на эту систему со стороны, она может выглядеть избыточной. Много ролей, много правил, много уровней.
Но на практике это решает одну простую проблему: устранение неопределённости в поведении AI.
Без этой структуры модель постоянно пытается “оптимизировать” процесс разработки, иногда разрушая архитектуру.
С этой структурой она перестаёт принимать стратегические решения и начинает работать как детерминированный исполнитель.
Как я храню правила: один источник истины для всех проектов
Когда система из агентов, команд и skills стала достаточно большой, появилась новая проблема.
Все правила жили внутри ~/.claude.
Пока работаешь на одном компьютере, этого почти не замечаешь. Но стоит перейти на другую машину, создать новый проект или подключить коллегу — выясняется, что вся система существует только в одном окружении.
Правила начинают расходиться между компьютерами, какие-то изменения забывают перенести вручную, а через несколько месяцев уже невозможно ответить на простой вопрос: какая конфигурация считается актуальной?
В этот момент я понял, что конфигурация AI ничем не отличается от исходного кода.
Она тоже должна иметь единый источник истины, храниться в Git и быть воспроизводимой.
Именно так появился claude-config-template.
Как работает claude-config-template: принцип, на котором всё держится
Проект claude-config-template построен на очень простой, но мощной идее: не менять способ работы Claude Code, а вынести его конфигурацию наружу и сделать её управляемой.
Вместо того чтобы редактировать содержимое ~/.claude напрямую (как это обычно и происходит), ты начинаешь рассматривать эту папку как собранный артефакт, а не источник истины.
Источник истины — это Git-репозиторий.
Вся магия сводится к трём шагам:
-
Ты хранишь структуру
.claudeодин в один внутри репозитория -
Этот репозиторий становится центром управления правилами
-
В реальной системе используется не копирование, а симлинки
То есть:
-
в репозитории у тебя лежит, например:
-
agents/ -
skills/ -
commands/ -
hooks/ -
mcp/
-
-
а в
~/.claudeэти же директории просто ссылаются на файлы из репозитория
Это ключевой момент: ты не дублируешь конфигурацию — ты подключаешь её.
Главное, что даёт этот подход — это не просто удобство.
Он меняет саму модель работы:
-
конфигурация становится воспроизводимой
-
команда получает единое поведение AI
-
правила перестают быть «магией на одной машине»
И именно поэтому claude-config-template — это не просто шаблон, а инфраструктурный слой для работы с AI.
Итог
Вся статья сводится к одной простой мысли: как только AI начинает влиять на код, он перестаёт быть «личным инструментом» и становится частью инженерной системы. А значит, к нему должны применяться те же принципы — структура, воспроизводимость, контроль версий и единые стандарты.
Подход с вынесением конфигурации в репозиторий и использованием шаблона вроде claude-config-template позволяет превратить разрозненные локальные правила в управляемую систему. Конфиг становится переносимым, единым для команды и независимым от конкретной машины или аккаунта.
В результате AI начинает работать предсказуемо: поведение стандартизировано, качество контролируется, а знания не теряются. И именно в этот момент он становится не просто помощником, а полноценной частью инфраструктуры разработки.
ссылка на оригинал статьи https://habr.com/ru/articles/1056162/