SSD Nodes Learn Hosting plans →
Руководства Matt ConnorАвтор: Matt Connor · Обновлено 2026-08-26

Вложенные файлы 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. Корневой файл, описывающий четыре сервиса, тратит этот лимит на три из них при выполнении каждой задачи.

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

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

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

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

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

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

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

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

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

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

Это поведение было проверено по документации Codex и Claude Code в августе 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?

Нет, и об этом стоит сказать прямо, так как вложенная структура зависит именно от этого. По состоянию на август 2026 года в документации указано: «Claude Code читает CLAUDE.md, а не AGENTS.md». Этот шаблон по-прежнему работает, вам просто нужно разместить CLAUDE.md рядом с каждым AGENTS.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 для создания символической ссылки требуются права администратора или включенный режим разработчика (Developer Mode), поэтому используйте там импорт через @AGENTS.md.

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

Настройки для подключения других агентов к 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 создается вами, фиксируется в 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 в этой директории в том же коммите. Размещение файла рядом с кодом помогает соблюдать это правило, так как изменения попадают в тот же pull request, который уже просматривает человек. Добавьте предупреждение в CI, которое сопоставляет каждый измененный путь с ближайшим файлом AGENTS.md выше по дереву, и периодически сравнивайте git log -1 --format=%cs для каждого файла с результатом выполнения той же команды для директории, которую он описывает.

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

Нет. По состоянию на август 2026 года в документации указано: «Claude Code читает CLAUDE.md, а не AGENTS.md». Создайте CLAUDE.md в той же директории, указав @AGENTS.md в первой строке; это загрузит общий файл и позволит добавить специфичные для Claude инструкции ниже. Символическая ссылка, созданная с помощью ln -s AGENTS.md CLAUDE.md, работает, если не нужно добавлять ничего дополнительного, хотя в Windows для этого требуются права администратора или включенный режим разработчика. Выполните /context в сессии и убедитесь, что файл появился в разделе Memory files.

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

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