Промпт для ревью кода через LLM: находим баги до продакшена
Готовый промпт для глубокого ревью кода через LLM. Находит баги, уязвимости, проблемы производительности и выдаёт структурированный отчёт с приоритетами P0–P2 и готовыми исправлениями.
Каждый разработчик знает: ревью кода — это бутылочное горлышко. Пулл-реквест висит два дня, пока коллега найдёт время посмотреть. Когда наконец смотрит — пропускает SQL-инъекцию в строке 47, потому что устал после третьего PR за утро. LLM-ревью не заменяет человека, но ловит то, что человек пропускает от усталости — и делает это за секунды.
Лучшее ревью кода — многослойное. LLM находит механические проблемы (уязвимости, утечки, гонки), человек оценивает архитектурные решения и бизнес-логику.
Задача
Промпт выполняет комплексный аудит кода по пяти направлениям:
- Безопасность — SQL-инъекции, XSS, утечки секретов, небезопасная десериализация
- Баги и логические ошибки — пропущенные edge cases, гонки, ошибки off-by-one
- Производительность — N+1 запросы, утечки памяти, избыточные аллокации
- Обработка ошибок — непойманные исключения, молчаливое проглатывание ошибок
- Качество кода — нарушения SOLID, мёртвый код, чрезмерная сложность
Каждая найденная проблема получает приоритет (P0/P1/P2) и готовое исправление.
Для кого
- Разработчики — самопроверка кода перед созданием pull request
- Тимлиды — ускорение ревью, когда в очереди 10+ PR
- Solo-разработчики — второе мнение, когда ревьюить некому
- DevOps/SRE — аудит инфраструктурного кода (Terraform, Docker, CI/CD)
Как работает промпт
graph LR
A["📄 Код на вход"] --> B["🔍 Анализ по 5 категориям"]
B --> C["⚠️ Приоритизация P0/P1/P2"]
C --> D["🛠️ Исправления для каждой проблемы"]
D --> E["📋 Итоговый вердикт"]
Промпт
Ты — senior software engineer с 15-летним опытом, специализирующийся на code review и безопасности приложений.
ЗАДАЧА: Проведи глубокое ревью предоставленного кода. Анализируй как строгий, но конструктивный ревьюер — твоя цель не придраться, а предотвратить реальные проблемы в продакшене.
ОБЛАСТЬ АНАЛИЗА (проверяй строго в этом порядке):
1. БЕЗОПАСНОСТЬ
- Инъекции (SQL, XSS, command injection, SSRF)
- Утечки секретов и чувствительных данных
- Небезопасная аутентификация / авторизация
- Небезопасная работа с файлами и путями
2. БАГИ И ЛОГИКА
- Необработанные edge cases (null, пустые коллекции, граничные значения)
- Гонки (race conditions) и проблемы конкурентности
- Ошибки off-by-one, неправильные условия
- Нарушения контрактов API
3. ПРОИЗВОДИТЕЛЬНОСТЬ
- N+1 запросы к базе данных
- Утечки памяти и незакрытые ресурсы
- Избыточные вычисления в циклах
- Отсутствие индексов / неоптимальные запросы
4. ОБРАБОТКА ОШИБОК
- Молчаливое проглатывание исключений (empty catch)
- Отсутствие валидации входных данных на границах системы
- Неинформативные сообщения об ошибках
5. КАЧЕСТВО КОДА
- Нарушения SOLID-принципов
- Мёртвый / недостижимый код
- Цикломатическая сложность выше 10
ПРАВИЛА:
- Не комментируй стиль, именование и форматирование — это задача линтера.
- Если в категории проблем не найдено — напиши "Проблем не обнаружено", без выдумывания.
- Каждая проблема должна содержать конкретную строку кода, а не абстрактное замечание.
- Предлагай МИНИМАЛЬНОЕ исправление — не переписывай весь блок ради одной строки.
ФОРМАТ ВЫВОДА — для каждой найденной проблемы:
### [P0|P1|P2] Категория: Краткое описание
**Строка:** `номер строки или фрагмент кода`
**Проблема:** Что именно не так и почему это опасно
**Исправление:**
```язык
исправленный код
ПРИОРИТЕТЫ:
- P0 (блокер): Уязвимость, потеря данных, крэш в продакшене. Мержить нельзя.
- P1 (важно): Баг, который проявится при реальном использовании. Желательно исправить до мержа.
- P2 (улучшение): Потенциальная проблема или неоптимальность. Можно исправить позже.
ИТОГ: В конце дай общий вердикт:
- ✅ APPROVE — критических проблем нет, код готов к мержу
- ⚠️ REQUEST CHANGES — есть P0/P1, требуют исправления
- ❌ BLOCK — серьёзные уязвимости, нужна переработка
Количество найденных проблем по приоритетам: P0: X, P1: X, P2: X
КОД ДЛЯ РЕВЬЮ: [вставьте код сюда]
КОНТЕКСТ (опционально):
- Язык/фреймворк: [например, Python/FastAPI]
- Что делает этот код: [краткое описание]
- Какие изменения внесены: [что именно изменилось, если это diff]
💡 Совет: добавляйте контекст
Секция «КОНТЕКСТ» — необязательная, но она кардинально улучшает качество ревью. Когда модель знает, что код — это обработчик платёжного webhook, она обращает особое внимание на идемпотентность и валидацию подписей. Без контекста — просто проверяет синтаксис.
## Пример результата
Допустим, на вход подан следующий Python-код:
```python
from flask import Flask, request
import sqlite3
import os
app = Flask(__name__)
@app.route("/user")
def get_user():
user_id = request.args.get("id")
conn = sqlite3.connect("app.db")
cursor = conn.cursor()
cursor.execute(f"SELECT * FROM users WHERE id = {user_id}")
user = cursor.fetchone()
return {"name": user[1], "email": user[2]}
@app.route("/upload", methods=["POST"])
def upload():
file = request.files["file"]
path = os.path.join("/uploads", file.filename)
file.save(path)
return {"status": "ok"}
@app.route("/config")
def config():
db_password = os.environ.get("DB_PASSWORD", "admin123")
return {"db_host": "prod-db.internal", "pool_size": 10}
Модель выдаст примерно такой ответ:
P0 Безопасность: SQL-инъекция в get_user
Строка: cursor.execute(f"SELECT * FROM users WHERE id = {user_id}")
Проблема: Значение user_id подставляется в SQL-запрос напрямую через f-string. Атакующий может передать id=1 OR 1=1 и получить все записи, либо id=1; DROP TABLE users для уничтожения данных.
Исправление:
cursor.execute("SELECT * FROM users WHERE id = ?", (user_id,))
P0 Безопасность: Path traversal в upload
Строка: path = os.path.join("/uploads", file.filename)
Проблема: file.filename может содержать ../../etc/passwd или другие пути. Атакующий перезаписывает произвольные файлы на сервере.
Исправление:
from werkzeug.utils import secure_filename
safe_name = secure_filename(file.filename)
path = os.path.join("/uploads", safe_name)
P1 Безопасность: Захардкоженный пароль-фолбэк
Строка: db_password = os.environ.get("DB_PASSWORD", "admin123")
Проблема: Если переменная окружения не задана, используется пароль admin123. В продакшене это создаёт риск несанкционированного доступа.
Исправление:
db_password = os.environ["DB_PASSWORD"] # упадёт явно, если не задан
P1 Баги и логика: Необработанный None в get_user
Строка: return {"name": user[1], "email": user[2]}
Проблема: Если пользователь не найден, user будет None, и обращение по индексу вызовет TypeError. Клиент получит 500-ошибку без объяснения.
Исправление:
user = cursor.fetchone()
if user is None:
return {"error": "User not found"}, 404
return {"name": user[1], "email": user[2]}
P1 Обработка ошибок: Незакрытое соединение с базой
Строка: conn = sqlite3.connect("app.db")
Проблема: Соединение не закрывается ни явно, ни через context manager. При исключении ресурс утечёт.
Исправление:
with sqlite3.connect("app.db") as conn:
cursor = conn.cursor()
cursor.execute("SELECT * FROM users WHERE id = ?", (user_id,))
user = cursor.fetchone()
P2 Безопасность: Эндпоинт /config раскрывает инфраструктуру
Строка: return {"db_host": "prod-db.internal", "pool_size": 10}
Проблема: Внутреннее имя хоста базы данных доступно без аутентификации. Упрощает разведку при атаке.
Исправление: Удалить эндпоинт или добавить аутентификацию.
Вердикт: ❌ BLOCK — 2× P0 (SQL-инъекция, path traversal), нужна переработка
P0: 2, P1: 3, P2: 1
Сравнение приоритетов
| Приоритет | Что означает | Пример | Действие |
|---|---|---|---|
| P0 — блокер | Уязвимость или потеря данных | SQL-инъекция, утечка секретов | Не мержить, исправить немедленно |
| P1 — важно | Баг при реальном использовании | NullPointerException, утечка ресурсов | Исправить до мержа |
| P2 — улучшение | Потенциальная проблема | Неоптимальный запрос, лишний код | Можно взять в техдолг |
Вариации и настройки
Ревью с фокусом только на безопасности
Добавьте в начало промпта:
ФОКУС: Только безопасность. Игнорируй производительность, качество кода и стиль.
Проверяй по OWASP Top 10 2025:
- A01: Broken Access Control
- A02: Cryptographic Failures
- A03: Injection
- A07: Security Misconfiguration
Ревью инфраструктурного кода
КОНТЕКСТ: Это Terraform/Docker/CI-конфигурация.
Дополнительно проверяй:
- Привилегированные контейнеры и избыточные capabilities
- Секреты в переменных окружения вместо vault/secrets manager
- Отсутствие ограничений ресурсов (CPU/memory limits)
- Публичные security groups / открытые порты
Ревью с учётом стандартов команды
СТАНДАРТЫ КОМАНДЫ:
- Все SQL-запросы через ORM (SQLAlchemy), raw SQL запрещён
- Обязательный type hints для публичных функций
- Логирование через structlog, не через print/logging
- Максимальная длина функции: 30 строк
Автоматизация: промпт в CI/CD
Для интеграции в pipeline используйте промпт как системный message через API:
import anthropic
client = anthropic.Anthropic()
def review_code(code: str, language: str, description: str = "") -> str:
system_prompt = """Ты — senior software engineer...""" # полный промпт выше
user_message = f"""КОД ДЛЯ РЕВЬЮ:
```{language}
{code}
КОНТЕКСТ:
Язык/фреймворк: {language}
Что делает этот код: {description}"""
message = client.messages.create( model=“claude-sonnet-4-6-20260410”, max_tokens=4096, system=system_prompt, messages=[{“role”: “user”, “content”: user_message}] ) return message.content[0].text
📝 Пример интеграции с GitHub Actions
Популярный подход — запускать LLM-ревью автоматически на каждый pull request. Инструменты вроде CodeRabbit и ai-code-review делают это из коробки. Для собственного решения: GitHub Action получает diff, отправляет в API, результат постит как комментарий к PR.
## Советы по улучшению
**1. Подавайте diff, а не весь файл.** Если ревьюите изменения, а не весь файл — отправляйте `git diff`. Модель сфокусируется на том, что изменилось, и не будет отвлекаться на старый код.
**2. Указывайте фреймворк.** «Python» и «Python/Django» — два разных ревью. Зная фреймворк, модель проверит специфичные паттерны: N+1 в Django ORM, небезопасные сериализаторы в DRF, CSRF-токены в формах.
**3. Добавляйте примеры ваших стандартов.** Если в команде есть style guide или ADR — вставьте ключевые правила в секцию «СТАНДАРТЫ». Модель будет проверять код не только по общим практикам, но и по вашим конвенциям.
**4. Итерируйте.** После первого ревью отправьте исправленный код на повторную проверку с пометкой: «Проверь, что все P0 и P1 из предыдущего ревью исправлены».
> Промпт для ревью — не замена процессу, а усилитель. Он ловит 80% механических проблем за секунды, освобождая человеку время для обсуждения архитектуры и бизнес-логики.
graph TD
A["Разработчик пишет код"] --> B["Самопроверка: LLM-ревью"]
B --> C{"P0 найдены?"}
C -->|Да| D["Исправить и повторить"]
D --> B
C -->|Нет| E["Создать Pull Request"]
E --> F["CI: автоматическое LLM-ревью"]
F --> G["Человек-ревьюер"]
G --> H{"Approve?"}
H -->|Да| I["Мерж в main"]
H -->|Нет| D
Источники
- AI Prompts for Code Review: Catch Bugs, Improve Structure, Ship Better Code
- Best AI Prompts for Developers in 2026 — DEV Community
- 7 AI Prompts for Code Review and Security Audits
- Effective prompt engineering for AI code reviews — Graphite
- Prompting best practices — Claude API Docs
- Code Review — Claude Code Docs