TL;DR
ExploreRepair — это двухэтапная схема организации кодинг-агентов (исследование + иерархическая сборка), в которой три независимых агента параллельно изучают проблему с трёх разных сторон — структура вызовов кода, замысел разработчика (контракт API) и воспроизводящий тест (PoV), а затем отдельные агенты-агрегаторы сводят их выводы («уроки») и черновики патчей в итоговое решение.
Когда разработчику или кодинг-агенту нужно срочно закрыть уязвимость или неочевидный баг, у него почти никогда нет готового эксплойта или подробного описания причины — известно только примерное место в коде. В такой ситуации одиночный агент (или общая дискуссия агентов в одном чате) быстро хватается за первую правдоподобную гипотезу и чинит симптом, ломая соседнюю логику или пропуская похожие места в репозитории. Попытка дать одному агенту сразу все инструменты и инструкции («агент 3-в-1») тоже проваливается: из-за перегруженного контекста модель путается в разнородных уликах и работает даже хуже обычного одиночного агента.
Метод решает эту проблему жёстким разделением труда на 2 фазы: на этапе исследования три изолированных агента собирают каждый свой тип улик и предлагают свой патч, после чего на этапе агрегации длинные логи их работы сжимаются в короткие структурированные «уроки» (lessons), два отдельных агрегатора параллельно собирают патч по логике уроков и патч по коду diff-ов, а финальный агрегатор сверяет обе версии с репозиторием и выпускает чистое исправление.
Схема метода
Процесс требует отдельных изолированных запусков (сессий) агентов на этапе исследования и последовательной цепочки вызовов на этапе сборки:
ФАЗА 1: НЕЗАВИСИМОЕ ИССЛЕДОВАНИЕ (3 отдельные сессии агентов параллельно)
├── Агент 1 (Structural / Структура): трассирует граф вызовов, импорты и соседние функции → [Лог + Патч 1]
├── Агент 2 (Semantic / Замысел): отвечает на 4 вопроса о контракте API и формулирует до 5 правил безопасности → [Лог + Патч 2]
└── Агент 3 (Executable / Тест): пишет и запускает тест-эксплойт (PoV) до срабатывания бага, затем чинит код → [Лог + Патч 3]
ФАЗА 2: ИЕРАРХИЧЕСКАЯ СБОРКА (последовательные шаги агрегации)
ШАГ 1 (Дистилляция): LLM сжимает длинный лог и патч каждого из 3 агентов → [3 коротких Урока (Lessons) с уликами и сомнениями]
ШАГ 2А (Lesson Aggregator): синтезирует ремонт ТОЛЬКО из 3 текстовых уроков → [Патч L + Лог L]
ШАГ 2Б (Patch Aggregator): синтезирует ремонт ТОЛЬКО из 3 конкретных diff-патчей → [Патч P + Лог P]
ШАГ 3 (Final Aggregator): получает уроки L и P + Патч L и Патч P, проверяет их по коду репозитория → [Финальный патч]
Пример применения
Задача: В российском сервисе доставки еды и продуктов после ночного релиза аналитики безопасности прислали краткий сигнал: «В модуле расчёта промокодов и возвратов (promo_service.py, функции apply_partner_discount и refund_bonus) возможен обход лимитов при параллельных запросах от корпоративных аккаунтов». Готового теста, воспроизводящего взлом, нет; подробного отчёта тоже нет — нужно быстро и без поломки штатных заказов найти корень проблемы и выпустить патч с помощью субагентов в Claude Code.
Промпт:
# Организация субагентов по схеме ExploreRepair (для запуска в Claude Code / агентном пайплайне)
У нас задача с неполными данными: подозрение на уязвимость в `promo_service.py` (функции `apply_partner_discount`, `refund_bonus`). Не делай поспешных правок. Выполни работу в 2 фазы через изолированных субагентов:
## ФАЗА 1: Запусти 3 независимых субагента (без обмена контекстом между ними)
### Субагент 1 — Структурные улики (Structural Explorer):
Изучи только структуру кода вокруг `apply_partner_discount` и `refund_bonus`:
1. Проследи все пути, по которым внешние входные данные из API доходят до этих функций.
2. Проверь функции-помощники, валидаторы и соседние модули, которые менялись в тех же коммитах или делают похожие проверки баланса.
3. Предложи свой кандидат-патч (diff) и верни отчёт о найденных путях в коде.
### Субагент 2 — Семантические улики и замысел (Intent Explorer):
Реконструируй замысел разработчика, ответив строго по порядку на 4 вопроса с указанием файлов и строк (если данных в репозитории не хватает — явно зафиксируй неопределённость):
1. Какой API-контракт или бизнес-спецификация управляет этим кодом?
2. Кто может вызывать этот код и контролировать его входные параметры?
3. Какие ресурсы (деньги, бонусы, лимиты БД) этот код защищает?
4. Какие ограничения должны выполняться для недоверенных входных данных?
На основе ответов сформулируй до 5 правил безопасности (security constraints), найди, где текущий код их нарушает, и предложи свой кандидат-патч (diff).
### Субагент 3 — Исполняемые улики (PoV Explorer):
1. Проследи путь данных от публичного эндпоинта до `apply_partner_discount`.
2. Напиши и запусти тест (Proof-of-Vulnerability), который реально демонстрирует нарушение безопасности (например, списание бонусов в минус или двойной возврат). Дорабатывай тест, пока он не воспроизведёт сбой на текущем коде.
3. Напиши патч, устраняющий корневую причину в продакшен-коде (ЗАПРЕЩЕНО ослаблять сам тест или ставить заглушку под конкретное число из теста), и перезапусти тест. Верни патч и лог запуска.
## ФАЗА 2: Иерархическая агрегация
1. Сожми отчёт каждого из 3 субагентов в короткий «Урок» (Lesson): подозреваемая уязвимость, строки кода / результаты запуска, суть правки и оставшиеся сомнения.
2. Сформируй два черновика решения: один — опираясь на 3 текстовых Урока и правила безопасности (Lesson Aggregator), второй — сравнивая и объединяя 3 конкретных кода правок (Patch Aggregator).
3. Сделай финальную сверку обоих черновиков с кодом репозитория, разреши противоречия и выдай итоговый патч, прогнав штатные юнит-тесты.
Результат:
Вместо того чтобы сразу поставить костыль в первую попавшуюся строку promo_service.py, три изолированных субагента принесут три разных среза: первый найдёт, что функция вызывается ещё и из вебхука партнёров без валидации, второй сформулирует бизнес-инвариант (сумма возврата не может превышать списанный чек с учётом идемпотентности), а третий подтвердит баг рабочим падающим тестом. Иерархический сборщик объединит точную локализацию из diff-ов с бизнес-ограничениями и выдаст патч, который закрывает проблему даже в том случае, если каждый субагент по отдельности ошибся в деталях.
Почему это работает
Когда модель ищет сложный баг в большом проекте без готового теста, перед ней стоят три совершенно разные задачи: проследить граф вызовов по файлам, понять бизнес-логику автора кода и подобрать входные данные, которые ломают программу. Если свалить все три задачи в один промпт («агент 3-в-1») или заставить агентов сразу спорить в общем чате, срабатывает ловушка ранней фиксации: первая же правдоподобная догадка забивает контекст, и остальные шаги подгоняются под неё. Кроме того, сырые логи блуждания агента по репозиторию огромны — если передать их сборщику целиком, модель тонет в тысячах строк шумного текста.
Сильная сторона LLM проявляется тогда, когда в одной сессии у неё одна узкая линза внимания и чёткий алгоритм проверки, а при сведении результатов она работает со сжатыми выводами. В частности, семантический агент опирается на 4 строгих вопроса о границах доверия, а тестовый агент привязан к реальности через запуск кода.
ExploreRepair соединяет эти сильные стороны через двухступенчатую дистилляцию и разделение диагноза и кода. Сначала длинные траектории сжимаются в короткие «уроки» (lessons), где явно выписаны не только находки, но и сомнения (uncertainties). Затем система специально разводит синтез по смыслу (Lesson Aggregator думает над архитектурой и ограничениями безопасности) и синтез по коду (Patch Aggregator видит точные строки и синтаксис в diff-ах, которые теряются при пересказе словами). Финальный арбитр получает уже выжатый концентрат из двух лучших версий и может починить уязвимость даже тогда, когда все три разведчика поодиночке написали неполные патчи.
Рычаги управления методом:
- Отказ от «агента 3-в-1»: никогда не объединяйте три роли исследования в один системный промпт — эксперименты показали, что один агент со всеми тремя инструкциями работает хуже раздельных субагентов на 8,9–18,3 процентного пункта.
- Явная фиксация сомнений в «Уроке»: требуйте при суммаризации лога каждого агента обязательно заполнять пункт «неразрешённые вопросы / нехватка данных» — это не даёт агрегатору поверить в уверенный блеф одного из разведчиков.
- Облегчённая версия для быстрых задач: если нет возможности запускать оба промежуточных агрегатора, для моделей с сильным рассуждением по тексту можно оставить только Lesson Aggregator, а для кодовых моделей — Patch Aggregator, но полная связка даёт максимальную надёжность.
Шаблон промпта
Ниже — универсальный шаблон для применения архитектуры ExploreRepair к задаче поиска и исправления бага/уязвимости через мультиагентную настройку (например, субагентов Claude Code или цепочку промптов):
# Шаблон ExploreRepair для исправления бага/уязвимости при неполных вводных
Контекст: Репозиторий `{название_проекта}`, подозрительный участок кода: `{файл_и_функции}`.
Описание проблемы (без готового теста): `{краткий_симптом_или_подозрение}`.
## ЭТАП 1. Запусти 3 независимых исследования (в отдельных сессиях/субагентах)
### [Сессия 1 — Structural Agent (Структура)]
Исследуй `{файл_и_функции}` по связям в коде:
- Найди все вызывающие функции (callers), импорты и зависимости, через которые внешние данные попадают в `{файл_и_функции}`.
- Проверь функции-валидаторы и соседние участки кода с аналогичной логикой (включая файлы, которые менялись вместе в Git).
- Выдай: 1) траекторию анализа путей кода, 2) свой вариант патча (diff).
### [Сессия 2 — Intent Agent (Замысел и правила безопасности)]
Прежде чем писать код, ответь строго по порядку на 4 вопроса (подкрепляй каждый ответ ссылками на файлы и строки; если данных в коде нет — явно запиши неопределённость):
1. Какая спецификация или API-контракт управляет этим участком кода?
2. Кто может вызывать этот код и контролировать его входные данные?
3. Какие ресурсы или инварианты он защищает?
4. Какие ограничения должны выполняться для недоверенных данных?
На основе ответов сформулируй до 5 обязательных ограничений безопасности (security constraints), укажи строки, где они нарушены, и выдай: 1) разбор диагноза, 2) свой вариант патча (diff).
### [Сессия 3 — PoV Agent (Воспроизводящий тест)]
Проверь проблему запуском кода:
1. Проследи путь входных данных от публичного интерфейса/API до `{файл_и_функции}`.
2. Напиши и запусти проверочный тест (PoV), демонстрирующий сбой или нарушение безопасности. Дорабатывай тест, пока он наглядно не воспроизведёт проблему.
3. Исправь корневую причину в основном коде (не ослабляй тест и не пиши заглушку под конкретный вход теста) и убедись, что тест проходит. Выдай: 1) наблюдения из запусков, 2) свой вариант патча (diff).
## ЭТАП 2. Дистилляция и Иерархическая сборка
### [Шаг 2.1 — Дистилляция в Уроки (Lessons)]
Для каждого из 3 отчётов составь краткий конспект (Lesson) по схеме:
- Подозреваемая причина сбоя;
- Подтверждающие строки кода или результаты запуска теста;
- Суть предложенного изменения;
- Оставшиеся сомнения и непроверенные допущения.
### [Шаг 2.2 — Раздельный синтез]
- **Lesson Aggregator:** На основе трёх текстовых конспектов (Lessons) и кода репозитория синтезируй патч `Patch_L` (фокус на полноте логики и соблюдении ограничений безопасности).
- **Patch Aggregator:** На основе трёх исходных diff-патчей и кода репозитория синтезируй патч `Patch_P` (фокус на точных местах вставки кода и деталях реализации).
### [Шаг 2.3 — Финальное согласование (Final Aggregator)]
Сравни `Patch_L` и `Patch_P` и их аргументацию со свежим кодом `{файл_и_функции}`:
- Объедини взаимодополняющие правки, отбрось ложные допущения и сформируй единый финальный патч.
Что подставлять в плейсхолдеры:
- {название_проекта} — имя вашего сервиса или модуля.
- {файл_и_функции} — локализация проблемы (файл, класс, диапазон строк из баг-репорта или алерта).
- {краткий_симптом_или_подозрение} — любая неполная вводная, с которой пришёл запрос.
🚀 Быстрый старт — вставь в чат с кодинг-агентом (например, Claude Code):
Вот шаблон ExploreRepair. Адаптируй под мою задачу: [твоя задача].
Задавай вопросы, чтобы заполнить поля.
[вставить шаблон выше]
LLM спросит, в каком файле или функции подозревается баг и есть ли возможность запускать тесты в терминале — потому что это нужно для настройки трёх ролей субагентов (структурного, смыслового и тестового). Она возьмёт паттерн из шаблона и адаптирует под задачу.
Ограничения
⚠️ Высокий расход токенов и времени на оркестрацию: Полный цикл включает 3 независимых запуска агентов-разведчиков, 3 вызова для сжатия логов в уроки и 3 запуска агрегаторов — для мелких опечаток и очевидных багов такая схема избыточна.
⚠️ Для полной реализации структурного агента нужен граф кода или поиск по репозиторию: В оригинале авторы строили AST-граф вызовов и векторный индекс (
search_code,graph_neighbors); в обычном кодинг-агенте эту роль приходится заменять встроенными инструментами поиска по символам (LSP / grep / git log).
⚠️ Нельзя сливать роли в одну сессию: Если ради экономии попросить одного агента сделать все три проверки подряд в одном контексте («3-in-1 Agent»), качество ремонта падает ниже обычного одиночного агента из-за информационной перегрузки.
Как исследовали
Команда исследователей из университетов Сиднея, Виктории, Монаша и Сингапурского университета менеджмента (SMU) начала с неприятного факта из реальной жизни: в 95,9% случаев (из 75 807 изученных уязвимостей CVE) в течение года после публикации в открытом доступе нет готового теста-эксплойта (PoV), тогда как почти все передовые научные системы авторемонта кода требуют такой тест как обязательную подсказку. Чтобы проверить работу в реальных «спартанских» условиях, авторы взяли 204 настоящие уязвимости: 169 задач на Python, JavaScript и Go из бенчмарка PatchEval и 35 задач на C/C++ из VulnLoc+. Из контейнеров специально удалили все проверочные эксплойты бенчмарка, описания CVE и скрипты оценки, оставив агентам только сам репозиторий на уязвимом коммите и подсказку с именем функции.
Эксперименты гоняли на двух современных моделях — GPT-5.6-Luna и DeepSeek-V4.1-Flash — и сравнивали ExploreRepair с одиночным агентом, обычной мультиагентной системой, специально обученными системами ремонта (IntentFix, EvoRepair, LoopRepair) и универсальным кодинг-агентом OpenAI Codex. Результаты оказались впечатляющими: на PatchEval с моделью DeepSeek-V4.1-Flash метод ExploreRepair успешно починил 71,6% уязвимостей (против 57,4% у одиночного агента, 55,6% у обычного мультиагента, 46,2% у EvoRepair и 43,8% у Codex), а на C/C++ в VulnLoc+ обошёл систему LoopRepair на 17,1–20,0 процентного пункта (и даже выиграл у версии LoopRepair, которой дали готовый авторский PoV-тест!). Самое интересное вскрылось при разборе деталей: во-первых, когда все три инструмента исследования дали одному агенту («3-in-1 Agent»), его результат просел с 57,4% до 53,3% из-за каши в длинном контексте; во-вторых, иерархическая агрегация смогла полностью починить 11 уязвимостей на DeepSeek и 3 на GPT-5.6, с которыми не справился ни один из трёх агентов-исследователей по отдельности — сборщик буквально собрал рабочий пазл из трёх неудачных, но дополняющих друг друга попыток.
Адаптации и экстраполяции
💡 Адаптация для сложного дебаггинга продакшен-инцидентов (не только уязвимостей): Тот же самый конвейер идеально ложится на расследование «плавающих» багов в бэкенде, когда клиент прислал только скриншот ошибки 500, а шаги воспроизведения неизвестны.
В этом случае три субагента в Claude Code получают роли: 1. Трассировщик данных (Structural): ищет все места записи и чтения проблемного поля в БД и очередях сообщений. 2. Аналитик бизнес-инвариантов (Intent): выписывает из кода и тестов, какие состояния заказа/платежа считаются валидными и где пропущена проверка состояния. 3. Охотник за воспроизведением (Executable): пишет интеграционный pytest, перебирающий граничные условия до тех пор, пока не поймает тот самый
Exception, после чего агрегатор собирает финальный фикс.
Ресурсы
Исследование: ExploreRepair: Evidence-Specialized Agents for Vulnerability Repair under Information Constraints Авторы: Duc Manh Tran, Ratnadira Widyasari, Ivana Clairine Irsan, Huihui Huang, Ting Zhang, David Lo, Rahul Gopinath, Hong Jin Kang (The University of Sydney, University of Victoria, Singapore Management University, Monash University) Бенчмарки: PatchEval (Python, JS, Go), VulnLoc+ (C/C++)
