Как я создал скилл для перекрёстного ревью плана и кода с двумя ИИ-моделями

Как я создал скилл для перекрёстного ревью плана и кода с двумя ИИ-моделями

Когда одна и та же модель генерирует и проверяет код, она часто пропускает собственные ошибки. Она «помнит» логику своих решений и не ставит их под сомнение. Это похоже на вычитку собственного текста — глаз замыливается, а мозг подставляет правильный смысл там, где его нет.

Почему нужно два ИИ, а не один

В живой команде код всегда проверяет не автор, а другой разработчик — с другим контекстом и другими слепыми зонами. С ИИ можно сделать то же самое: использовать две разные модели от разных вендоров. Разная архитектура, разный pretrain — разные ошибки. Одна модель пишет, другая проверяет.

В англоязычной среде такой подход называют adversarial review — «состязательное ревью». Суть в том, что ревьюер не подтверждает корректность, а пытается опровергнуть решение. Я называю это проще — перекрёстное ревью.

У меня Claude Opus планирует и пишет код, а Codex (на базе GPT) его ревьюит. Процесс автоматизирован и проходит в цикле до одобрения. Всё это реализовано как один скилл для Claude Code.

Зачем ревьюить план, а не только код

Большинство ИИ-инструментов ревьюят только код. Это логично: код конкретен, diff понятен, замечания легко привязать к строкам. Но ошибки в коде — самые дешёвые.

Гораздо дороже обходятся ошибки в плане: неправильная декомпозиция задачи, пропущенные зависимости, отсутствие ключевых шагов. Код может быть технически безупречным, но решать не ту проблему или в неправильной последовательности. При этом план почти никогда не ревьюят — хотя именно он определяет качество всей реализации.

Ревью ИИ не заменяет человеку проверку смысла. Я сам отвечаю за зачем и что. А как — уже может проверять агент. Пропущенный шаг, неучтённая зависимость — это хорошо ловится второй моделью. Человек отвечает за цель, ИИ — за полноту и корректность реализации.

Как я пришёл к автоматизации

Мой цикл работы с ИИ: план → ревью → код → ревью. План и код я генерирую в Claude Opus, а ревью передаю в Codex — одна из самых сильных моделей GPT. Работает отлично: разный стиль мышления помогает выявлять ошибки.

Но был один недостаток — копипаста. По 2–4 раунда ревью плана, столько же для кода. Копируешь из одного чата, вставляешь в другой, ждёшь ответ, переносяшь замечания, правишь, повторяешь. Раздражало, но терпимо.

Автоматизировать? Хотел, но не хотел городить сложные системы. Нужно было сохранить контроль и гибкость. Решение появилось с выходом скиллов для Claude Code — особенно с возможностью запускать внешние программы.

Я нашёл скилл benedictking/codex-review на GitHub, попробовал — но столкнулся с избыточными запросами подтверждения и отсутствием ревью плана. Решил «немного подправить». Переписал несколько раз. Получился рабочий инструмент.

Позже увидел официальный плагин от OpenAI — codex-plugin-cc. Вдохновился некоторыми идеями, но свой скилл не заменил.

Почему свой скилл лучше официального плагина

У плагина OpenAI есть сильные стороны: продуманные промпты, скептическая настройка ревьюера, готовые чек-листы. Часть этих решений я использовал (и указал это в README). Но два отличия оказались критичными.

  • Режимы ревью: плагин проверяет только код. Мой скилл работает в трёх режимах — ревью плана, ревью кода и ревью кода против плана. Ревью плана можно запускать прямо в Plan Mode, до написания кода.
  • Простота: плагин OpenAI — это 15 JS-модулей, сервер, брокер, хуки. Мой скилл — один файл SKILL.md. Это текстовая инструкция, которую агент интерпретирует сам. Нет сервера, нет зависимостей — только CLI ревьюера. Легко адаптировать под другую модель.

Скилл — это не программа, а инструкция. Агент сам решает, как её выполнить, учитывая контекст.

Как это работает

Claude генерирует план или код. Скилл собирает данные (diff или файл плана), формирует промпт и запускает Codex в read-only режиме. Тот выносит вердикт: APPROVED или REVISE. Если нужна правка — Claude вносит изменения и отправляет на повторное ревью. Цикл — до 5 раундов, на практике хватает 2–3.

Режим определяется автоматически по контексту или задаётся вручную.

Ключевые решения:

  • Ревьюер работает в read-only режиме — он не должен править, только находить проблемы.
  • Замечания передаются без фильтрации — Claude не «смягчает» их, иначе теряется смысл второго мнения.
  • Повторные раунды идут через resume — продолжение сессии, экономия токенов.

Adversarial промпты: как заставить ИИ критиковать

Нейтральный промпт вроде «проверь код на баги и стиль» даёт вялый ответ: «всё норм, можно добавить тесты». Adversarial промпт настраивает модель на скепсис — она должна искать, что сломается.

Промпты структурированы через XML-секции:

  • <attack_surface> — чек-лист: авторизация, целостность данных, race conditions, rollback safety.
  • <finding_bar> — каждое замечание должно отвечать на четыре вопроса: что сломается, почему уязвимо, какой импакт, как исправить.
  • <scope_exclusions> — не комментировать стиль и спекулятивные улучшения. Одно сильное замечание ценнее пяти слабых.

Если код надёжен, ревьюер должен это чётко сказать. Ложные срабатывания подрывают доверие.

Технические нюансы

Разрешения: Claude Code запрашивает подтверждение на каждую bash-команду. При нескольких раундах ревью это десятки подтверждений. Часть решается через permissions.allow в настройках, часть — заменой bash на встроенные инструменты (например, Write tool вместо echo). Полностью избавиться не удалось, но стало терпимо.

Resume и настройки модели: команда codex exec resume экономит токены, но есть нюанс. При resume Codex игнорирует переданные параметры и берёт текущие настройки пользователя. Например, если у вас по умолчанию medium reasoning, ревью будет поверхностным. У меня, наоборот, скидывало на xhigh вместо high — лишние токены.

Diff vs список файлов: ранние версии передавали полный diff в промпт — это раздувало контекст. Сейчас в промпт идёт только --name-only список файлов и команды для получения diff. Codex читает diff сам — контекст чище, токены не тратятся.

Таймауты: Codex иногда зависает. Без таймаута приходится ждать бесконечно. С timeout 600 через 10 минут получаем exit code 124 и можем повторить. Просто, но критично.

Читать оригинал