SSD Nodes Learn Hosting plans →
Руководства Matt ConnorАвтор: Matt Connor

Как настроить вложенные AGENTS.md в монорепозитории

Разберите схему вложенных AGENTS.md для монорепозитория: корневые правила и инструкции сервисов сокращают контекст агента и не устаревают в одном файле.

Что означает вложенный AGENTS.md в монорепозитории

Вложенный AGENTS.md в монорепозитории означает наличие одного небольшого файла в корне репозитория и еще по одному файлу внутри каждой директории сервиса. Корневой файл содержит несколько правил, актуальных для всего проекта, а также карту расположения остальных файлов. Каждый файл сервиса содержит команды и соглашения, относящиеся только к этой директории. Агент, редактирующий services/worker/queue.py, считывает корневой файл и файл рабочего сервиса, не тратя контекст на фронтенд, с которым он не будет работать.

Ничего устанавливать не нужно. AGENTS.md — это соглашение, и в исходном проекте об этом сказано прямо:

AGENTS.md — это обычный Markdown. Используйте любые заголовки; агент просто парсит предоставленный вами текст.

Именно поэтому стоит правильно освоить этот метод. Формат не изменится. То, что может нарушиться — это размещение и поддержка, и то и другое входит в ваши обязанности.

Почему один большой файл AGENTS.md в корне перестает работать?

Один файл AGENTS.md объемом 600 строк в корне репозитория, содержащего веб-приложение, фоновый воркер и директорию Terraform, дает сбои по четырем разным причинам.

Он устаревает, потому что у него нет владельца. Инженер, который переименовывает тестовый скрипт в apps/web, редактирует файлы в apps/web. Корневой AGENTS.md не попадает в этот diff, поэтому никто из проверяющих не видит несоответствия. Через шесть недель файл описывает этап сборки, которого больше не существует, а человек, который внес изменения, уже забыл об этом.

Он расходует контекст при каждой задаче. Эти файлы загружаются в начале сессии, до того как агент узнает, о чем вы собираетесь спросить. В документации Claude Code указано: «старайтесь, чтобы размер файла CLAUDE.md не превышал 200 строк. Более длинные файлы потребляют больше контекста и снижают точность выполнения инструкций». Codex перестает объединять файлы инструкций, как только их суммарный размер достигает 32 KiB, что является значением по умолчанию для project_doc_max_bytes. Корневой файл, описывающий четыре сервиса, тратит этот лимит на три из них при выполнении каждой отдельной задачи.

Инструкции начинают противоречить друг другу. Веб-директория требует pnpm test. Воркер требует pytest -q. Будучи записанными в одном файле, каждое правило оказывается верным лишь частично, поэтому агенту приходится угадывать, какое из них применимо. Документация Claude Code описывает результат: «если две инструкции противоречат друг другу, Claude может выбрать одну из них произвольно». Файл в каждой директории исключает необходимость гадать, так как в контексте всегда находится только одно из двух правил. Когда правило, которое вы четко прописали, все равно игнорируется, лучше разобраться в причинах, по которым инструкция не срабатывает, чем переписывать формулировку в четвертый раз.

Он заполняется фактами, которые агент может прочитать из кода. Дерево директорий, список зависимостей, краткое описание того, что делает каждый пакет. Проверка /doctor в Claude Code существует именно для того, чтобы удалять такие данные. Она «отсекает контент, который Claude может извлечь из кодовой базы самостоятельно, например, структуру директорий, списки зависимостей и обзоры архитектуры», и оставляет «подводные камни, обоснования и соглашения, которые отличаются от стандартных настроек инструментов». Это предложение — лучший известный мне способ проверить, стоит ли вообще включать строку в файл.

Читает ли агент корневой файл или только ближайший?

Здесь большинство пользователей ошибаются в понимании модели работы, поэтому стоит процитировать официальное соглашение, а не пересказывать его:

Размещайте файл AGENTS.md внутри каждого пакета. Агенты автоматически считывают ближайший файл в дереве каталогов, поэтому приоритет имеет самый близкий файл, и каждый подпроект может содержать специализированные инструкции.

О конфликтах:

Файл AGENTS.md, расположенный ближе всего к редактируемому файлу, имеет приоритет; явные запросы пользователя в чате переопределяют всё остальное.

Фраза «имеет приоритет» для многих звучит как «корневой файл игнорируется». Это не так. В инструментах, реализующих данное соглашение, считываются и объединяются все файлы на пути от корня репозитория до рабочей директории. Ближайший файл побеждает только в том случае, если два файла содержат противоречивые указания по одному и тому же вопросу.

Codex прямо описывает этот механизм: «Codex объединяет файлы, начиная от корня, соединяя их пустыми строками. Файлы, расположенные ближе к вашей текущей директории, переопределяют более ранние инструкции». Claude Code работает аналогично. При запуске сессии он считывает «каждый AGENTS.md и .claude/AGENTS.md в вашей рабочей директории и директориях выше неё», а документация ясно описывает модель загрузки: «Все найденные файлы объединяются в контекст, а не переопределяют друг друга». Директории ниже рабочей ведут себя иначе: Claude Code загружает AGENTS.md поддиректории по требованию, «когда Claude открывает там файл с помощью инструмента Read».

Из этого следуют два практических вывода. Корневой файл является префиксом для каждой сессии в репозитории, поэтому каждая строка в нём — это строка, за которую вы платите сотни раз в неделю. Файл в конкретной директории ничего не стоит, пока агент работает в другом месте, поэтому там можно не экономить на деталях.

Данное поведение было проверено по документации Codex и Claude Code 12 октября 2026 года. Инструменты реализуют это соглашение с небольшими различиями и могут обновляться, поэтому уточняйте правила загрузки для того агента, который использует ваша команда.

Рабочая структура репозитория с тремя сервисами

repo/
  AGENTS.md                   rules true everywhere, plus the map
  apps/web/AGENTS.md          TypeScript client, Vite, Vitest
  services/worker/AGENTS.md   Python queue consumer, pytest
  infra/AGENTS.md             Terraform and the deploy scripts

Корневой файл намеренно сделан коротким. Он указывает, где искать информацию, и содержит только те правила, которые действуют во всех директориях.

# AGENTS.md

This is a monorepo. Each top-level directory ships its own AGENTS.md.
Read this file and the AGENTS.md nearest the code you are editing
before you change anything.

- `apps/web` browser client
- `services/worker` queue consumer
- `infra` Terraform and deploy scripts

## Rules for the whole repository

- The package manager is `pnpm`. `npm install` writes a second lockfile
  that CI ignores, so the install you tested is not the install that ships.
- Any `generated/` directory is build output. Edit the schema in
  `schemas/` and run `pnpm codegen` instead.
- `.env.local` holds real credentials. Do not read it and do not print it.
- If you change code in a directory, update that directory's AGENTS.md
  in the same commit.

Файл в каждой директории содержит детали и может быть настолько подробным, насколько это необходимо для данной директории.

# apps/web

Browser client. Vite and React, TypeScript with `strict` on.

## Commands

- `pnpm dev` serves on port 5173.
- `pnpm test` runs Vitest once and exits.
- `pnpm typecheck` runs `tsc --noEmit`.

## Conventions

- One component per file under `src/components/`.
- All HTTP goes through `src/api/client.ts`. Do not call `fetch` directly,
  because the client attaches the auth header and retries on 429.

## Traps

- `pnpm build` does not type check. Vite strips the types instead of
  checking them, so a broken type still produces a green build.
  Run `pnpm typecheck` as a separate step.

Файл рабочего процесса имеет ту же структуру, но другое содержание: команду установки, pytest -q, причину, по которой потребитель должен оставаться идемпотентным, и миграцию, которая должна выполниться до прохождения тестов. В файле инфраструктуры вы прописываете правила, которые не позволяют агенту нанести вред. Никогда не запускайте terraform apply. Выполняйте terraform plan и останавливайтесь на этом, указывая бэкенд состояния, который уже настроен, чтобы агент не пытался инициализировать новый.

Обратите внимание, чего нет ни в одном из этих файлов: описания того, для чего предназначен каждый сервис. Это информация для людей. Upstream проводит ту же границу, утверждая, что «файлы README.md предназначены для людей: быстрый старт, описание проекта и правила внесения правок», в то время как AGENTS.md содержит «дополнительный, иногда детальный контекст, необходимый агентам для написания кода: этапы сборки, тесты и соглашения». В разделении между AGENTS.md и ориентированным на людей README эта граница рассматривается предложение за предложением, а файл DESIGN.md, фиксирующий причины, по которым код организован именно так охватывает третий тип файлов — тех, что объясняют принятые решения, а не команды.

Кто обновляет файл при изменении кода?

Существует одно правило, которое прописано в корневом файле: любой, кто изменяет код в директории, обязан обновить файл AGENTS.md в этой же директории в рамках того же коммита.

Это работает по техническим причинам, а не из-за корпоративной культуры. Файл в конкретной директории попадает в тот же diff, что и код, поэтому рецензент pull request видит их одновременно. Корневой файл принадлежит всем, а значит — никому; он никогда не попадает в diff, который кто-то просматривает в данный момент.

Подкрепите это правило проверкой в pull request. Она находит ближайший файл AGENTS.md для каждого измененного файла и сообщает, если этот файл не был затронут.

#!/usr/bin/env bash
# Warn when code changed but the nearest AGENTS.md above it did not.
changed=$(git diff --name-only origin/main...HEAD)

nearest_doc() {
  d=$(dirname "$1")
  while [ "$d" != "." ]; do
    if [ -f "$d/AGENTS.md" ]; then echo "$d/AGENTS.md"; return; fi
    d=$(dirname "$d")
  done
  echo "AGENTS.md"
}

printf '%s\n' "$changed" | while read -r f; do
  [ -n "$f" ] || continue
  case "$f" in AGENTS.md|*/AGENTS.md) continue ;; esac
  doc=$(nearest_doc "$f")
  printf '%s\n' "$changed" | grep -Fqx "$doc" && continue
  echo "note: $f changed but $doc was not updated"
done

В ветке, где был переработан API client, но не была обновлена документация, вывод выглядит так:

note: apps/web/src/api/client.ts changed but apps/web/AGENTS.md was not updated

Пусть это будет предупреждением, а не блокирующей ошибкой. Жесткий запрет приучает людей добавлять пустую строку в файл только ради того, чтобы CI стал зеленым. Файл, отредактированный ради робота, бесполезен. Предупреждение дает рецензенту повод задать вопрос, и именно это работает на практике.

Как определить, что файл AGENTS.md устарел?

Сегодня вы можете выполнить две проверки, а также обратить внимание на один симптом, возникающий во время сессии.

Сравните дату изменения каждого файла с датой кода, который он описывает. %cs выводит дату коммита в формате YYYY-MM-DD.

for f in $(git ls-files '*AGENTS.md'); do
  d=$(dirname "$f")
  printf '%s  doc:%s  code:%s\n' "$f" \
    "$(git log -1 --format=%cs -- "$f")" \
    "$(git log -1 --format=%cs -- "$d")"
done
apps/web/AGENTS.md          doc:2026-02-11  code:2026-08-07
services/worker/AGENTS.md   doc:2026-07-29  code:2026-08-09
infra/AGENTS.md             doc:2026-08-01  code:2026-08-01

Если дата документации отстает от даты кода на шесть месяцев, это не доказывает, что файл содержит ошибки. Это лишь указывает, какой файл следует прочитать в первую очередь, и это всё, что требуется от проверки, занимающей одну секунду.

Ищите пути, которые больше не существуют. Документация устаревает вполне конкретным образом: она продолжает описывать код, который был удален. Каждый путь в этих файлах оформлен в обратных кавычках, поэтому их легко извлечь и проверить.

grep -o '`[^`]*`' apps/web/AGENTS.md | tr -d '`' | grep '/' | while read -r p; do
  [ -e "$p" ] || [ -e "apps/web/$p" ] || echo "missing: $p"
done

Изучайте вывод команды вручную, а не интегрируйте её в CI. Она также помечает шаблоны (globs), такие как src/**/*.ts, и любые указанные вами URL, поскольку оба содержат косую черту и не являются файлами на диске.

Симптом во время сессии. Агент читает файл, пытается открыть src/api/client.ts, так как файл дал такую инструкцию, и инструмент возвращает:

No such file or directory

В результате агент поступает логично и пишет собственную обертку fetch. В этом и заключается реальная цена устаревшего файла. Агент не игнорирует вашу документацию. Он следует ей, переходит по пути, который был удален три месяца назад, и пересобирает код, который у вас уже есть. Такие навыки, как Ponytail, который ограничивает агента минимально необходимыми изменениями, делают подобный инстинкт пересборки более редким, но они не способны найти вспомогательный инструмент, на который ваш файл указывает неверно.

Читает ли Claude Code файлы AGENTS.md?

Да, начиная с версии Claude Code v2.1.277. Точное правило имеет значение, так как от него зависит вложенная структура. Согласно документации на 12 октября 2026 года: «Claude Code может читать AGENTS.md в качестве инструкций для вашего проекта, поэтому репозиторий, уже настроенный для других агентов кодирования, будет работать без добавления CLAUDE.md, импорта или дополнительных настроек». Значение по умолчанию для Project instructions, claude-md-or-agents-md, гласит: «ваши файлы AGENTS.md, если в рабочем каталоге или выше него отсутствуют CLAUDE.md или CLAUDE.local.md». Вложенные файлы также учитываются: Claude читает AGENTS.md в подкаталоге, «когда Claude открывает там файл с помощью инструмента Read», при условии, что в этом подкаталоге нет собственного CLAUDE.md.

Это превращает старый совет размещать CLAUDE.md рядом с каждым AGENTS.md в ловушку. При наличии AGENTS.md и CLAUDE.md или CLAUDE.local.md в рабочем каталоге или выше, документация указывает, что Claude читает «только ваши файлы CLAUDE.md». Один сопутствующий файл в корне, содержащий единственную строку для Claude, скрывает все AGENTS.md по пути, и персональный CLAUDE.local.md делает то же самое. Если вы хотите сохранить оба, введите /config и установите для Project instructions значение claude-md-and-agents-md, которое считывает оба файла: сначала CLAUDE.md каждого каталога, а затем его AGENTS.md.

Чтобы убедиться, что всё работает, выполните claude --version и проверьте версию v2.1.277 или новее. В интерактивном сеансе Claude Code выводит строку типа no CLAUDE.md found; AGENTS.md loaded: с указанием пути, а /memory отображает список файлов.

Форма импорта по-прежнему актуальна там, где Claude не может читать AGENTS.md напрямую: в старой версии, в сеансе, где отключен встроенный плагин для чтения, или в проекте, где сохранен CLAUDE.md с параметром Project instructions, установленным в claude-md. Добавьте это в services/worker/CLAUDE.md:

@AGENTS.md

## Claude Code

Use plan mode for changes under `services/worker/migrations/`.

Форма символической ссылки (symlink) подходит, когда нет необходимости добавлять специфические для инструмента параметры.

git ls-files '*AGENTS.md' | while read -r f; do
  ln -s AGENTS.md "$(dirname "$f")/CLAUDE.md"
done
ls -l apps/web/CLAUDE.md

ln не выводит ничего при успешном выполнении, поэтому проверьте список: apps/web/CLAUDE.md -> AGENTS.md. Затем начните сеанс и выполните /context, где загруженные файлы появятся в разделе Memory files. В Windows для создания символической ссылки требуются права администратора или режим разработчика, поэтому используйте там импорт @AGENTS.md. Если вы настроили любой из этих обходных путей до того, как Claude Code начал читать AGENTS.md самостоятельно, их можно оставить: согласно документации, сохранение импорта «никогда не заставляет Claude читать AGENTS.md дважды», а символическая ссылка CLAUDE.md считывается один раз.

С этим связана одна ловушка. После /compact файл CLAUDE.md в корне проекта считывается с диска заново, но вложенные файлы в подкаталогах не перечитываются. Claude Code перезагружает их по требованию, когда агент в следующий раз работает с файлом в этом каталоге. Документация разъясняет это для файлов CLAUDE.md и не описывает отдельно процесс сжатия для AGENTS.md, считываемого напрямую, поэтому ожидайте, что вложенные файлы с любым из этих имен будут вести себя одинаково. Если правило для конкретного каталога перестает применяться в середине долгого сеанса, обычно причина в этом; чтение любого файла в этом каталоге восстановит работу правила.

Настройки, указывающие другим агентам на AGENTS.md

Codex читает AGENTS.md нативно. На каждом уровне он сначала проверяет AGENTS.override.md, что позволяет задать локальное переопределение для одного каталога без редактирования общего файла. Он прекращает объединение, как только суммарный размер достигает 32 KiB (значение project_doc_max_bytes по умолчанию), что является еще одной причиной сохранять корневой файл небольшим.

Aider принимает его через .aider.conf.yml со строкой read: AGENTS.md.

Gemini CLI принимает его через .gemini/settings.json с помощью { "context": { "fileName": "AGENTS.md" } }.

В документации вышестоящего проекта указано обратное переименование для репозиториев, все еще использующих старое единственное имя: mv AGENT.md AGENTS.md && ln -s AGENTS.md AGENT.md.

В очень больших монорепозиториях настройка claudeMdExcludes в Claude Code позволяет пропускать файлы предков по пути или маске (glob), что полезно, если каталог другой команды находится выше вашего. Эти шаблоны применяются и к файлам AGENTS.md, которые считывает Claude Code.

Чем это отличается от памяти агента или навыка?

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

Файл AGENTS.md создается вами, фиксируется в git, проходит проверку в pull request и является идентичным для всех, кто клонирует репозиторий. Память агента создается самим агентом, хранится вне репозитория и привязана к одной конкретной машине. Документация Claude Code проводит ту же границу: CLAUDE.md содержит «Инструкции и правила», которые пишете вы, автоматическая память хранит «Изученное и шаблоны», которые записывает Claude, а директория с памятью не синхронизируется между машинами. Проверка проста. Если факт должен быть верным для коллеги, работающего с чистой копией репозитория, он не может находиться в памяти. Как память агента сохраняется между сессиями описывает эту часть процесса.

Навык — это третий элемент. AGENTS.md — это контекст, который загружается в каждой сессии; навык — это процедура, которая загружается по мере необходимости. Документация Claude Code предлагает полезное правило: «Если запись представляет собой многошаговую процедуру или важна только для одной части кодовой базы, перенесите ее в навык или правило, ограниченное путем». Вторая часть этого предложения — именно то, что решают вложенные файлы AGENTS.md. Первая часть — это то, для чего предназначены навыки агента, а если одна и та же процедура требуется в нескольких репозиториях, используйте общий навык для разных репозиториев вместо того, чтобы копировать одни и те же абзацы в десять разных файлов AGENTS.md.

Разработчики upstream отмечают, что «на момент написания в основном репозитории OpenAI содержится 88 файлов AGENTS.md». Это число — главный аргумент. Большому репозиторию не нужен один огромный файл. Ему нужно больше маленьких файлов, каждый из которых находится рядом с кодом, который он описывает, и за каждый из которых отвечает тот, кто последним вносил изменения в этот код.

FAQ

Заменяет ли вложенный AGENTS.md корневой файл или дополняет его?

Он дополняет его. В upstream сказано: «приоритет имеет ближайший файл». Это описывает поведение при конфликте, а не то, какие файлы загружаются. Codex «объединяет файлы от корня вниз, разделяя их пустыми строками», а Claude Code объединяет каждый найденный файл при переходе вверх от рабочей директории, а не заменяет их. Ближайший файл имеет приоритет только в тех случаях, когда два файла содержат разные инструкции по одной теме. Запишите общие правила один раз в корневом файле и не повторяйте их в каждой директории.

Каким должен быть размер корневого AGENTS.md?

Он должен быть достаточно небольшим, чтобы вы не возражали против его добавления в начало каждого запроса, который отправляете в этом репозитории. Именно это и происходит. Документация Claude Code рекомендует ориентироваться на размер менее 200 строк для каждого файла и предупреждает, что более длинные файлы «снижают соблюдение инструкций». По умолчанию Codex прекращает объединять файлы инструкций после достижения общего размера 32 KiB. Если в корневом файле описаны четыре сервиса, то для любой отдельной задачи большая часть этого содержимого не нужна. Перенесите подробности в файлы для отдельных директорий и оставьте вместо них карту.

Как не допустить устаревания этих файлов?

Добавьте в корневой файл одно правило: тот, кто изменяет код в директории, обновляет AGENTS.md этой директории в том же коммите. Размещение файла рядом с кодом помогает соблюдать это правило, потому что изменение тогда попадает в diff того же pull request, который человек и так просматривает. Добавьте предупреждение CI, которое сопоставляет каждый изменённый путь с ближайшим AGENTS.md выше него, и время от времени сравнивайте git log -1 --format=%cs в каждом файле с результатом той же команды, выполненной для директории, которую этот файл описывает.

Читает ли Claude Code файлы AGENTS.md?

Да, начиная с v2.1.277. Согласно документации, проверенной 12 October 2026, Claude Code по умолчанию читает AGENTS.md, если в рабочей директории или выше неё нет CLAUDE.md или CLAUDE.local.md, а AGENTS.md поддиректории читает, когда открывает находящийся в ней файл с помощью инструмента Read. Не добавляйте CLAUDE.md рядом с каждым AGENTS.md: если такой файл находится в рабочей директории или выше неё, Claude читает только «Your CLAUDE.md files». Если вам также нужен CLAUDE.md, задайте Project instructions равным claude-md-and-agents-md в /config или укажите @AGENTS.md в его первой строке. Выполните /memory в сеансе и убедитесь, что в списке появился путь AGENTS.md.

Куда поместить правило, которое нужно только иногда?

Не в AGENTS.md. Этот файл загружается в каждом сеансе, поэтому каждая его строка конкурирует за внимание с фактическим запросом, который вы ввели. Процедуру из нескольких шагов, которая требуется время от времени, следует поместить в skill, загружаемый по требованию. Правило, применимое к одной директории, следует поместить в AGENTS.md этой директории. Факт, который агент может прочитать непосредственно из кода, например дерево директорий или список зависимостей, не следует помещать ни в один из них.