Как сделать собственного код-ревьювера для Claude на основе истории коммитов

Вы смотрите на пул-реквест, в котором переписана половина кодовой базы. Ведущий разработчик в отпуске, и теперь вы должны проверить всё это так, будто вы — это он.

Робот Helix от Figure AI складывает посуду в посудомойку пока ты занимаешься код-ревью без своего уникального агента-ревьювера, юзернейм.
Робот Helix от Figure AI складывает посуду в посудомойку пока ты занимаешься код-ревью без своего уникального агента-ревьювера, юзернейм.

В чем секрет? Ваша команда уже написала тысячи идеальных ревью. Они просто лежат в GitHub мертвым грузом. Комментарии вроде «вынеси это в `validateUser()`» или «нарушен лимит в 80 символов, см. строку 47» — это маленькие решения, на освоение которых ушли годы.

Давайте их заберем. Мы создадим инструмент, который проанализирует каждое ревью вашей команды, выявит важные для вас паттерны и будет проверять новый код точно так же. Это не просто стандартные правила линтера — это ваши реальные стандарты. То, как Катя всегда находит утечки памяти в асинхронных функциях, или как Миша замечает, что кто-то в третий раз изобретает велосипед вместо использования общего формата дат. Это не просто «нейросеть-ревьюер», это клонирование коллективного разума вашей команды.

Никто это не записывает.

У каждой команды инженеров формируется своя культура ревью. У старших разработчиков в голове всегда есть негласный чеклист: как здесь принято называть переменные, как именно мы обрабатываем ошибки, какие архитектурные паттерны используем на самом деле и какие баги всплывают чаще всего. Все эти знания хранятся только в памяти людей и в изредка обновляемом code style документе который читают обычно один раз при онбординге
Комментарии к PR бесследно тонут в бесконечной ленте GitHub. Ценное замечание ведущего инженера о том, почему в этот API нельзя передавать null? Похоронено в PR #847 полугодичной давности.

Подход к решению

1. Соберите все комментарии из ревью, которые сможете найти. Удачные решения, ошибки, мелкие придирки — всё подряд.
2. Проанализируйте повторяющиеся моменты. Окажется, что у вашей команды есть свои паттерны — вы просто их еще не зафиксировали.
3. Сформулируйте правила. Не абстрактное «пишите чистый код», а конкретное «всегда проверяй на null перед обращением к индексам массива» с примерами из вашего репозитория.
4. Создайте агента, который проводит ревью так же, как ваш старший разработчик в три часа ночи: максимально тщательно, но без лишних слов.

Теперь раскрою каждый из этих пунктов по отдельности.

Сбор данных

Вот пример скрипта для сбора всех комментариев, которые когда-либо писал ваш проверяющий:

#!/bin/bash # Collecting review comments for training ORGANIZATION="your-org" REPOSITORIES="repo1 repo2 repo3" REVIEWER="senior-reviewer-username" YEAR="${YEAR:-2025}" OUTPUT_FILE="${1:-reviewer-comments.json}" echo "[" > "$OUTPUT_FILE" for REPO in $REPOSITORIES; do echo "Processing repository: $REPO..." # Fetching all pull requests for the specified year PRS=$(gh pr list -R "$ORGANIZATION/$REPO" --state merged --search "merged:$YEAR-01-01..$YEAR-12-31" --json number -q '.[].number') for PR in $PRS; do # Extracting comments from the specific reviewer gh api "repos/$ORGANIZATION/$REPO/pulls/$PR/reviews" \ --paginate \ -q ".[] | select(.user.login == \"$REVIEWER\") | {body: .body, state: .state, pr: $PR, repo: \"$REPO\"}" >> "$OUTPUT_FILE.tmp" gh api "repos/$ORGANIZATION/$REPO/pulls/$PR/comments" \ --paginate \ -q ".[] | select(.user.login == \"$REVIEWER\") | {body: .body, path: .path, diff_hunk: .diff_hunk, pr: $PR, repo: \"$REPO\"}" >> "$OUTPUT_FILE.tmp" done done # Formatting into a valid JSON array cat "$OUTPUT_FILE.tmp" | jq -s '.' >> "$OUTPUT_FILE" rm "$OUTPUT_FILE.tmp" echo "Done! Data saved to $OUTPUT_FILE"

Уверен Claude напишет вам скрипт не хуже, поэтому я не буду больше играть в примеры кода, а сконцентрируюсь на сути.

По итогам этого этапа у вас появляется файл со всеми комментариями, вы можете выбрать удобный вам формат, от csv и json до импорта в Гугл Таблицы.

Анализ

Заваривайте кофе. Вам предстоит пялиться на две с половиной тысячи гневных комментариев. Это была шутка, вы можете попросить Claude найти повторяющиеся закономерности прямо из файла. У вас слишком много комментариев? Разбейте файл на части или используйте Gemini с большим окном контекста. Вы можете даже отдать файл двум или трем разным моделям, а потом попросить каждую из них оценить выводы друг друга. Таким образом вы сэкономите время и получите свод правил. В идеальном мире это хороший этап чтобы показать этот набор старшим разработчикам и попросить оценить. Пробежаться глазами по исходнику тоже не мешало бы. Выгружайте комментарии самых внимательных ревьюверов чтобы изначальный набор данных содержал больше полезных комментариев!
Для того чтобы искать повторяющиеся шаблоны можно быстро с помощью bash скрипта собрать повторяющиеся глаголы и фрагменты кода в ревью:

# Найдите глаголы, которые встречаются чаще всего jq -r '.[].body' comments.json | \ grep -oE '\b(переименовать|упростить|удалить|добавить|изменить|использовать|предпочесть)\b' | \ sort | uniq -c | sort -rn | head -20 # Посмотрите, какие фрагменты кода упоминаются чаще всего jq -r '.[].body' comments.json | \ grep -oE '`[^`]+`' | \ sort | uniq -c | sort -rn | head -50

И оценить их глазами.
В моем случае мы с Клодом проанализировали 2400 комментариев и нашли 45 повторяющихся паттернов, которые распределили по 9 категориям:

  • именование
  • единообразие
  • упрощение
  • обработка ошибок
  • организация тестов
  • порядок кода
  • ввод-вывод (IO)
  • стандартные библиотеки
  • миграции.

Превращаем паттерны в правила.

Каждый паттерн состоит из пяти элементов:

  • Название: Понятная метка, которую вы точно запомните. -
  • Правило: Одно предложение о том, что нужно или нельзя делать.
  • Обоснование: Объяснение «почему», которое помогает правилу закрепиться в памяти.
  • Примеры: Наглядное сравнение хорошего и плохого вариантов.
  • Реальная цитата: Комментарий из практики, который стал поводом для создания паттерна.

Пример правила:

### Start with a verb Name your methods like commands. Open with a verb that tells the reader exactly what happens when you call it. // Good func getUser(id string) (*User, error) func getQuery(ctx context.Context) (*Response, error) func parseHomeddress(raw string) (*HomeAddress, error) // Bad func user(id string) (*User, error) // what does this do with the user? func requestMake(ctx context.Context) // makes… what kind of request? func handleError(err error) // handles it how? Logs? Retries? Real review example: "Call this getXXError instead. handleError could be swallowing alerts or logging them—you wouldn't know from the name."

Другой пример:

### Stick to the Standard Library Don’t reinvent the wheel. When Go gives you `maps.Clone`, use it. // Clean — maps handles it import "maps" copy := maps.Clone(original) // Bad — you’re writing copy-paste code the stdlib already perfected copy := make(map[K]V, len(original)) for k, v := range original { copy[k] = v } // Better — let the type do the work var counter atomic.Int64 counter.Add(1) // Bad — manual atomic var counter int64 atomic.AddInt64(&counter, 1)

Создание навыка для Claude

Начните с самого ревьюера. Его голос здесь имеет решающее значение — то, как он придирается к именам переменных, вздыхает над избыточным проектированием или каким тоном указывает на пропущенную проверку на nil. Возьмите десять его последних комментариев к пулл-реквестам, если они у вас есть. Выбирайте стоящие примеры, где он нашел реальные проблемы, а не просто написал «мелочь: лишний пробел».

--- name: custom-reviewer description: | [reviewer]’s code review twin. Obsessed with readable names, consistent patterns, and deleting code that doesn't need to exist. Speaks [language]. model: inherit --- You’re [name], the reviewer who caught that we used three different error handling styles in the same file last week. You sound like: “Let’s rename this to `validateUserInput`—the verb tells us what it does at a glance.” “The pattern we use everywhere else is early return on error. Here’s how it looks…” Your reviews: - **Collaborative**: “Let’s try…” instead of “Change this…” - **Always explain the reasoning**: Not “this is wrong” but “this breaks the pattern we established in auth.js” - **Show the fix**: Replace vague suggestions with exact code blocks - **Reference existing code**: “We handle this same case in paymentService.js” - **Ruthlessly simplify**: If you can delete it, you do ## 1. NAMING — The First Thing You Check [Pattern details with examples] ## 2. CONSISTENCY — If It Exists Twice, Make It Match [Pattern details with examples] ## 3. SIMPLIFICATION — Delete First, Ask Questions Later [Pattern details with examples] ... ## Your Review Flow: 1. **Scan names** — Can you understand this without reading the body? 2. **Check patterns** — Does this match how we did it three files over? 3. **Delete things** — Variables you only use once, checks we don’t need 4. **Error handling** — Is this the order we agreed on (validate → sanitize → process)? 5. **Test review** — Are the test names telling you what they’re testing? ... End every comment with why it matters and exactly what you’d do instead.

Добавьте к персоне набор полученных правил из предыдущего шага. Создайте в корне Claude новый файл: `agents/review/your-reviewer.md` и поместите туда полученный выше файл из персоны и правил.

Создание своей слеш команды

Чтобы вызвать агента с помощью слеш-команды вроде `/review-like-a-king`, создайте файл навыка в `skills/review-like-a-king.md`:

--- name: review description: Trigger code review with your custom reviewer argument-hint: "[file path or empty for auto-detect]" --- # Code Review Skill ## Determine What to Review 1. If argument provided: review that file 2. If open PR exists: review PR changes 3. If uncommitted changes: review the diff 4. Otherwise: ask user to specify ## Execute Review Use Task tool to launch your-reviewer agent: Task your-reviewer("Review this code: [context]") ## Output Present findings organized by severity: - 🔴 Critical: Must fix before merge - 🟡 Important: Should fix - 🔵 Nice-to-have: Optional improvements

Теперь вызывая команду /review-like-a-king вы будете получать код-ревью о

Интеграция с Compound Engineering

Если вы используете плагин compound-engineering, вы можете добавить собственного рецензента, чтобы он запускался вместе с другими рецензентами при выполнении команды `/workflows:review`.

Команда compound-engineering `/workflows:review` одновременно запускает несколько агентов для рецензирования.

#### Parallel Agents to review the PR: 1. Task kieran-rails-reviewer(PR content) 2. Task dhh-rails-reviewer(PR content) 3. Task security-sentinel(PR content) 4. Task performance-oracle(PR content)

1. **Найдите файл рабочего процесса**:

~/.claude/plugins/marketplaces/every-marketplace/plugins/compound-engineering/commands/workflows/review.md

2. **Найдите раздел "Параллельные агенты"** (примерно строки 54-71) 3. **Добавьте вашего агента** в список:

Task your-reviewer(PR content) - [Brief description of focus]​

Агенты с условным запуском и постоянно активные агенты

Вы можете настроить агента так, чтобы он запускался только при определённом типе файлов:

Всегда запускать (добавить в parallel_tasks)

Task your-reviewer(PR content) - [Brief description of focus]​

Или запускать только для языка Go:

**If PR contains Go files (*.go):** Task go-style-reviewer(PR content) - Go-specific code review **When to run:** - PR includes files matching `*.go` - PR modifies Go modules or packages

Можно сделать даже так:

your-plugin/ ├── agents/ │ └── review/ │ ├── go-reviewer.md # Go-specific patterns │ ├── python-reviewer.md # Python-specific patterns │ └── ts-reviewer.md # TypeScript-specific patterns

И добавить каждого из них в compound-engineering в качестве условных агентов:

**If PR contains Go files:** Task go-reviewer(PR content) **If PR contains Python files:** Task python-reviewer(PR content) **If PR contains TypeScript files:** Task ts-reviewer(PR content)

Тестирование и улучшения

1. Создайте тестовый PR с соответствующими изменениями, вы можете взять уже существующий набор PR из прошлого, где есть комментарии ваших звездных инженеров

2. Запустите команду `/workflows:review` или вашу команду `/review-like-a-king`

3. Убедитесь, что выводы вашего агента появились в сводном отчете

4. При необходимости скорректируйте промпт агента

Вывод

Создание собственного агента для ревью кода на основе реальной истории рецензий даёт инструмент, который:

  • Сохраняет корпоративные знания, которые иначе могли бы быть утеряны
  • Обеспечивает постоянную обратную связь независимо от доступности рецензентов
  • Ускоряет адаптацию новых членов команды
  • Развивается вместе с практиками вашей команды

Ваши лучшие рецензенты уже создали обучающие данные — они хранятся в истории ваших pull-request’ов. Осталось только извлечь, структурировать и закодировать их.

Технические вложения скромны (около 1–2 дней на первоначальную настройку), а шаблоны со временем накапливаются, по мере добавления новых данных и уточнения правил.

В этой статье описывается создание агента-рецензента с помощью плагинов Claude Code. Те же принципы применимы и к другим помощникам по написанию кода — основная работа заключается в извлечении и кодификации паттернов.

Об авторе.

Иван Кузнецов, ex-fullstack dev, ex-fintech-executive, теперь продуктовый менеджер, vibe-кодинг и RoR энтузиаст. Веду закрытое сообщество для опытных пользователей ИИ Нейробилд

22