TL;DR
RefactorAssist — система, которая чинит код после того, как LLM его "улучшила" (рефакторинг), но что-то сломала. Сначала простыми правилами без LLM восстанавливаются забытые импорты и сбалансированные скобки. Если тесты всё равно падают, запускается двухшаговый цикл: сначала LLM объясняет причину сбоя (root cause) и даёт подсказку (hint) — без кода, потом на основе этого объяснения генерирует исправление.
Главная находка: когда LLM рефакторит код, почти четверть всех провалов происходит не из-за синтаксиса, а из-за непонимания контекста и придумывания того, чего не было — модель меняет логику, добавляет несуществующую функциональность, переименовывает переменные наполовину. То есть модель ломает не форму, а смысл, и сама этого не замечает.
Метод решает это в два отдельных шага: сначала LLM ставит диагноз на основе лога ошибки и diff (что именно изменилось между старым и новым кодом), потом отдельным запросом генерирует точечное исправление на основе этого диагноза — вместо того чтобы просить "исправь ошибку" за один раз.
Схема метода
ШАГ 1 (без LLM): Статический ремонт — восстановить забытые импорты,
сбалансировать скобки, поправить явные несоответствия типов
→ рабочий файл или переход к шагу 2
ШАГ 2 (запрос к LLM): Диагноз ошибки — на основе лога ошибки + diff
(что изменилось) → {причина сбоя, подсказка для фикса}
ШАГ 3 (отдельный запрос к LLM): Генерация исправления — на основе
диагноза + diff + кода → исправленный код,
минимальные точечные правки
ШАГ 4: Прогон тестов → если не прошли, вернуться к шагу 2
с новым логом ошибки. Повтор до 10 раз.
Пример применения
Задача: У вас есть Python-скрипт, который выгружает данные из Google Sheets и собирает отчёт. Вы попросили Claude "почистить" код — вынести повторяющуюся логику в функцию. После этого скрипт стал падать с KeyError.
Промпт (шаг 1 — диагноз, без исправлений):
Вот ошибка, которая появилась после того, как ты переписал код:
{текст ошибки}
Вот что именно изменилось (было → стало):
{старый фрагмент кода}
→
{новый фрагмент кода}
Не исправляй пока ничего. Сначала ответь:
1. В чём точная причина ошибки?
2. Что нужно поправить — назови конкретные переменные, ключи или функции.
Промпт (шаг 2 — исправление, отдельным сообщением):
На основе этого диагноза исправь код.
Правки должны быть минимальными и точечными — трогай только то,
что связано с причиной ошибки.
Не меняй остальную логику, не добавляй новых переменных или функций.
Верни весь исправленный код целиком.
Результат: На первом шаге модель выдаст текстовое объяснение причины и подсказку — без кода. Это позволяет проверить, правильно ли модель поняла проблему, до того как она начнёт что-то менять. На втором шаге придёт исправленный код с точечными правками, а не переписанный с нуля файл.
Почему это работает
Когда просишь LLM "исправь ошибку" одним запросом, модель часто сразу переписывает крупные куски кода — она не разделяет "понять причину" и "написать фикс", и вместе с фиксом заносит новую ошибку или лечит симптом вместо причины.
LLM хорошо объясняет проблему текстом, если дать ей конкретные факты — лог ошибки и diff, — а не абстрактное "тут баг, найди сам". Diff показывает модели именно то место, где риск, а не весь файл целиком.
Метод копирует то, что делает хороший разработчик при отладке: сначала понять, что и почему сломалось, только потом чинить. Разделение на два отдельных запроса заставляет модель "остановиться" на диагнозе, прежде чем лезть в код.
Рычаги управления: - Число итераций (в исследовании — 10) → для простой правки хватит 1-2 раза, экономия времени - Инструкция "минимальные точечные правки, не менять сигнатуры" → без неё модель начнёт переписывать весь файл - Объём дополнительного контекста (другие файлы проекта) → давайте по минимуму: в исследовании избыток контекста иногда ухудшал результат, а не улучшал
Шаблон промпта
ШАГ 1 — ДИАГНОЗ (отдельное сообщение):
Вот ошибка после изменения кода:
{текст ошибки / лог}
Вот что изменилось (было → стало):
{старый код} → {новый код}
Не исправляй пока ничего. Ответь:
1. Точная причина ошибки (root cause)
2. Что именно нужно поправить — конкретные переменные/функции/строки (hint)
---
ШАГ 2 — ИСПРАВЛЕНИЕ (следующее сообщение, после диагноза):
На основе диагноза выше исправь код.
Правки — минимальные и точечные, только там, где причина ошибки.
Не меняй остальную логику, не добавляй новых переменных или функций,
не меняй публичные названия функций, если это не требуется для фикса.
Верни код целиком.
Подставляйте текст ошибки/лога и фрагменты кода до и после изменения.
🚀 Быстрый старт — вставь в чат:
Вот шаблон двухшагового ремонта кода (диагноз → исправление).
Адаптируй под мою задачу: {опиши свою ошибку и код}.
Задавай вопросы, чтобы заполнить поля.
[вставить шаблон выше]
LLM спросит текст ошибки и что именно вы меняли в коде — потому что без конкретного лога и diff диагноз строить не из чего, метод работает только с фактами, а не с общим "тут баг".
Ограничения
⚠️ Нужен явный сигнал ошибки: метод работает только когда есть конкретный текст ошибки, лог или тест, который падает. Без чёткого "что именно сломалось" диагноз ставить не из чего.
⚠️ Избыток контекста вредит: добавление большого количества сопутствующего кода в промпт в исследовании снижало точность исправления. Давайте только код, напрямую связанный с ошибкой, а не весь проект.
⚠️ В чате нет прогона тестов: оригинальная система автоматически компилирует код и запускает юнит-тесты после каждой правки. В обычном чате вы не можете это автоматизировать — придётся вручную запускать код у себя и присылать модели новый результат на каждой итерации.
Ресурсы
RefactorAssist: Agentic Refinement for Reliable Code Refactoring — Jonathan Cordeiro, Shayan Noei, Ying Zou, Queen's University, Canada. Репозиторий с промптами и данными: github.com/Software-Evolution-Analytics-Lab-SEAL/Automating-refactoring-correction
