Перейти к содержимому

Генерация кода и структурные правки

Генерация кода — режим, в котором модель по запросу создаёт или изменяет код: пишет функцию, рефакторит модуль, добавляет эндпоинт, обновляет тесты. В отличие от автодополнения, здесь человек формулирует задачу, а не просто продолжает печатать.

Практически важнее не «написать с нуля», а изменить существующее: добавить параметр, протянуть его через слой доступа к данным, поправить три вызова и обновить тесты. Именно такие задачи занимают большую часть рабочего времени, и именно они проверяют, умеет ли инструмент работать с проектом, а не с абстрактным примером.

ФорматЧто делаетКогда уместен
Однофайловая правкаМеняет функцию, блок или файл целикомЛокальная задача с ясными границами
Многофайловый diffСобирает согласованное изменение по нескольким файламНовая функциональность, рефакторинг, миграция API
Структурная трансформацияПереписывает код по правилу, а не по смыслу: переименование, замена вызова, codemodМассовые механические изменения в большом репозитории

Структурные правки — недооценённый сценарий. Когда нужно заменить устаревший вызов в двухстах местах, правило на основе AST или LSP-переименование надёжнее генерации: результат детерминирован, его можно проверить диффом и повторить.

Модель не «редактирует файл» — она возвращает текст или инструкцию, а применяет её среда. От этого зависит очень многое:

  • Search-and-replace блоки. Модель отдаёт фрагмент «найти → заменить». Среда ищет фрагмент в файле дословно и падает, если он не совпал. Дешёво, но чувствительно к пробелам и переименованиям.
  • Полная перезапись файла. Просто, но опасно на больших файлах: модель может потерять код, который не попал в контекст.
  • Правки через инструменты. Среда даёт модели операции read, grep, edit, write с проверкой и подсчётом строк; агент вызывает их по шагам. Это уже агентный режим.
  • Структурные операции. Переименование, извлечение метода, применение codemod — выполняются языковым сервером или AST-инструментом, а не моделью.

Правило: чем более «текстовый» способ применения, тем важнее, чтобы после него запускались компилятор, типы и тесты. Дословное совпадение блока не гарантирует, что изменение осмысленно.

  1. Дайте план до кода. Список затрагиваемых файлов и порядок шагов уменьшает хаотичные правки и облегчает проверку. См. SDD.
  2. Дробите задачу. Три маленьких изменения с проверкой между ними почти всегда лучше одного большого diff.
  3. Покажите проектные паттерны. Один существующий контроллер или тест в контексте работает лучше, чем абзац описания «как у нас принято».
  4. Зафиксируйте границы. «Меняй только файлы в этом модуле» — не формальность: без границы агент тянет правки в соседние слои.
  5. Требуйте проверок. Задача считается выполненной, когда тесты и линтер прошли, а не когда код выглядит правильным.
  • Фантомные API. Метод выглядит знакомо, но не существует в вашей версии библиотеки. Ловится типами и запуском.
  • Дрейф стиля. Каждая правка сама по себе корректна, вместе они дают три способа делать одно и то же.
  • Дублирование абстракций. Модель не видит существующий хелпер и пишет четвёртый по счёту.
  • Потеря кода при перезаписи. Классика больших файлов: часть содержимого не попала в контекст и исчезла из результата.
  • Зелёные тесты при неверном поведении. Если тест писал тот же агент, он мог закрепить ошибку, а не требование.
  • Разрастание diff. Изменение на 40 файлов невозможно осмысленно отревьюить; это не признак эффективности, а риск.
  • Проходит ли сборка и типы — до чтения diff.
  • Покрыто ли новое поведение тестом, который падал до изменения.
  • Нет ли правок за пределами заявленной области.
  • Совпадает ли решение с проектными соглашениями — или это общепринятый паттерн из обучающих данных.
  • Откатывается ли изменение одной командой.