Петля «починил одно — сломал другое»
почему она возникает и как из неё выйти
Что это
Знакомая картина: починили ошибку A — появилась B. Починили B — вернулась A. Третий круг, четвёртый, и кажется, что код сопротивляется.
Петля возникает не от невезения. У неё три причины, и все три устранимы.
Почему так происходит
Причина 1. ИИ не видит целого
Каждая правка делается локально: вот эта функция, вот эта ошибка. Что эта функция вызывается ещё в трёх местах с другими ожиданиями — ИИ не знает, если ему не показали.
Поэтому правка, верная сама по себе, ломает соседнее.
Причина 2. Чинится симптом
Если каждый раз править место падения, а не причину, ошибка никуда не девается — она переезжает. Выскакивает в другом месте, под другим именем, и выглядит как новая (статьи 2.12, 2.13).
Причина 3. Контекст сессии засорён
К пятому кругу в разговоре лежат три отменённых решения, два неверных предположения и куча кода, который уже не актуален. ИИ опирается на всё это и начинает противоречить сам себе.
Как выйти
Остановиться и записать
Первое и самое полезное — перестать просить правки и выписать, что известно. Пять строк обычного текста:
A: падает при пустом городе — чинили дважды
B: дублируются записи — появилось после первой починки A
Общее: обе про функцию save_sub
Не проверял: вызывается ли save_sub из двух местЧасто на этом месте петля и кончается: становится видно общее звено.
Зафиксировать поведение тестом
Пока нет проверки, каждая правка — это обмен одной ошибки на другую вслепую. Два теста — на A и на B — превращают игру в угадайку в работу: теперь видно, когда починены оба.
Напиши два теста: один воспроизводит A, второй B.
Оба должны падать на текущем коде. Код не чини.Требование «оба должны падать» существенно — оно доказывает, что тесты действительно проверяют нужное (статья 4.6).
Сузить зону
Если правки трогают полпроекта, каждая задевает лишнее. Явные границы (статья 3.13) резко снижают число побочных поломок:
Меняй только save_sub. Если задачу не решить, не трогая
остальное, — остановись и скажи, что ещё нужно менять.Начать новую сессию
Если круг третий и ответы противоречат друг другу — дело в засорённом контексте. Новая сессия с внятно сформулированной задачей и свежим кодом почти всегда быстрее, чем шестой круг в старой.
Что перенести в новую сессию: текущий код, оба теста, записку из первого шага. Чего не переносить — историю неудачных попыток.
Как сказать ИИ
Когда подозреваешь, что правка заденет лишнее:
Эта функция вызывается где-то ещё? Если да — что в тех
местах сломается от предложенной правки?Когда петля уже закрутилась:
Мы чиним это третий раз: сначала A, потом B, снова A.
Не предлагай правку. Скажи, что общего у этих двух ошибок
и какая может быть одна причина у обеих.Запрет «не предлагай правку» нужен обязательно. Без него ИИ выдаст четвёртую версию кода вместо анализа.
На что смотреть
Каждая правка больше предыдущей. Первая — три строки, вторая — двадцать, третья — новый модуль. Признак, что чинится не то; размер растёт от попыток обойти, а не решить.
«Теперь точно работает». После третьего круга эта фраза ничего не значит, пока нет теста.
Ошибки меняются местами. A и B появляются по очереди, никогда вместе — почти наверняка у них одна причина и одно место.
Правки в разных файлах. Если одна ошибка чинится то здесь, то там, значит, причина не найдена ни разу.
Шпаргалка
Три причины: ИИ не видит целого · чинится симптом · контекст засорён.
Остановись и выпиши, что известно, — часто этого достаточно.
Два теста, оба падающие, превращают угадайку в работу.
Сузь зону правок явной границей.
Третий круг — повод начать новую сессию, перенеся код и тесты.
«Не предлагай правку, скажи, что общего у этих ошибок».