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

Нарушения стиля редко появляются как одна большая ошибка. Обычно это крошечные «достаточно близко» решения в pull request, которые кажутся безвредными, а затем накапливаются, и база кода становится разнородной и сложной для чтения.
Дрейф стиля часто выглядит так: в одном файле используют userID, в другом — userId, в третьем — uid. Один обработчик возвращает { error: "..." }, другой бросает ошибку, третий логирует и возвращает null. Каждое изменение небольшое, но вместе они создают репозиторий, где шаблоны перестают быть предсказуемыми.
Быстрая итерация и множество участников усугубляют проблему. Люди копируют то, что видят, особенно под давлением времени. Если в репозитории появился ближайший пример с упрощением, это упрощение становится шаблоном для следующего изменения. Через несколько недель «дефолтный стиль» — это не ваше написанное руководство. Это то, что произошло последним.
Поэтому цель — согласованные соглашения, а не личные предпочтения. Вопрос не «нравится ли мне это имя?», а «соответствует ли это правилам, о которых мы договорились, чтобы следующий человек мог следовать им без размышлений?".
Раннее обнаружение нарушений значит — остановить плохие паттерны прежде, чем они станут добычей для copy-paste. Фокусируйтесь на новом и изменённом коде, исправляйте первое появление новой несогласованности и блокируйте слияния, которые вводят новый дрейф. Когда вы помечаете проблему, добавляйте короткий пример предпочтительного варианта, чтобы люди могли его повторить в следующий раз.
Реалистичный пример: разработчик добавляет новый API-эндпоинт и логирует сырые тела запросов «просто для отладки». Если это попадёт в репозиторий, следующий эндпоинт скопирует это, и скоро в логах появятся чувствительные данные. Поймать это в первом PR дешево. Исправлять после распространения — дорого и рискованно.
Руководство стиля работает в обзорах только если читается как чеклист, а не набор вкусовых предпочтений. Перепишите каждое правило как правило, которое можно проверить по diff.
Организуйте правила в четыре категории, чтобы их было трудно пропустить: именование, слои, обработка ошибок и логирование. Для каждой категории напишите два пункта: что должно быть правдой и что запрещено.
Решите заранее степень строгости каждого правила:
Ограничьте область проверки, чтобы обзоры не превращались в бесконечные рефакторы. Простое правило хорошо работает: «новый и изменённый код должен соответствовать; существующий нетронутый код не переписывается, если это не блокирует исправление». Если нужен cleanup, сделайте его отдельной задачей с ограничением по времени.
Также определите ожидаемый результат ревью, чтобы было легко действовать: вердикт пройден/не пройден, список нарушений с файлами и ссылками на строки, предложенные исправления в виде конкретных правок и краткая заметка по риску, если что-то может вызвать баги или утечки.
Пример: если в PR логируются сырые токены пользователей, ревью должно провалиться по правилу «логирование: не логировать секреты» и предложить логировать request ID вместо этого.
Промпты стиля проваливаются, когда звучат как предпочтения. Хороший промпт для ревью читается как контракт: ясные неоспоримые правила, чётко обозначенные исключения и предсказуемый вывод.
Начните с двух коротких блоков: что обязательно и что можно ослабить. Затем добавьте правило решения: «Если непонятно — пометить Needs Clarification. Не домысливать».
Требуйте доказательства. Когда инструмент помечает нарушение, требуйте, чтобы он процитировал точный идентификатор и путь файла, а не давал расплывчатое описание. Это одно требование убирает много лишних уточнений.
Держите область узкой: комментируйте только изменённые строки и прямо затронутые пути кода. Если вы разрешите нерелевантные рефакторы, принуждение стиля превратится в «перепишите файл», и люди перестанут доверять обратной связи.
Вот структура, которую можно переиспользовать:
Role: strict style guide reviewer.
Input: diff (or files changed) + style guide rules.
Non-negotiables: [list].
Allowed exceptions: [list].
Scope: ONLY comment on changed lines and directly impacted code paths. No unrelated refactors.
Evidence: Every finding MUST include (a) file path, (b) exact identifier(s), (c) short quote.
Output: structured compliance report with pass/fail per category + minimal fixes.
Требуйте, чтобы отчёт всегда содержал одни и те же разделы, даже если в каком-то из них будет «No issues found»: Naming, Layering, Error handling, Logging.
Если в отчёте сказано «service layer leaking DB details», он должен сослаться на что-то вроде internal/orders/service/order_service.go и точный вызов (например db.QueryContext), чтобы можно было исправить утечку без споров о смысле.
Руководство стиля приживается, когда процесс повторяем. Цель — заставить модель проверять правила, а не спорить о вкусе, и делать это одинаково каждый раз.
Используйте простой двухэтапный workflow:
Пример: в PR добавлен новый эндпоинт. Первый проход помечает, что хендлер обращается к PostgreSQL напрямую (layering), используются смешанные имена для структур запроса (naming), и логируются полные email (logging). Второй проход делает минимальные исправления: перенос запроса в service или repository, переименование структуры и маскирование email в логах. Больше ничего не меняется.
Проблемы с именованием кажутся мелкими, но они создают реальные расходы: люди неправильно читают намерения, поиск усложняется, и почти одинаковые имена множатся.
Укажите правила именования, которые ревьюер должен применить ко всему изменению: имена файлов, экспортируемых типов, функций, переменных, констант и тестов. Будьте явными по поводу регистра (camelCase, PascalCase, snake_case) и выберите одно правило для акронимов (например APIClient vs ApiClient). Затем требуйте его везде.
Также стандартизируйте общий словарь: типы ошибок, поля логов и ключи конфигурации. Если в логах используется request_id, не допускайте reqId в одном файле и requestId в другом.
Практическая инструкция для ревьюера:
Check every new or renamed identifier. Enforce casing + acronym rules.
Flag vague names (data, info, handler), near-duplicates (userId vs userID), and names that contradict behavior.
Prefer domain language: business terms over generic tech words.
Попросите короткий отчёт: три самых запутанных имени, любые почти-дубликаты и какое имя оставить, а также имена логов/конфигураций/ошибок, не соответствующие стандарту.
Правила слоёв работают лучше, когда сформулированы простым языком: handlers работают с HTTP, services содержат бизнес-логику, repositories работают с базой данных.
Зафиксируйте направление зависимостей. Handlers могут вызывать services. Services могут вызывать repositories. Repositories не должны вызывать services или handlers. Handlers не должны импортировать код базы данных, SQL-хелперы или ORM-модели. Если у вас есть общие пакеты (config, time, IDs), держите их без логики приложения.
Назначьте кросс-срезные обязанности в одно место. Валидация обычно на границе для формы запроса и в service для бизнес-правил. Авторизация часто начинается в handler (идентичность, scope), но service должен обеспечивать окончательное решение. Маппинг выполняется на границах: handler мапит HTTP в domain input, repository мапит DB-строки в domain типы.
Вставьте это в промпт, чтобы ревьюера было легко удержать конкретику:
Check layering: handler -> service -> repository only.
Report any leaks:
- DB types/queries in handlers or services
- HTTP request/response types inside services or repositories
- repository returning DB models instead of domain objects
- auth/validation mixed into repository
For each leak, propose the smallest fix: move function, add interface, or rename package.
Сделайте отчёт явным: укажите файл, слой, к которому он относится, импорт или вызов, нарушающий правило, и минимальное изменение, которое предотвратит распространение паттерна.
Большинство споров по стилю разгораются, когда что-то ломается в проде. Чёткая политика обработки ошибок успокаивает процесс исправлений, потому что все знают, как должен выглядеть «правильный» код.
Пропишите философию и обеспечьте её исполнение. Например: «Оборачивайте ошибки, чтобы добавить контекст; создавайте новую ошибку только при изменении смысла или при сопоставлении с сообщением для пользователя. Возвращайте сырые ошибки только на границе системы». Одна такая фраза предотвращает разброс паттернов.
Отделяйте текст для пользователя от внутренних деталей. Пользовательские сообщения должны быть короткими и безопасными. Внутренние ошибки могут содержать имя операции и ключевые идентификаторы, но не секреты.
В ревью проверяйте несколько повторяющихся ошибок: проглатывание ошибок (залогировано, но не возвращено), неоднозначные возвращаемые значения (nil значение и nil ошибка после провала) и пользовательские сообщения, которые сливают стек-трейсы, текст запросов, токены или PII. Если у вас есть retries или таймауты, требуйте, чтобы они были явными.
Пример: вызов оплаты тайм-аутится. Пользователь видит «Payment service is taking too long.» Внутри — оберните таймаут, добавив op=checkout.charge и order ID, чтобы это было удобно искать и действовать.
Логи помогают только когда все пишут их одинаково. Если каждый разработчик придумывает собственную формулировку, уровень и поля, поиск превращается в угадайку.
Сделайте уровни логов обязательными: debug — для деталей разработки, info — для обычных значимых событий, warn — для неожиданных, но обработанных ситуаций, error — когда действие пользователя терпит неудачу или требует внимания. Держите «fatal» или «panic» редкими и привязанными к явной политике краша.
Структурированные логи важнее идеальных предложений. Требуйте стабильных имён ключей, чтобы дашборды и оповещения не ломались. Решите небольшой набор ключей (например event, component, action, status, duration_ms) и используйте их последовательно.
Относитесь к чувствительным данным как к жёсткому запрету. Ясно пропишите, что нельзя логировать: пароли, auth-токены, полные номера карт, секреты и сырые персональные данные. Отдельно отметьте вещи, которые кажутся безобидными, но нет: ссылки для сброса пароля, session ID и полные тела запросов.
Correlation ID делает отладку возможной между слоями. Требуйте request_id в каждой строчке лога в контексте запроса. Если логируете user_id, определите, когда это разрешено и как обозначать отсутствие или анонимность пользователя.
Блок промпта, который можно переиспользовать:
Review the changes for logging conventions:
- Check level usage (debug/info/warn/error). Flag any level that does not match impact.
- Verify structured fields: require stable keys and avoid free-form context in the message.
- Confirm correlation identifiers: request_id on all request-bound logs; user_id only when allowed.
- Flag any sensitive data risk (tokens, secrets, personal data, request/response bodies).
- Identify noisy logs (in loops, per-item logs, repeated success messages) and missing context.
Return: (1) violations with file/line, (2) suggested rewrite examples, (3) what to add or remove.
Перед мерджем сделайте краткий «safety pass»: любые новые логи без request_id для запросной работы, любые новые ключи, которые меняют существующие имена (userId vs user_id), любые error-логи без указания того, что пошло не так (операция, ресурс, статус), любые высокочастотные логи, которые сработают на каждом запросе, и любая возможность появления секретов или персональных данных в полях или сообщениях.
Относитесь к дрейфу стиля как к сбою сборки, а не к предложению. Добавьте строгий gate, который запускается перед мерджем и возвращает ясное пройдено/не пройдено. Если нарушено обязательное правило (именование, границы слоёв, безопасность логов, обработка ошибок), оно проваливается и указывает точные файлы и строки.
Держите gate быстрым. Одна практическая трюк — требовать ДА/НЕТ чеклист по каждому правилу и не давать одобрения, если хоть один пункт — НЕТ.
Чеклист размером с PR, который ловит большую часть проблем:
Когда инструмент предлагает исправления, требуйте маленький корректный сниппет для каждого затронутого правила. Это предотвращает расплывчатую обратную связь вроде «переименуйте для ясности».
Самый быстрый способ провалить руководство стиля — оставить место для интерпретаций. Если два ревьюера прочитают одно и то же правило и придут к разным выводам, инструмент будет навязывать вкус, а не стандарт.
Именование — частый пример. «Используйте понятные имена» непроверяемо. Уточните до проверяемого уровня: «функции — глаголы (например createInvoice), булевы — с префиксом is/has/can, экспортируемые типы — PascalCase».
Ещё одна ловушка — просить всё и сразу. Когда один промпт пытается покрыть именование, слои, ошибки, логирование, тесты и производительность, обратная связь становится поверхностной. Разделяйте ревью на фокусные проходы при необходимости или держите gate-пrompt ограниченным обязательными правилами.
Проблемы, которые приводят к дрейфу:
Если вы относитесь к промптам как к тестам, получите предсказуемое соблюдение. Если как к советам — нарушения прокрадутся и размножатся.
Сделайте быстрый проход по diff (не по всему репозиторию) и подтвердите:
Держите маленький шаблон промпта и вставляйте его с каждым изменением:
Review ONLY the changed code against our rules for naming, layering, errors, and logging.
List mandatory violations first (with file + line if available). Then list optional suggestions.
End with either: “no mandatory violations found” or “mandatory violations found”.
Пример: новая функция procUsr() в handler, которая пишет в PostgreSQL напрямую, должна провалить naming и layering, даже если фича работает. Поймать это здесь предотвращает распространение через copy-paste.
Коллега добавляет новый эндпоинт: POST /v1/invoices/{id}/send. Изменяются handler, service и storage.
На первом проходе нужен отчёт, не переписывание:
Pass 1 (report only)
You are a strict style checker. Read the patch.
Rules: naming must match our guide, handlers call services only, services call storage only, no SQL in handlers,
errors must be wrapped with context, logs must be structured and not leak PII.
Output: a numbered list of violations with file:line, rule name, and one-sentence impact. Do not propose fixes.
If a rule might be intentionally broken, ask one clarification question.
Типичные находки: SendInvoiceNow() vs SendInvoice — несоответствие именования, handler вызывает db.QueryRow напрямую, возвращается сырой err без контекста, и шумные логи вроде log.Printf("sending invoice %v", invoice), которые дампят целые объекты.
Второй проход просит минимальные, безопасные изменения:
Pass 2 (minimal fix suggestions)
Using the violations list, propose the smallest code edits to comply.
Constraints: keep behavior the same, no refactors beyond what is needed, show suggested function names and where code should move.
For each fix, include 1-2 lines of example code.
Если нарушение правила допустимо, скажите об этом сразу: «Исключения разрешены только при добавлении короткого комментария с объяснением и создании follow-up задачи на их удаление."
После исправлений handler становится тонким адаптером, service владеет workflow, storage владеет запросом, ошибки превращаются в fmt.Errorf("send invoice: %w", err), а логи — в одну аккуратную строку с безопасными полями (invoice ID, а не весь invoice).
Выберите один командой утверждённый промпт и используйте его как общий инструмент. Начните с того, что чаще всего мешает в ревью (дрейф имен, утечки слоёв, непоследовательные ошибки, небезопасные логи). Обновляйте промпт только когда видите реальное нарушение в реальном коде.
Держите небольшой блок правил в начале промпта и вставляйте его в каждое ревью без изменений. Если все будут редактировать правила каждый раз, у вас не будет стандарта — у вас будет спор.
Простая периодичность помогает: один человек собирает топ ошибок за неделю и вы добавляете ровно одно более ясное правило или один лучший пример.
Если вы работаете в чат-ориентированном процессе сборки вроде Koder.ai (koder.ai), стоит запускать те же gate-проверки во время изменений, а не только в конце. Функции вроде планирования, снимков и отката помогают держать правки стиля небольшими и обратимыми до экспорта исходного кода.