AGENTS.mdとCLAUDE.mdの違いと同期方法:@インポート・リンク・生成スクリプト・モノレポ配置
CodexとClaude CodeがAGENTS.md・CLAUDE.mdをどの順で読むかを公式ドキュメントで確認し、3つの同期方式とモノレポ3階層での読み込みをWindowsで実測。2026年9月14日時点の挙動です。
AGENTS.md と CLAUDE.md を両方置くなら、AGENTS.md を正本にして、CLAUDE.md には @AGENTS.md の1行と Claude Code 固有の追記だけを書くのが、Windows でも壊れない最短の構成です。 シンボリックリンクは Windows で権限に引っかかり、生成スクリプトは CI で同期チェックまで組めるので大規模向きです。
「2つのファイルは何が違うのか」は AGENTS.md完全ガイド で扱いました。この記事は一段下りて、各ツールがどのファイルをどの順で読むかを公式ドキュメントで確認し、3つの同期方式を実際に Windows 環境で動かして比べます。後半では、モノレポで指示ファイルを階層ごとに置いたときにどれが読まれるかも実測します。
先に結論
- Claude Code は CLAUDE.md だけ、Codex は AGENTS.md だけを読む。 公式ドキュメントが双方でそう明記しています。相手のファイルを勝手に拾うことはありません。
@AGENTS.mdインポートは実測で効いた。 CLAUDE.md に1行書くだけで、AGENTS.md の内容と CLAUDE.md 側の追記の両方がセッションに載りました。- Windows のシンボリックリンクは権限で落ちる。
mklinkは非管理者では失敗し、Git のcore.symlinksも false でした。 - 生成スクリプトは
--checkで片方だけ古い状態を検知できる。 複数人・複数ツールなら CI に入れる価値があります。 - モノレポでは、上位の CLAUDE.md は起動時に全部、下位はそのディレクトリのファイルを読んだ時に追加される(実測)。 連結はルート側が先、近い側が後で、Codex の公式仕様も同じ向きです。
.claude/settings.jsonは CLAUDE.md と違って親から継承されない(仕様)。 ここを混同すると権限設定が効かなくなります。
各ツールは何を、どの順で読むか
同期方式を選ぶ前に、読み込みの仕様を押さえます。ここは推測を入れず、両方の公式ドキュメント(2026-09-14 閲覧)から引きます。
表の「連結順」を見ると分かるとおり、両者ともルートから作業ディレクトリへ向かって連結し、近い側が後に来る設計です。ここは揃っています。違うのはファイル名と、Claude Code だけがインポート構文を持つ点です。同期方式の選択は、事実上この2点で決まります。もう1つの違いである「作業ディレクトリより下の扱い」は、同期方式ではなく配置の判断に効くので、後半のモノレポの節で実測します。
方式1: @AGENTS.md インポート(実測: 動いた)
Claude Code の公式ドキュメントが第一候補として挙げている方法です。AGENTS.md を正本にし、CLAUDE.md は参照と固有追記だけにします。
@AGENTS.md
## Claude Code
- `src/billing/` の変更は plan mode で進める実際に一時ディレクトリで試しました。AGENTS.md に MARKER_AGENTS=one、CLAUDE.md の追記部分に MARKER_CLAUDE_ONLY=two という目印行を置き、ツールを使わずに「読めている MARKER 行を列挙して」と claude -p に頼みます。
printf '# Shared\nMARKER_AGENTS=one\n- test: npm test\n' > AGENTS.mdprintf '@AGENTS.md\n\n## Claude Code\nMARKER_CLAUDE_ONLY=two\n' > CLAUDE.md
claude -p "Without using any tools, list every line containing MARKER_ that appears in your instructions/memory files. Output only those lines." \ --output-format text --setting-sources projectMARKER_AGENTS=oneMARKER_CLAUDE_ONLY=two両方の行が返りました。--setting-sources project を付けているのは、私の ~/.claude/CLAUDE.md が混ざらないようにするためです。
インポートの細則で実務に効くのは3つです。いずれも公式ドキュメントの記述です。
- 相対パスはインポートを書いたファイルの場所基準で解決される(作業ディレクトリ基準ではない)
- コードスパンやコードブロックの中にある
@pathはインポートされない。パスを文章として言及したいときはバッククォートで囲む - 作業ディレクトリの外を指すインポート(
@~/...など)は初回に承認ダイアログが出る
逆方向、つまり Codex に CLAUDE.md を読ませる手段としては、~/.codex/config.toml の project_doc_fallback_filenames があります。公式の説明は「AGENTS.md が無いときに試す追加のファイル名」です。
project_doc_fallback_filenames = ["CLAUDE.md"]ただしこれはAGENTS.md が存在しないディレクトリでしか効きません。両方置く運用とは相性が悪く、また私の環境では実測できていません。「CLAUDE.md しか無いリポジトリを Codex でも触りたい」という限定的な場面向けと考えてください。
方式2: シンボリックリンク(実測: Windows では失敗)
Claude 固有の追記が不要なら、公式ドキュメントは ln -s AGENTS.md CLAUDE.md も挙げています。macOS / Linux では成功時に何も出力されず、次のセッションで /context の Memory files に CLAUDE.md が載れば成功です。
問題は Windows です。公式ドキュメントにも「Windows でシンボリックリンクを作るには管理者権限か開発者モードが必要なので、代わりに @AGENTS.md インポートを使う」と書かれています。実際に非管理者の cmd で試すと、そのとおり失敗しました。
> mklink CLAUDE.md AGENTS.mdこの操作を実行するための十分な特権がありません。(Git Bash 経由で cmd を呼んだため出力は cp932 で化けており、上はメッセージを読み直したものです。)
さらに、この環境では git config --get core.symlinks が false でした。Windows 向け Git はリンクをテキストファイルとしてチェックアウトすることがあるので、仮に手元で作れても、クローンした別のマシンで「AGENTS.md」という1行だけの CLAUDE.md になっている事故が起きます。Windows の開発者が1人でもいるチームでは、シンボリックリンクは避けるのが安全です。
方式3: 生成スクリプト(実測: --check でズレを検知)
インポート構文が無いツールが混在する、あるいは「生成物であること」をファイル先頭に明示したい場合は、AGENTS.md から CLAUDE.md を生成する方が扱いやすくなります。Node.js だけで動く最小版です。
// scripts/sync-agents.mjs — AGENTS.md を正本にして CLAUDE.md を生成する (Node.js 18+)import { readFileSync, writeFileSync, existsSync } from 'node:fs';
const shared = readFileSync('AGENTS.md', 'utf8').trimEnd();const extra = existsSync('CLAUDE.extra.md') ? readFileSync('CLAUDE.extra.md', 'utf8').trimEnd() : '';const out = [ '<!-- GENERATED from AGENTS.md by scripts/sync-agents.mjs. Edit AGENTS.md / CLAUDE.extra.md instead. -->', shared, extra ? '\n' + extra : '', '',].join('\n');
if (process.argv.includes('--check')) { const current = existsSync('CLAUDE.md') ? readFileSync('CLAUDE.md', 'utf8') : ''; if (current !== out) { console.error('CLAUDE.md is out of sync. Run: node scripts/sync-agents.mjs'); process.exit(1); } console.log('CLAUDE.md is in sync');} else { writeFileSync('CLAUDE.md', out); console.log('CLAUDE.md regenerated');}Claude 固有の内容は CLAUDE.extra.md に分けます。実行結果です。
$ node sync-agents.mjsCLAUDE.md regenerated$ node sync-agents.mjs --checkCLAUDE.md is in sync
# AGENTS.md に1行足した直後$ node sync-agents.mjs --checkCLAUDE.md is out of sync. Run: node scripts/sync-agents.mjs(終了コード 1)--check を CI か pre-commit に置けば、「AGENTS.md だけ直して CLAUDE.md が古いまま」という状態でマージできなくなります。先頭の HTML コメントは、Claude Code がコンテキストへ流す前に取り除くと公式ドキュメントにあるので、トークンは消費しません。
もう1つ、AGENTS.md 側に「CLAUDE.md は生成物。直したいときは AGENTS.md か CLAUDE.extra.md を編集して node scripts/sync-agents.mjs を実行する」と1行書いておくと、エージェント自身が CLAUDE.md を直接編集してズレを作る事故を減らせます。エージェントに渡す指示は、エージェントが読むファイルに書くのが一番確実です。
どれを選ぶか
判断の軸は「Windows の開発者がいるか」と「ツールが何種類か」です。
- Claude Code と Codex の2つだけ、Windows あり →
@AGENTS.mdインポート。今日から使えます。 - Claude Code と Codex の2つだけ、Unix 系のみ、固有追記なし → シンボリックリンクでも可。ただし後から追記したくなったらインポートに切り替えます。
- Cursor / Gemini CLI など3種以上が混在 → 生成スクリプト。各ツール向けの出力を1つの正本から作り、
--checkを CI に入れます。
3番目の場合、各ツール向けの雛形をゼロから書くのは手間です。AI設定ファイル変換ツール に既存の AGENTS.md や CLAUDE.md を貼ると、共通ルールを抽出して各形式のテンプレートを生成し、MCP や権限など移植できない項目は注釈で分けて出します。生成スクリプトの初期値を作る用途に使えます。
モノレポでネストしたときの読み込み
モノレポでは、指示ファイルが階層ごとに複数できます。Claude Code で実測した結果は**「上位は起動時に全部、下位はそのディレクトリのファイルを読んだ時に追加」**でした。連結の向きはルート側が先、作業ディレクトリ側が後で、Codex の公式仕様も同じ向きです。この2点を押さえると、配置はほぼ機械的に決まります。
実測: 3階層の CLAUDE.md をどう読むか
一時ディレクトリに Git リポジトリを作り、各階層の CLAUDE.md に目印行を置きました。AGENTS.md も同じ階層に置いていますが、Claude Code は AGENTS.md を読まないので、今回の観測対象は CLAUDE.md だけです。
mono/ (git root)├── CLAUDE.md MARKER_ROOT_CLAUDE=alpha├── AGENTS.md MARKER_ROOT_AGENTS=alpha-a└── packages/ ├── api/ │ └── CLAUDE.md MARKER_API_CLAUDE=delta └── web/ ├── CLAUDE.md MARKER_WEB_CLAUDE=beta ├── AGENTS.md MARKER_WEB_AGENTS=beta-a └── src/ ├── CLAUDE.md MARKER_SRC_CLAUDE=gamma ├── AGENTS.md MARKER_SRC_AGENTS=gamma-a └── index.tsプロンプトは方式1と同じく「ツールを使わずに、指示ファイルに含まれる MARKER_ の行だけを列挙して」で、--setting-sources project も付けています。4パターン走らせました。
# A: packages/web で起動、ファイルは読まないcd packages/webclaude -p "Without using any tools, list every line containing MARKER_ that appears in your instructions/memory files. Output only those lines." \ --output-format text --setting-sources project
# B: 同じ場所で、先に src/index.ts を Read させてから列挙claude -p "First read the file src/index.ts with the Read tool. Then list every line containing MARKER_ ..." \ --output-format text --setting-sources project --allowedTools Read
# C: ルートで起動、ファイルは読まない# D: ルートで起動、先に packages/web/src/index.ts を Read結果です。
A packages/web 起動 / 読まない MARKER_ROOT_CLAUDE=alpha MARKER_WEB_CLAUDE=beta
B packages/web 起動 / src/index.ts MARKER_ROOT_CLAUDE=alpha を Read した後 MARKER_WEB_CLAUDE=beta MARKER_SRC_CLAUDE=gamma
C ルート起動 / 読まない MARKER_ROOT_CLAUDE=alpha
D ルート起動 / packages/web/src/ MARKER_ROOT_CLAUDE=alpha index.ts を Read した後 MARKER_WEB_CLAUDE=beta MARKER_SRC_CLAUDE=gamma4つの結果から読み取れることを整理します。
- A: 上位(ルート)と起動ディレクトリ(web)は最初から載る。兄弟の
apiと下位のsrcは載らない。公式ドキュメントの「作業ディレクトリとその上位は起動時に読み込む」「サブディレクトリはそこにあるファイルを読んだ時に含める」と一致します。 - B:
src/index.tsを1回 Read しただけでsrc/CLAUDE.mdが追加された。 - C: ルートで起動すると、最初はルートの1枚だけ。
packages/*/CLAUDE.mdはどれも載らない。 - D: 深い階層のファイルを1つ読むと、経路上の web と末端の src が両方追加された。途中の階層が飛ばされることはありませんでした。
出力順も注目点です。どのパターンでも、ルート → web → src の順で列挙されました。公式ドキュメントは「ファイルシステムのルートから作業ディレクトリへ向かう順で連結され、起動場所に近い指示が最後に読まれる」としており、観測と合っています。
ただし、「後に来る」は「上書き」ではなく「後に読まれる」という意味です。 Claude Code の公式ドキュメントは、複数の CLAUDE.md を「上書きするのではなく連結する」と書いています。近い階層が後に来るのは事実ですが、矛盾する2つの指示があった場合に近い方が必ず勝つ保証はなく、「Claude が任意に片方を選ぶことがある」と明記されています。ルートと下位で矛盾する規約を書かないのが前提で、優先順位に頼る設計にはしないでください。
Codex の探索ルール(公式仕様)
Codex は実測できていないので、公式ドキュメントの記述の整理です。表のとおり、プロジェクトルート(通常 Git ルート)から作業ディレクトリまで下りながら、各ディレクトリで AGENTS.override.md → AGENTS.md → project_doc_fallback_filenames の順に候補を見ます。見つけたファイルはルート側から順に空行で連結され、「作業ディレクトリに近いファイルは後に来るので、先の指示を上書きする」とされています。合計は project_doc_max_bytes(既定 32 KiB)までで、上限に達したらそれ以上は足しません。
Claude Code との一番大きな違いは、作業ディレクトリより下は見ないことです。Codex は「ルートから作業ディレクトリまで」で探索が終わります。Claude Code のように「読んだファイルの階層の CLAUDE.md を後から足す」記述は、Codex のドキュメントにはありません。
配置の指針
公式の「monorepo or large codebase」ガイドは、2層構成を基本として示しています。
monorepo/ CLAUDE.md # 全パッケージ共通(コミット規約、触ってはいけないパス) packages/ api/ CLAUDE.md # api 固有(.env の準備、クエリビルダの指定) .claude/skills/ web/ CLAUDE.md # web 固有 shared/ CLAUDE.mdCodex 向けの AGENTS.md も同じ階層に同じ内容で置けば、探索ルールが同じ向きなので挙動が揃います。ここに実測結果を重ねると、運用は次のように決まります。
どこで起動するか。 公式ガイドの表では、ルート起動は「全ファイルにアクセスでき、CLAUDE.md はルートだけ起動時に読み、サブディレクトリは読んだ時」、サブディレクトリ起動は「そのサブツリーだけアクセスでき、そのディレクトリと上位の CLAUDE.md を起動時に読む」です。実測 C・D がそのままこれでした。1パッケージの作業なら、そのパッケージで起動する方が最初から固有規約が効きます。
下位の規約を確実に効かせたいとき。 実測 B・D のとおり、下位の CLAUDE.md は「そこのファイルを読んだ後」でないと載りません。エージェントが最初の一手でそのディレクトリのファイルを読むとは限らないので、「src/db/ を触る前に必ず守ること」のような規約は、ルートの .claude/rules/ に paths: 付きで置く方が確実です。公式ドキュメントは「パス条件付きルールは一致するファイルを読んだ時に発火する」としており、発火条件は同じですが、ルートに集約されるぶん見落としが減ります。
---paths: - "packages/api/src/db/**"---# DB 層のルール- マージ済みマイグレーションは編集しない。新しいマイグレーションを追加する他チームのパッケージを除外する。 ルート起動で作業していると、読んだ先の CLAUDE.md がどんどん足されます(実測 D)。関係ないパッケージの規約が混ざるのを防ぐには claudeMdExcludes です。
{ "claudeMdExcludes": [ "**/packages/web/**" ]}個人の都合なら .claude/settings.local.json、チーム共通なら .claude/settings.json に置きます。配列は設定レイヤー間でマージされ、管理ポリシーの CLAUDE.md だけは除外できません。
設定ファイルは継承されない
CLAUDE.md と同じ感覚で .claude/settings.json を扱うと事故が起きます。公式ガイドは「.claude/settings.json の項目は、CLAUDE.md のように親ディレクトリから継承されない」と明記しています。
具体的には、packages/api/.claude/settings.json に書いた permissions.deny や worktree.sparsePaths は、packages/api で起動したセッションにしか効きません。ルートで起動した場合はルートの .claude/settings.json だけが読まれます。さらに worktree を作ると作業ディレクトリが worktree のルートになるので、そこでも packages/api 側の設定は載りません。公式ガイドは、worktree でも効かせたい deny ルールをルートの .claude/settings.json に「二重に」置く例を示しています。
CLAUDE.md は「上位が効く」、settings は「起動場所のものだけ」。この非対称を覚えておくと、「ルールは効くのに権限設定が効かない」を切り分けられます。
兄弟パッケージを触るとき
packages/api で起動して packages/shared の型を直したい場合、アクセス権と CLAUDE.md の読み込みは別に扱われます(公式ガイド)。
additionalDirectories設定: アクセスは付くが、その先の CLAUDE.md・rules・skills は読まれない--add-dirフラグ //add-dir: skills は読まれる。CLAUDE.md と rules はCLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1を付けたときだけ
CLAUDE_CODE_ADDITIONAL_DIRECTORIES_CLAUDE_MD=1 claude --add-dir ../shared「shared の規約が効いていない」と感じたら、まずここを疑います。
移行の補助機能(Claude Code 側)
すでに AGENTS.md がある状態で Claude Code を導入する場合、公式ドキュメントに記載の補助が2つあります。いずれも今回は動作未検証で、記述は公式ドキュメントに基づきます。
/init:CLAUDE_CODE_NEW_INIT=1を設定して実行すると、AGENTS.md や.cursor/rules/、.github/copilot-instructions.mdなどを読み、生成する CLAUDE.md に取り込む/import:対応ツールの設定を Claude Code に取り込む。AGENTS.md などの指示ファイルは CLAUDE.md へ一度きりのコピーとして追記され、MCP サーバーやサブエージェントの設定も移す(v2.1.213 以降)
どちらも「コピー」なので、その後の同期は本記事の方式1か方式3で行うことになります。
まとめ
- Claude Code は CLAUDE.md、Codex は AGENTS.md しか読まない。連結順は両方とも「ルート側が先、作業ディレクトリ側が後」
@AGENTS.mdインポートは実測で AGENTS.md 側と CLAUDE.md 側の追記の両方が読まれた。Windows でも動く- Windows のシンボリックリンクは非管理者で失敗し、
core.symlinks=falseの環境ではクローン先で壊れる - 生成スクリプトは
--checkで同期漏れを検知できる。ツールが3種以上なら CI に組み込む - Codex の
project_doc_fallback_filenamesは「AGENTS.md が無いとき」だけの代替で、両方置く運用の同期手段にはならない(未実測) - モノレポでは、Claude Code は上位の CLAUDE.md を起動時に全部読み、下位はそのディレクトリのファイルを読んだ時に追加する(実測 A〜D)。Codex は作業ディレクトリより下の AGENTS.md を見る記述がなく、合計 32 KiB で打ち切る
- 配置は「ルートに共通、パッケージ直下に固有」の2層。下位の規約を確実に効かせたいなら
.claude/rules/のpaths:に寄せる .claude/settings.jsonは親から継承されない。CLAUDE.md との非対称が権限トラブルの典型原因
正本を1つに決め、もう一方は参照か生成物にする。同期方式そのものより、「どちらを直すか」を迷わない状態を作ることがこの話の本題です。「読まれているか分からない」ときは、セッション内で /context の Memory files を見るか、今回のように目印行を仕込んで claude -p に列挙させるのが、一番早い切り分けです。
関連記事
この記事の情報・検証メモ
- agents-md
- claude-code
- codex
- workflow
- troubleshooting
- 公開日
- 情報確認
- 参考リンク
- 4件
- 更新性
- 長く使える
仕様・料金・提供範囲が変わりやすいテーマは、公開日・更新日・情報確認日を分けて管理します。 導入前には必ず記事末尾の一次情報と公式ドキュメントで最新状況を確認してください。
一次情報・参考リンク
- Claude Code Docs: How Claude remembers your project (CLAUDE.md / imports / AGENTS.md) https://code.claude.com/docs/en/memory
- Claude Code Docs: Set up Claude Code in a monorepo or large codebase https://code.claude.com/docs/en/large-codebases
- Codex Docs: AGENTS.md (discovery order, override, size limit) https://learn.chatgpt.com/docs/agent-configuration/agents-md
- Codex Docs: Configuration reference (project_doc_fallback_filenames / project_doc_max_bytes) https://learn.chatgpt.com/docs/config-file/config-reference