6 мин

Как давать Claude Code контекст, чтобы код был точнее

Разбираем, как давать 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 или менять структуру ответа, нарушение видно сразу.

Пошаговый процесс: как давать задачу и получать предсказуемый код

Держитесь простого ритуала. Он занимает пару минут, зато заметно снижает шанс, что модель «додумает» недостающие детали.

Удобный порядок:

  1. Цель и критерии готовности. Несколько коротких пунктов: что должно работать и как вы это проверите (например: «все тесты проходят», «API не меняется», «ошибки обрабатываются так-то»).
  2. Окружение и технические ограничения. Язык, версия, фреймворк, где запускается (локально, контейнер, CI), стиль кода, запрет на новые зависимости.
  3. Минимальные примеры вход-выход. 1-2 обычных примера и один крайний.
  4. Рамка изменений. Какие файлы/модули можно трогать, а какие нельзя. Если критично - отдельно «не переименовывать сущности», «не переписывать архитектуру».
  5. Сначала план, потом код. Попросите план правок и список вопросов. Подтвердите план - и только затем просите финальный дифф или код.

Когда код готов, не ограничивайтесь «проверь, все ли ок». Лучше попросить самопроверку по точкам:

  • где он мог неверно понять требования и что именно предположил;
  • какие риски (регрессии, гонки, ошибки типов) и как их проверить;
  • какие тесты/кейсы он бы запустил и почему.

Как просить проверку результата и ловить ошибки раньше

Сделайте примеры вход-выход
Сформулируйте 2-4 кейса и запреты, и получите предсказуемый результат.

Чтобы было меньше сюрпризов, просите не только «сделай», но и «проверь по правилам». Модель может угадать недостающие детали и подать это как факт, поэтому полезно отдельно фиксировать проверку.

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

Попросите перечислить затронутые сценарии: не только «счастливый путь», но и ошибки, пустые значения, отсутствие прав, пустую базу, повторный запрос. Если модель не называет такие случаи, требования все еще двусмысленны.

Формула запроса на ревизию

Просите ревизию «по требованиям», а не «сделай лучше». «Лучше» часто означает лишние рефакторинги и неожиданные изменения. Удобная формулировка: «Проверь решение строго по требованиям и ограничениям. Найди несоответствия и места, где нужны уточнения, но не меняй архитектуру».

В ответе попросите одним блоком:

  • Короткие тест-кейсы: что проверить руками и что покрыть тестом.
  • Затронутые сценарии: нормальный, ошибочный, пустой ввод.
  • Объяснение простыми словами: что было, что стало.
  • Список предположений: где он мог «догадаться».
  • Вопросы на уточнение: что нужно подтвердить до мержа.

Небольшой пример

«Проверь реализацию по требованиям: кнопка “Сохранить” должна быть неактивна при пустом имени; при ошибке сервера показываем текст ошибки. Не добавляй новых библиотек. Сначала дай тест-кейсы, потом список рисков и уточняющих вопросов».

Частые ошибки в промптах и как их быстро исправить

Большая часть «галлюцинаций» в коде появляется из-за размытых запросов. Ищите места, где ассистент вынужден угадывать.

  • «Сделай лучше» без критерия успеха. Замените на измеримые признаки: «уменьши время ответа эндпойнта 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) и переписать запрос по шаблону. Один такой прогон обычно дает больше пользы, чем набор общих советов.

Похожие статьи