Почему AI-агенты игнорируют инструкции пользователя
Агенты часто нарушают правила из-за переполнения контекстного окна или конфликтов в коде. Узнайте, как диагностировать проблему и заставить модель следовать вашим указаниям.
Почему агенты для написания кода игнорируют ваши инструкции
Агенты для написания кода игнорируют ваши инструкции по четырем причинам, и ни одна из них не связана с тем, что вы были слишком вежливы. Правило не попало в контекстное окно. Правило было слишком расплывчатым, чтобы проверить по нему действие. Что-то другое в контексте противоречило ему — обычно это код, который агент только что прочитал. Или правило все еще загружено, но находится далеко за пределами текущего диалога, и агент работает с тем, что находится ближе.
У каждой причины есть свое решение, поэтому первая задача — научиться их различать. Заглавные буквы и слово IMPORTANT не являются диагностикой. В механике ниже в качестве примера используется Claude Code, поскольку его поведение при загрузке и сжатии данных подробно задокументировано по состоянию на август 2026 года. Другие инструменты отличаются в деталях, но в общих чертах ведут себя так же.
Сначала определим два термина. Контекстное окно — это блок текста, который модель видит на конкретном этапе: системный промпт, файлы с вашими инструкциями, история диалога и каждый файл, который агент прочитал. Обвязка (harness) — это программа вокруг модели, которая считывает файлы с диска и собирает этот блок. Почти каждая жалоба в этом посте на самом деле является жалобой на обвязку, а не на модель.
Файл инструкций — это сообщение, а не настройка
Файл инструкций не является конфигурацией. Ни один компонент среды выполнения не считывает CLAUDE.md и не принуждает к его исполнению. Инструментарий считывает файл с диска и вставляет текст в диалог. В Claude Code это содержимое передается как сообщение пользователя, размещенное после системного промпта. Это означает, что модель видит ваши правила так же, как и любой другой введенный вами текст.
У этого есть неприятное следствие. Ваши правила конкурируют с любым другим текстом в окне на равных основаниях. Правило — это утверждение. Файл, который агент только что открыл, — это доказательство. Когда они противоречат друг другу, доказательство часто побеждает, и никакой ошибки не возникает, потому что с точки зрения модели ничего не пошло не так.
Официальная документация прямо говорит об этом: файлы инструкций рассматриваются как контекст, а не как принудительная конфигурация. Чтобы заблокировать действие независимо от решения модели, вам нужен хук, а не предложение. Запомните это правило. Большинство исправлений в конце этой статьи представляют собой применение этого принципа к конкретному случаю.
Какие файлы инструкций загружаются и когда
Claude Code выполняет поиск вверх по дереву каталогов, начиная с той директории, в которой вы его запустили. Все файлы CLAUDE.md и CLAUDE.local.md, начиная от корня файловой системы и заканчивая вашей рабочей директорией, загружаются целиком при запуске. Они объединяются в указанном порядке, поэтому файл, расположенный ближе всего к месту запуска, считывается последним, а внутри одной директории файл .local добавляется после основного.
Файлы в поддиректориях ниже вашей рабочей директории ведут себя иначе. Они не загружаются при запуске. Они загружаются в тот момент, когда агент считывает файл в этой директории. То же самое относится к правилам с ограничением по пути в .claude/rules/, которые содержат поле frontmatter paths:: они попадают в контекст при чтении соответствующего файла, а не на каждом шаге.
Эта единственная разница объясняет значительную часть зарегистрированных сбоев. Вы помещаете правило в packages/api/CLAUDE.md, задаете вопрос об API, и агент отвечает, не открывая ни одного файла в packages/api/. Правило не было проигнорировано. Оно просто не было загружено. Если в вашем репозитории рекомендации разделены по файлам инструкций для каждого пакета в монорепозитории, это первое, что нужно проверять каждый раз.
Еще одна ловушка при загрузке, и это самая распространенная версия ситуации «агент проигнорировал мои инструкции»: Claude Code считывает CLAUDE.md, а не AGENTS.md. Репозиторий, стандартизированный на AGENTS.md и не имеющий CLAUDE.md, не дает Claude Code ничего для загрузки. Поддерживаемым мостом является файл CLAUDE.md, первой строкой которого идет @AGENTS.md, что импортирует файл при запуске, с любыми примечаниями для Claude ниже. Символическая ссылка также работает, если вам нечего добавить. Решение о том, что именно должно находиться в этом файле, — отдельный вопрос, который рассматривается в разделении инструкций для агента и документации для людей.
Убедитесь, что файл загружен, прежде чем перезаписывать его
Не меняйте формулировки, пока не получите доказательств того, что агент видит файл. Существует две проверки, и сначала выполняется более простая.
Выполните /context внутри сессии. Команда выводит текущее окно, разбитое по категориям, а список Memory files содержит названия всех файлов инструкций, которые были успешно загружены. Если файла нет в этом списке, значит, он не участвует в диалоге, поэтому любые изменения в нём не принесут результата. /memory выводит пути к файлам и открывает их для редактирования, включая те, которые ещё не существуют.
Для более точной проверки используйте логирование загрузок. Событие хука InstructionsLoaded срабатывает каждый раз, когда CLAUDE.md или файл правил попадает в контекст, а его сопоставитель (matcher) указывает причину загрузки: session_start, nested_traversal, path_glob_match, include или compact. Добавьте это в .claude/settings.json:
{
"hooks": {
"InstructionsLoaded": [
{
"matcher": "nested_traversal",
"hooks": [
{
"type": "command",
"command": "cat >> /tmp/instructions-loaded.log"
}
]
}
]
}
}Хук получает данные в формате JSON через стандартный ввод, поэтому cat дописывает всю запись целиком. Следите за этим файлом с помощью tail -f /tmp/instructions-loaded.log во время работы. Код завершения этого события игнорируется, поэтому хук может только наблюдать, но не блокировать действия. Если ваш вложенный файл не появляется в этом логе во время сессии, когда вы ожидаете его увидеть, прекратите редактирование. Проблема заключается в размещении файла.
Как длительная сессия влияет на ваши правила
Здесь действуют два отдельных эффекта, требующих разных подходов.
Дистанция. Правило, заданное на 1-м шаге, остается в окне контекста на 90-м шаге, конкурируя с 90 шагами текста, который является более свежим и специфичным для текущей задачи. Это нельзя исправить настройками, но можно измерить. Запустите ту же задачу в новой сессии. Если правило работает там, но перестает действовать в конце длинной сессии, причина в дистанции.
Сжатие. Когда окно заполняется, система суммирует ход беседы и продолжает работу на основе этого резюме. Сохраняется то, что алгоритм суммирования счел важным, а это не всегда совпадает с вашим мнением. Claude Code документирует результат для каждого механизма, и различия существенны. Корневой файл проекта CLAUDE.md и правила без области действия повторно считываются с диска после сжатия. Автоматическая память также перезагружается с диска. Правила с метаданными paths: теряются до тех пор, пока соответствующий файл не будет прочитан снова. Вложенные файлы CLAUDE.md в поддиректориях теряются до тех пор, пока не будет прочитан файл в этой поддиректории.
Распределите свои инструкции согласно этой таблице, и вы увидите порядок их уязвимости. Правило, введенное только в чате, является самым хрупким элементом сессии: оно сохраняется, только если алгоритм суммирования случайно его оставил. Правило в packages/api/CLAUDE.md находится на втором месте, так как оно было загружено один раз, удалено при суммировании и возвращается только при следующем чтении в этой директории. Правило в корневом файле проекта является самым устойчивым, так как оно считывается с диска при каждом обращении.
Поэтому, если инструкция должна действовать на протяжении всей сессии, она должна находиться в корневом файле проекта без метаданных paths:. Все остальное — это компромисс, на который вы должны идти осознанно. В Управление содержимым окна контекста рассматриваются /compact с аргументом focus и /clear между несвязанными задачами; оба этих метода меняют частоту, с которой алгоритм суммирования принимает решение о том, какими были ваши правила.
Почему окружающий код важнее правила
Это сбой, который люди описывают чаще всего, а диагностируют реже всего. Ваш файл гласит, что доступ к базе данных должен идти через уровень репозитория. Агент пишет обработчик, который обращается к ORM (object relational mapper) напрямую. Вас проигнорировали не из-за стиля. Вас перевесили факты.
Правило описывает предпочтение. Код демонстрирует его. Когда агент открывает три файла в модуле, который собирается редактировать, и все три обращаются к ORM напрямую, контекст содержит одно абстрактное предложение с одной стороны и три конкретных, актуальных, подходящих под задачу примера с другой. Копирование локального паттерна — обычно верное поведение. Здесь оно ошибочно только потому, что вы знаете то, чего не знает контекст: эти файлы являются legacy.
Поэтому запишите это в правило. Правила, которые сами называют свои контрпримеры, выживают при столкновении с реальным репозиторием. Правила, которые просто выражают предпочтение, — нет.
Новый доступ к базе данных должен идти черезapp/repositories/. Файлы вapp/legacy/по-прежнему обращаются к ORM напрямую. Это старый код, а не паттерн. Не копируйте его.
Второе предложение выполняет всю работу. Оно говорит агенту, что он собирается найти и как это интерпретировать, еще до того, как он это найдет. Та же правка применима к любому правилу, которому ваш репозиторий явно противоречит: стиль коммитов, которому не следует ваша история, структура тестов, которую игнорирует половина вашего набора, соглашение об импортах, которое соблюдается только в новом коде. Везде, где код не согласуется с файлом, укажите на это несоответствие в самом файле.
Размытое правило невозможно проверить, а значит, его нельзя соблюсти
«Пишите чистый код». «Не усложняйте». «Придерживайтесь простоты». «Будьте осторожны с миграциями». Ни одно из этих требований нельзя проверить на соответствие конкретному действию ни агенту, ни вам. Если агент получает правило, которое он не может сопоставить со своим результатом, он начинает гадать, а вы оцениваете его догадки на основе собственных ощущений.
Примените этот тест к каждой строке вашего файла. Напишите команду оболочки, которая завершится с ненулевым кодом, если правило нарушено. Если вы не можете написать такую команду, правило невозможно проверить. Сравните эти пары:
- Нельзя проверить: «Пишите короткие функции». Можно проверить: «Функция длиннее 60 строк должна иметь комментарий сверху с объяснением причин».
- Нельзя проверить: «Тестируйте изменения». Можно проверить: «Запустите
npm testи вставьте количество ошибок перед тем, как считать задачу выполненной». - Нельзя проверить: «Держите файлы в порядке». Можно проверить: «HTTP-обработчики должны находиться в
src/api/handlers/. Никакие другие файлы не должны быть в этой директории». - Нельзя проверить: «Форматируйте код правильно». Можно проверить: «Используйте отступ в 2 пробела в файлах
.ts».
Правило «Не усложняйте» — это то, от чего люди отказываются в первую очередь, потому что решение заключается не в сокращении предложения, а в его расширении: детальное описание того, что именно означает минимально необходимое изменение, дает агенту критерии, по которым он может оценить собственный diff.
Размер файла — это та же проблема под другим углом. Рекомендации Claude Code ограничивают объем файла инструкций 200 строками и прямо указывают, что более длинные файлы снижают точность выполнения. Файл на 700 строк не является более строгой инструкцией. Это 700 строк утверждений, в которых больше шансов на противоречия, и они расходуют ваше окно контекста на каждом шаге, что напрямую отражается на потреблении токенов. Структурирование файла таким образом, чтобы каждое правило находилось под заголовком, который легко просканировать взглядом, описано в написании файла инструкций, с которым агент может работать.
Как провести диагностику за десять минут
Выполняйте эти действия по порядку. Переход сразу к последнему шагу — причина, по которой у пользователей накапливаются длинные списки неработающих правил.
- Проверьте загрузку. Выполните
/contextи изучите список файлов Memory. Если файла нет в списке, исправьте путь и остановитесь. Остальные пункты пока не имеют значения. - Воспроизведите в новой сессии. Запустите новую сессию и дайте минимальную задачу, которая должна активировать правило. Если проблема возникает только в длительной сессии, причина в удаленности или сжатии данных. Если проблема возникает сразу — ошибка в самом правиле.
- Устраните конкуренцию. Попробуйте применить то же изменение в директории, где существующий код уже соответствует правилу. Если соответствие восстановилось, значит, окружающий код перекрывал вашу инструкцию.
- Найдите конфликт. Наличие двух файлов с противоречивыми указаниями для одного и того же действия — задокументированная ошибка: модель может выбрать любой из них произвольно, не уведомляя вас об этом.
- Сделайте правило проверяемым и повторите тест. Перепишите правило, добавив конкретный путь и условие. Значительный рост соответствия правилам означает, что проблема была в формулировках.
Шаг 4 выполняется одной командой. Выполните поиск по всем источникам инструкций, а не только по тому файлу, который вы редактировали:
grep -rni "migration" --include="CLAUDE.md" --include="CLAUDE.local.md" .
grep -rni "migration" .claude/rules/ ~/.claude/CLAUDE.md ~/.claude/rules/ 2>/dev/nullНахождение двух файлов с противоречивыми указаниями — это и есть ваша ошибка. Удалите один из них. Не пытайтесь приоритизировать их с помощью более строгих формулировок, так как механизм ранжирования отсутствует.
Способы исправления: от простых к эффективным
Каждый последующий шаг обладает большей эффективностью, чем предыдущий, но требует больших затрат на настройку. Начинайте с верхних пунктов, если правило легко переформулировать. Переходите к нижним, как только правило становится критически важным и пропуски становятся недопустимы.
- Сделайте правило конкретным. Укажите путь, команду или условие. Добавьте контрпримеры, которые агент обнаружит в репозитории, как было показано ранее. Это бесплатно и исправляет удивительно много случаев.
- Переместите правило ближе к объекту управления. Используйте вложенный
CLAUDE.md, правило с ограничением пути в.claude/rules/или комментарий в начале самого файла. Правило будет прочитано одновременно с кодом, к которому оно относится. Примите компромисс: всё, что загружается таким образом, вытесняется при следующей компактизации и возвращается при следующем соответствующем чтении. - Перенесите принудительное исполнение в хук. Текст — это просьба. Хук — это решение. Хуки выполняются как код в определённые моменты жизненного цикла и срабатывают независимо от выводов модели.
- Передайте правило детерминированному инструменту и удалите текстовое описание. Это касается форматирования, порядка импортов, длины строки, запрещённых импортов, структуры сообщения коммита. Используйте
ruff format,prettier --write,eslintили хукpre-commit. Форматировщик всегда прав и не тратит токены. Предложение правомерно в большинстве случаев, но расходует токены при каждом обращении.
Разбор шага 3. Допустим, агент не должен редактировать файлы миграций. Добавьте это в .claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/guard-migrations.sh"
}
]
}
]
}
}И это в .claude/hooks/guard-migrations.sh:
#!/usr/bin/env bash
set -euo pipefail
path=$(jq -r '.tool_input.file_path // empty')
case "$path" in
*/migrations/*)
echo "Files under migrations/ are written by hand. Stop and ask first." >&2
exit 2
;;
esac
exit 0Запустите chmod +x .claude/hooks/guard-migrations.sh, затем начните новую сессию и попросите агента отредактировать файл в migrations/. Редактирование будет отклонено, а ваше сообщение вернётся в качестве причины. Код завершения 2 в PreToolUse блокирует вызов инструмента до его запуска, а ваш текст из stderr передаётся модели как блокирующее сообщение. ${CLAUDE_PROJECT_DIR} указывает на корень проекта, поэтому хук работает независимо от того, в какой директории находится агент. Агенту не нужно соглашаться с правилом, помнить его или удерживать в контексте. Редактирование не произойдёт.
Для простого запрета без логики, permissions.deny в ваших настройках выполнит ту же задачу без необходимости поддерживать скрипт, а права доступа определяют, что будет запущено без предварительного запроса. Если инструкцию действительно необходимо разместить на уровне системного промпта, а не в сообщении пользователя, --append-system-prompt поместит её туда. Однако её придётся передавать при каждом вызове, что больше подходит для скриптов, чем для интерактивной работы.
Чего нельзя добиться инструкциями
Четко разделяйте зоны ответственности. Размещение, формулировки, конфликты между файлами и размер файлов — это проблемы автора, которые решаются автором. Остальное — поведение модели, и лучшие формулировки его не исправят.
Согласие не означает выполнение. Агент подтвердит правило, правильно повторит его вам и нарушит через два вызова инструментов. Подтверждение ничего не стоит и ничего не гарантирует. Не воспринимайте его как исправление и не считайте проверкой.
Некоторые привычки устойчивы. Добавление комментариев, защитная обработка ошибок, написание итогового резюме, выполнение очевидной следующей команды. Они возвращаются даже при наличии запрещающего правила, пусть и реже, но не исчезают полностью. Вы можете измерить частоту нарушений самостоятельно: выполните одну и ту же задачу десять раз в новых сессиях и подсчитайте количество нарушений. Если число должно быть равно нулю, правило нужно убрать из промпта.
Ваша собственная сессия становится примером. Если агент нарушил правило на 12-м шаге, а вы проигнорировали это, нарушение остается в контексте как образец, и оно гораздо свежее, чем само правило. Исправляйте нарушение в момент его обнаружения. Неисправленное нарушение обучает модель на оставшуюся часть сессии.
Файл инструкций не является границей безопасности. Он формирует поведение, но не принуждает к нему. Все, где ошибка стоит дорого — учетные данные или деструктивные команды — должно регулироваться правами доступа или хуками. Ограничение доступа агента к секретам применяет тот же принцип к данным: не просите агента не читать файл, сделайте файл недоступным для чтения.
Краткая версия. Докажите, что файл загружен, сделайте правило проверяемым, разместите его рядом с объектом, который оно регулирует, а если частота ошибок все еще критична — уберите правило из текста. Правило, которое агент не может проигнорировать — это правило, о котором агента никогда не просили.
FAQ
Почему Claude Code игнорирует мой CLAUDE.md?
Прежде чем делать вывод, что файл игнорируется, убедитесь, что он был загружен. Выполните /context и изучите список Memory files; если файла нет в этом списке, значит, он не участвует в диалоге. Файлы с инструкциями передаются как сообщение пользователя после системного промпта и рассматриваются как контекст, а не как принудительная конфигурация, поэтому строгая гарантия соблюдения отсутствует. В большинстве случаев проблема вызвана одной из четырех причин: файл находится в поддиректории, которую агент не читал; два файла противоречат друг другу, и модель выбрала один из них произвольно; правило сформулировано слишком расплывчато, чтобы сопоставить его с действием; или окружающий код демонстрирует обратное тому, что сказано в правиле.
Изменяет ли что-то редактирование файла инструкций во время сессии?
Нет, для копии, которая уже находится в диалоге. Файлы, расположенные выше вашей рабочей директории, загружаются целиком при запуске, поэтому модель оперирует текстом, актуальным на момент старта. Чтобы применить изменения, начните новую сессию или попросите агента прочитать файл с помощью стандартных инструментов работы с файлами — это добавит текущую версию в диалог как новое сообщение. После выполнения CLAUDE.md файл из корня проекта считывается с диска заново, поэтому новая версия появится в контексте в этот момент.
Какой файл имеет приоритет, если CLAUDE.md в корне и вложенный файл противоречат друг другу?
Ни один из них не имеет гарантированного приоритета. Обнаруженные файлы объединяются в контексте, а не перекрывают друг друга; они упорядочиваются от корня файловой системы до вашей рабочей директории, поэтому последний прочитанный файл — это тот, что находится ближе всего. Механизма разрешения противоречий не существует, и документация Claude Code указывает, что противоречивые правила могут применяться произвольно. Пишите вложенные файлы как дополнения, указывающие путь, к которому они относятся, и удаляйте противоречия вместо попыток переопределить их.
Сохраняются ли мои инструкции после /compact?
Это зависит от способа их загрузки. Файл в корне проекта CLAUDE.md, правила без указания области действия и автоматическая память повторно считываются с диска после сжатия. Правила с фронтметром paths: и вложенные файлы CLAUDE.md в поддиректориях теряются до тех пор, пока соответствующий файл не будет прочитан снова. Всё, что вы ввели только в чат, сохранится, только если суммаризатор случайно включил это в отчет. Если правило должно действовать на протяжении всей сессии, поместите его в файл в корне проекта без фронтметра paths:.
Когда правило стоит превратить в хук, а не оставлять в виде текста?
Когда проверка детерминирована, а цена ошибки выше, чем затраты на написание небольшого скрипта. К таким случаям относятся ограничения на пути к файлам, обязательные команды перед коммитом и запрещенные вызовы инструментов. Хук PreToolUse, который завершается с кодом 2, полностью блокирует вызов инструмента и возвращает ваш текст из stderr модели в качестве причины, поэтому правило будет действовать независимо от того, присутствует ли оно в контексте. Всё, что может проверить форматер или линтер, должно быть передано этим инструментам и полностью удалено из файла инструкций.