Как давать Claude Code контекст, чтобы код был точнее
Разбираем, как давать Claude Code контекст: требования, ограничения, примеры вход-выход и рамка изменений, чтобы снизить ошибки и правки.

Почему Claude Code может придумывать детали в коде
«Галлюцинации» в коде обычно выглядят не как фантазия, а как уверенный, аккуратный ответ, который не собирается или ведет себя не так. Типичные примеры: вызов несуществующей функции, импорт из пакета, которого нет, или «логика по умолчанию», которую вы не просили добавлять.
Почти всегда причина в контексте. Модель заполняет пробелы самым вероятным способом: если вы не показали текущий API, структуру проекта или реальные ограничения, она подставит привычный шаблон из похожих задач. Если в описании есть противоречия (например, «не меняй поведение» и одновременно «сделай по-другому»), она выберет один вариант и продолжит так, будто все согласовано.
Важно понимать: контекст - это не просто длинное описание. Контекст - это проверяемые опоры: что уже есть в коде, что нельзя трогать, как выглядит вход и какой выход ожидается. Чем меньше таких опор, тем больше догадок.
Есть симптомы, которые видно сразу, еще до запуска:
- Код расходится с требованиями или добавляет лишнее.
- Меняются имена функций, сигнатуры, поля JSON или статус-коды, и внешний API ломается.
- Появляются «удобные» рефакторинги и переезды файлов без запроса.
- Меняется поведение по умолчанию: новые значения, другая сортировка, новые проверки.
- Подтягиваются импорты и зависимости, которых нет в проекте.
Предсказуемый результат зависит не от того, «насколько умная» модель, а от того, насколько четко вы задали рамки. Ниже - техники, которые делают ответ проще проверять: структурированные требования, ограничения, примеры вход-выход и заранее заданный контур изменений.
Какой контекст реально помогает, а какой только мешает
Если цель туманная, ИИ начнет заполнять пустоты догадками. Поэтому полезно давать не «контекста побольше», а ровно то, что убирает двусмысленность.
Лучше всего работает связка из пяти опор: цель изменения (что должно стать лучше), ограничения (что трогать нельзя), окружение (язык, фреймворк, версии, где запускается), входы и выходы (что приходит и что должно уходить), критерии готовности (как вы поймете, что все ок). Этого чаще всего достаточно, чтобы правки были управляемыми.
Дополнительный контекст тоже бывает полезен: короткая история решения (почему так, а не иначе), обсужденные альтернативы, договоренности команды. Он помогает выбрать стиль и не повторить старые ошибки, но его легко раздуть так, что он начнет отвлекать.
Смысл чаще всего теряется там, где не проговорены термины и границы. Например, вы пишете «заказ», но не уточняете: это запись в базе, DTO для API или объект доменной модели. Или просите «добавить валидацию», но не говорите, где она должна жить: в контроллере, в сервисе или в отдельном модуле.
Как понять, чего не хватает
Хороший признак, что контекст неполный: ассистент вынужден выбирать за вас. В таких случаях полезно просить его сначала задать уточняющие вопросы. Минимальный набор:
- Какие входные данные и примеры реальных значений?
- Какой точный формат выхода (поле, статус, сообщение об ошибке)?
- Какие модули можно менять, а какие нельзя?
- Какие кейсы считаются ошибками и как их обрабатывать?
- Какие тесты или проверки подтвердят готовность?
Как держать контекст коротким, но точным
Сжимайте задачу до «карточки изменения» на 8-12 строк. Например: «React форма регистрации: добавить поле phone, формат +7XXXXXXXXXX, хранить как строку, UI не менять кроме поля, API контракт прежний, ошибки показывать под полем, готово когда проходят текущие тесты и добавлен тест на неверный номер». Текст короткий, но рамка понятная и почти не оставляет места для фантазии.
Шаблон структурированных требований для запроса
Когда просите Claude Code написать или изменить код, главная цель - убрать догадки. Помогает простой формат, где ясно: какой результат нужен, что уже есть, и что менять нельзя.
Ниже - шаблон, который хорошо работает и для новых фич, и для правок. Его можно копировать и заполнять перед каждой задачей.
Цель (1 предложение)
- Что должно измениться для пользователя/системы в итоге.
Текущая ситуация
- Где находится код (папка/модуль/файл, если знаете).
- Как сейчас работает поведение.
- Какие есть ограничения окружения (язык, фреймворк, БД).
Нужно сделать (поведение, не реализация)
- Новое/измененное поведение: что происходит и при каких условиях.
- Пограничные случаи: пустые значения, ошибки, права доступа, таймауты.
- Совместимость: что должно остаться как было.
Критерии готовности
- Проверяемые признаки: какие запросы/клики/кейсы должны пройти.
- Ожидаемый результат: что видим в UI/логах/ответе API.
- Минимальный набор тестов или сценариев ручной проверки.
Нельзя (запреты и инварианты)
- Что не трогать: публичные API, схему БД, контракты, зависимости.
- Что не добавлять: новые библиотеки, миграции, фоновые джобы.
- Ограничения по безопасности и данным.
Пример для раздела «Цель»: «После отправки формы показывать понятную ошибку, если сервер вернул 400». Это про результат, а не про то, как именно обрабатывать ответ.
Самый важный раздел - «Нельзя». Он резко снижает шанс, что модель начнет «улучшать» проект: переименует сущности, добавит зависимости или поменяет поведение в соседних местах.
Если вы используете TakProsto, этот шаблон удобно держать как заготовку и вставлять в чат первым блоком перед задачей - так изменения остаются компактными и проще проверяются.
Ограничения и допущения: как задавать границы
Когда запрос без границ, ИИ заполняет пробелы догадками. Ограничения нужны не для бюрократии, а чтобы модели не приходилось придумывать.
Начните с правил, которые нельзя нарушать. Формулируйте их коротко и проверяемо: «не добавлять новые зависимости», «не менять публичный API», «не менять названия файлов», «не трогать существующие тесты, кроме исправления падений».
Часто достаточно указать:
- Язык и стиль: версия (например, TypeScript 5), фреймворк (React), соглашения (camelCase, eslint/prettier), формат ошибок и логов.
- Зависимости: запрещено добавлять пакеты, нельзя менять версии.
- Данные: формат (JSON/CSV), кодировка (UTF-8), локаль (ru-RU), часовой пояс (Europe/Moscow), как обрабатывать пустые значения.
- Производительность: что критично (время ответа, память), а что не критично.
- Совместимость: какие окружения поддерживать (Node 18, PostgreSQL 14).
После ограничений добавьте допущения - ответы на вопросы, которые модель иначе будет угадывать. Примеры: «можно считать, что поле userId всегда есть», «данные уже валидированы на входе», «ошибки возвращаем в одном формате», «авторизация уже сделана выше по стеку».
Короткий пример рамки: вы просите добавить новое поле в ответ API. Ограничения: не менять маршруты и названия полей, не добавлять зависимости, сохранить обратную совместимость. Допущения: в базе поле уже существует и заполнено. С такими границами ИИ не начнет менять структуру ответа или тянуть новую библиотеку для валидации.
Примеры вход-выход: самый простой способ убрать двусмысленность
Если важен точный формат, начните с примеров. Два коротких кейса часто работают лучше, чем полстраницы описаний, потому что фиксируют формат, правила и границы.
Примеры особенно важны там, где есть строгие правила: парсинг строк, валидация полей, форматирование дат и денег, генерация текста по шаблону, набор исключений. В таких задачах ИИ легко угадывает намерение не так, как вы ожидаете.
Как писать примеры коротко и полезно
Обычно хватает 2-4 кейсов: один типовой, один с вариацией и один крайний. Крайний кейс должен проверять то, что часто забывают: пустые значения, лишние пробелы, неизвестный статус, нулевую сумму.
Оформляйте одинаково: «Вход» -> «Ожидаемый выход» и одна строка, почему так. Например, для нормализации номера телефона:
Вход: "+7 (999) 111-22-33"
Выход: "+79991112233"
Пояснение: удаляем пробелы и скобки, сохраняем +7.
Вход: "8 999 1112233"
Выход: "+79991112233"
Пояснение: 8 в начале считаем российским префиксом.
Вход: ""
Выход: ошибка "phone is required"
Пояснение: пустое значение не допускается.
Контрпример: что НЕ должно происходить
Иногда полезнее показать запрет, чем разрешение. Один контрпример помогает остановить «улучшения» данных:
- Вход: "999" -> Ошибка, а не попытка «дополнить» до номера.
- Вход: "+7abc" -> Ошибка, а не удаление букв и «почти» корректный результат.
Чтобы не оставлять серых зон, укажите единицы измерения (рубли или копейки), формат дат, допустимы ли null и пустая строка, и как выглядят ошибки (текст, код, поле).
Рамка изменений перед правками: чтобы не расползался дифф
Когда ИИ пишет код без границ, он часто «улучшает» лишнее: переименовывает функции, двигает файлы, меняет формат данных или добавляет зависимости. «Рамка изменений» - это короткое описание того, что разрешено трогать, а что нельзя. По сути, вы заранее задаете контур будущего диффа.
Сформулируйте рамку как набор явных разрешений и запретов. Лучше всего работает, когда вы называете конкретные файлы или модули.
До начала кода полезно зафиксировать:
- Где можно менять: конкретные файлы/папки, 1-2 модуля, тесты (можно или нельзя).
- Инварианты: публичные API не меняем, формат JSON не ломаем, поведение для старых кейсов сохраняем.
- Масштаб: «только добавить», «не переименовывать», «не переносить файлы», «без новых зависимостей».
- Подход: минимальная правка или рефакторинг (выберите одно и объясните почему).
- Критерий готовности: какие тесты должны пройти, какой пример запроса/ответа должен совпасть.
Практичный прием - попросить сначала план, а код писать только после согласования: «Сначала дай план из 5-7 шагов с перечнем затрагиваемых файлов и рисками. Жди моего ОК. Потом генерируй патч».
Пример рамки: вы добавляете поле isArchived в ответ API. Разрешено менять только DTO и сериализацию в одном эндпоинте, плюс тест. Запрещено менять имена существующих полей и правила сортировки. Если ИИ начнет «заодно» переименовывать archived_at или менять структуру ответа, нарушение видно сразу.
Пошаговый процесс: как давать задачу и получать предсказуемый код
Держитесь простого ритуала. Он занимает пару минут, зато заметно снижает шанс, что модель «додумает» недостающие детали.
Удобный порядок:
- Цель и критерии готовности. Несколько коротких пунктов: что должно работать и как вы это проверите (например: «все тесты проходят», «API не меняется», «ошибки обрабатываются так-то»).
- Окружение и технические ограничения. Язык, версия, фреймворк, где запускается (локально, контейнер, CI), стиль кода, запрет на новые зависимости.
- Минимальные примеры вход-выход. 1-2 обычных примера и один крайний.
- Рамка изменений. Какие файлы/модули можно трогать, а какие нельзя. Если критично - отдельно «не переименовывать сущности», «не переписывать архитектуру».
- Сначала план, потом код. Попросите план правок и список вопросов. Подтвердите план - и только затем просите финальный дифф или код.
Когда код готов, не ограничивайтесь «проверь, все ли ок». Лучше попросить самопроверку по точкам:
- где он мог неверно понять требования и что именно предположил;
- какие риски (регрессии, гонки, ошибки типов) и как их проверить;
- какие тесты/кейсы он бы запустил и почему.
Как просить проверку результата и ловить ошибки раньше
Чтобы было меньше сюрпризов, просите не только «сделай», но и «проверь по правилам». Модель может угадать недостающие детали и подать это как факт, поэтому полезно отдельно фиксировать проверку.
Рабочий вариант: сначала попросить набор проверок, а уже потом код. Например: «Опиши, как я проверю результат вручную, и какие автотесты добавил бы». Так быстрее видно, что именно считается «готово», и проще поймать расхождения до правок.
Попросите перечислить затронутые сценарии: не только «счастливый путь», но и ошибки, пустые значения, отсутствие прав, пустую базу, повторный запрос. Если модель не называет такие случаи, требования все еще двусмысленны.
Формула запроса на ревизию
Просите ревизию «по требованиям», а не «сделай лучше». «Лучше» часто означает лишние рефакторинги и неожиданные изменения. Удобная формулировка: «Проверь решение строго по требованиям и ограничениям. Найди несоответствия и места, где нужны уточнения, но не меняй архитектуру».
В ответе попросите одним блоком:
- Короткие тест-кейсы: что проверить руками и что покрыть тестом.
- Затронутые сценарии: нормальный, ошибочный, пустой ввод.
- Объяснение простыми словами: что было, что стало.
- Список предположений: где он мог «догадаться».
- Вопросы на уточнение: что нужно подтвердить до мержа.
Небольшой пример
«Проверь реализацию по требованиям: кнопка “Сохранить” должна быть неактивна при пустом имени; при ошибке сервера показываем текст ошибки. Не добавляй новых библиотек. Сначала дай тест-кейсы, потом список рисков и уточняющих вопросов».
Частые ошибки в промптах и как их быстро исправить
Большая часть «галлюцинаций» в коде появляется из-за размытых запросов. Ищите места, где ассистент вынужден угадывать.
- «Сделай лучше» без критерия успеха. Замените на измеримые признаки: «уменьши время ответа эндпойнта X», «убери N+1 запросы в списке заказов», «добавь валидацию, чтобы при пустом email возвращалось 400 с кодом ошибки».
- Несколько работ в одном запросе. Когда вы просите «добавь фичу + отрефактори + ускорь», модель двигает все сразу и задевает лишнее. Разрежьте на 2-3 задачи и закрепите порядок: функциональность, затем чистка, затем оптимизация.
- Противоречивые ограничения. «Не менять публичный API» и тут же «переименуй поля ответа». Вынесите ограничения отдельным блоком и проверьте, нет ли взаимоисключений.
- Валидация без примеров ошибок. В результате ассистент придумает свои правила. Дайте несколько кейсов (пустая строка, частично корректный ввод, корректный ввод) и ожидаемые ответы.
- Нет рамки изменений, дифф расползается. Помогает короткий набор правил: менять только файлы A и B; стиль не трогать без необходимости; новые зависимости не добавлять без согласования; текущие имена функций и API сохранить.
Часто забывают и про формат ответа. Уточните, что именно вам нужно: короткий патч, список точных правок или готовые файлы. Если вы работаете в среде с экспортом исходников и откатами (например, в TakProsto), формат «патч + список файлов» обычно помогает быстрее проверить изменения и при необходимости откатиться.
Короткий чеклист перед тем, как просить код
Перед отправкой задачи пробегитесь по списку. Это занимает 2-3 минуты, но часто экономит часы на правках:
- Сформулируйте цель одной фразой и рядом напишите критерии готовности. Убедитесь, что они не спорят друг с другом.
- Перечислите ограничения: какие зависимости уже есть, какие API доступны, какие данные приходят на вход, какой стиль или паттерны нужно сохранить. Если что-то нельзя использовать - скажите прямо.
- Добавьте 2-4 примера вход-выход. Один сделайте крайним (пустой ввод, очень длинная строка, неизвестный статус, null).
- Задайте рамку изменений: какие файлы и модули можно менять, а что трогать нельзя (публичные интерфейсы, схема БД, контракт ответа).
- Если задача затрагивает больше одного файла, попросите сначала короткий план: шаги, какие места в коде будут затронуты, какие риски. После кода - самопроверку: список допущений и что могло пойти не так.
Пример формулировки: «Нужно добавить валидацию телефона в форме регистрации. Готово, если номера +7XXXXXXXXXX и 8XXXXXXXXXX принимаются, остальные дают понятную ошибку. Нельзя менять формат ответа API и нельзя трогать компонент Header. Примеры: “+79991234567” -> ok, “89991234567” -> ok, “123” -> ошибка, пусто -> ошибка. Сначала план, потом код. В конце перечисли допущения и проверь, что тесты проходят».
Пример: добавляем небольшую фичу и не ломаем существующее
Удобно тренироваться на маленьких изменениях. Сценарий: в форме профиля нужно добавить поле company (название компании), но старые клиенты продолжают отправлять данные без него.
Сначала опишите текущий поток данных простыми словами: «Пользователь заполняет форму -> фронт отправляет JSON на сервер -> сервер валидирует -> сохраняет -> возвращает обновленный профиль». Затем зафиксируйте, какой формат уже существует (какие поля обязательны, какие нет) и где это используется (UI, валидатор API, ответ сервера).
Дальше - примеры входа и ожидаемого выхода. Обычно хватает трех кейсов:
- Корректный ввод:
company="ООО Ромашка"-> поле сохраняется и возвращается в ответе. - Пустое значение:
company=""или поле отсутствует -> сервер трактует как «не задано», старое поведение сохраняется. - Неверный формат: слишком длинная строка или запрещенные символы -> понятная ошибка валидации.
Теперь границы: «Не менять публичные эндпоинты и их пути. Не добавлять новые зависимости. Не менять схему авторизации. Старые клиенты должны продолжать работать без изменений». Это снижает риск, что ассистент предложит «удобный» рефакторинг или новый пакет.
Задайте рамку изменений: UI (добавить поле и отобразить), сервер (принять необязательное поле, валидировать, сохранить), тесты (добавить 2-3 проверки). Отдельно: «Не трогать остальные поля формы, не менять формат ответа кроме добавления нового поля».
В конце попросите результат в проверяемом виде: патч (дифф) и короткий список затронутых сценариев и рисков. Например: что будет, если фронт отправит null вместо строки.
Следующие шаги: закрепляем процесс и переносим в рабочий поток
Чтобы это работало каждый день, сделайте шаблон запроса и храните его как заготовку: файл в репозитории или заметка, которую вы копируете перед каждой задачей. Тогда качество будет стабильнее.
Привычка простая: сначала план и вопросы, потом код и самопроверка. Если ответ сразу ушел в реализацию, остановите и попросите вернуться к рамке изменений и критериям готовности.
Мини-процесс, который легко встроить в работу:
- Заполните шаблон: цель, ограничения, рамка изменений, критерии готовности.
- Добавьте 1-2 примера вход-выход или сценария использования.
- Попросите короткий план и список вопросов, если есть неопределенности.
- После кода попросите самопроверку по критериям и перечисление затронутых файлов.
- Зафиксируйте итог: что изменили и что не трогали.
Если вы работаете в команде, договоритесь о едином формате. Иначе каждый будет приносить разный уровень деталей, и результат будет «плавать». Достаточно зафиксировать простые правила: как оформляем примеры вход-выход, как описываем критерии готовности, какой масштаб изменений считаем допустимым.
Если вы делаете продукт через чат-разработку, удобно включать режим планирования и фиксировать состояние перед правками. На TakProsto (takprosto.ai) те же принципы работают напрямую: задаете требования, рамку изменений и примеры, а затем используете снимки и откат, чтобы спокойно пробовать разные варианты и быстро возвращаться назад.
Следующий шаг - взять одну текущую задачу (например, добавить поле в форме, не меняя API) и переписать запрос по шаблону. Один такой прогон обычно дает больше пользы, чем набор общих советов.