Claude CodeはAGENTS.mdを読まない—@importとsymlinkで繋ぐ

Claude CodeはAGENTS.mdを読まない—@importとsymlinkで繋ぐ | mohablog

Claude Code が読む指示ファイルは CLAUDE.mdAGENTS.md は読みません。AGENTS.md 対応を求める issue #6235 は 5,200 を超えるリアクションを集めたまま、2026年8月時点でも open のままです。

目次

AGENTS.md が読まれないことを確かめる

検証は Claude Code v2.1.228。空のリポジトリに AGENTS.md だけを置きます。

mkdir /tmp/agents-md-test && cd /tmp/agents-md-test && git init -q
cat > AGENTS.md <<'EOF'
# Test Project

## Build

このプロジェクトのビルドコマンドは `make zzz-alpha` です。
EOF

ツールを全部切って質問する

このまま質問すると、Claude が Read ツールで AGENTS.md を自力で開きます。それでは起動時に読み込まれたのか、後から探しに行ったのかが区別できない。--tools "" で組み込みツールを全て無効化すれば、最初からコンテキストにあった内容だけで答えます。

claude --tools "" -p "起動時に読み込まれた指示の中に、このプロジェクトのビルドコマンドの記載はありますか。あるならそのコマンドだけを答えてください。無ければ「記載なし」とだけ答えてください。"
記載なし

InstructionsLoaded フックで読み込みを記録する

応答だけでは間接的な証拠にしかなりません。公式ドキュメント “How Claude remembers your project” の “Troubleshoot memory issues” が案内している InstructionsLoaded フックを使うと、どのファイルがいつ読み込まれたかがそのまま取れます。

{
  "hooks": {
    "InstructionsLoaded": [
      {
        "matcher": "session_start",
        "hooks": [
          { "type": "command", "command": "cat >> /tmp/agents-md-test/loaded.log; echo '' >> /tmp/agents-md-test/loaded.log" }
        ]
      }
    ]
  }
}

このJSONを hook-settings.json として保存し、--settings で読ませます。

claude --tools "" --settings /tmp/agents-md-test/hook-settings.json -p "起動時に読み込まれた指示の中に、このプロジェクトのビルドコマンドの記載はありますか。"

loaded.log に落ちたのは1件だけでした。

{
  "session_id": "9aa4373c-0e93-41a4-b487-d3acd5441809",
  "transcript_path": "/Users/moha/.claude/projects/-private-tmp-agents-md-test/9aa4373c-0e93-41a4-b487-d3acd5441809.jsonl",
  "cwd": "/private/tmp/agents-md-test",
  "hook_event_name": "InstructionsLoaded",
  "file_path": "/Users/moha/.claude/CLAUDE.md",
  "memory_type": "User",
  "load_reason": "session_start"
}

発火したのは ~/.claude/CLAUDE.md の1件、memory_typeUser。個人設定のグローバル CLAUDE.md だけ。プロジェクト側のファイルは1つも報告されていません。file_pathmemory_type はドキュメントの入力スキーマ表に載っていないフィールドですが、実際のペイロードには含まれます。

両方置いても AGENTS.md は無視される

片方だけ置いた検証には、「CLAUDE.md が無いときだけフォールバックで読むのでは」という疑いが残ります。両方置いて、わざと違う値を書けば決着します。

printf '# Test\n\nビルドコマンドは `make zzz-alpha` です。\n' > AGENTS.md
printf '# Test\n\nビルドコマンドは `make yyy-beta` です。\n' > CLAUDE.md
claude --tools "" -p "起動時に読み込まれた指示にあるビルドコマンドを、コマンド名だけ答えてください。"
`make yyy-beta`

CLAUDE.md 側が返りました。AGENTS.md はフォールバックですらなく、同じディレクトリに存在しても参照されない。AGENTS.md にコミット規約を書いたリポジトリで Claude Code を回し、規約が毎回無視される理由を半日探したことがあります。原因はこれ。読み込まれたファイルの一覧は /contextMemory files でも確認できます。詳しくはClaude Code /contextの読み方を参照してください。

2つのファイルは誰が読むのか

AGENTS.md 側の定義は「コーディングエージェントを導くためのシンプルでオープンな形式」。README のエージェント版という位置づけで、60,000 を超える OSS リポジトリが採用し、24種類以上のツールが対応を表明しています。この一覧に Claude Code は入っていません。

CLAUDE.mdAGENTS.md
読むツールClaude CodeCodex / Copilot / Cursor / Zed / Devin など24種以上
置き場所./CLAUDE.md./.claude/CLAUDE.md~/.claude/CLAUDE.md、管理ポリシー配置リポジトリルートとサブディレクトリ
複数ファイルの扱い全て連結最も近いものが優先
インポート記法@path(最大4段)規定なし
パス限定ルール.claude/rules/paths フロントマター規定なし

標準化を待つ理由は Anthropic 側から示されています。CLAUDE.md が持つパス限定・at-mention・ネストといった機能を落とさずに標準へ寄せるのが難しく、仕様が落ち着いたら合流したい、という立場。issue #6235 が open のまま動かないのはそのためです。

@AGENTS.md でインポートする

公式ドキュメントの “AGENTS.md” セクションは、CLAUDE.md 側からインポートする書き方を示しています。

@AGENTS.md

## Claude Code

`src/billing/` 配下の変更は plan mode で進めてください。
`make zzz-alpha`

AGENTS.md の中身が読まれました。インポート行の下に Claude Code 固有の指示を足せるのがこの方式の利点。plan mode の運用や、Claude Code にしかない機能への指示はここに置きます。

フックのログにインポート先は出ない

同じ構成で InstructionsLoaded フックを仕掛けると、報告されるのは2件です。

User    | /Users/moha/.claude/CLAUDE.md      | session_start
Project | /private/tmp/agents-md-b/CLAUDE.md | session_start

AGENTS.md は独立したイベントになりません。インポートは CLAUDE.md の一部として展開されるため、フックから見れば CLAUDE.md が1つ読まれただけ。読み込みの検査をフックのログだけに頼ると、インポートが効いているかどうかは判別できません。

バッククォートで囲むと展開されない

公式の “Import additional files” にはこう書かれています。

Import parsing skips Markdown code spans and fenced code blocks.

コードスパンとコードブロックはインポート解析の対象外。つまり次の書き方では何も読み込まれません。

共通の指示は `@AGENTS.md` に書いてあります。
記載なし

説明のつもりでファイル名をバッククォートで囲むと、インポートが黙って消えます。パスに言及したいだけならこれが正しい書き方で、読み込ませたいなら裸で書く。バッククォートの有無だけで、読み込まれるかどうかが変わります。

相対パスの基準と4段の制限

相対パスはインポート元のファイルからの相対で解決されます。作業ディレクトリ基準ではありません。インポート先がさらに別ファイルをインポートする再帰は4段まで。

ホームディレクトリ配下など作業ディレクトリの外を指すインポートをプロジェクトの CLAUDE.md に書くと、初回に承認ダイアログが出ます。ここで断ると以後そのインポートは無効のまま、ダイアログも二度と出ません。他人がコミットしたファイルを勝手に読み込まないための仕組み。~/.claude/CLAUDE.md 側のインポートは自分で書いたものとして扱われ、ダイアログは出ません。

シンボリックリンクで済ませる

Claude Code 固有の追記が要らないなら、symlink の方が1行で終わります。

ln -s AGENTS.md CLAUDE.md

成功時は何も出力されません。同じ質問を投げると AGENTS.md の中身が返ります。

`make zzz-alpha`
観点@AGENTS.md インポートシンボリックリンク
Claude 固有の指示インポート行の下に足せる足せない
Windowsそのまま動く管理者権限か開発者モードが必要
git 上の見え方通常ファイルが2つmode 120000 のリンク1つ
チェック方法/context の Memory files/context の Memory files

symlink をコミットすると、git はリンク先のパス文字列を中身として持つ mode 120000 のエントリを作ります。symlink を再現できない環境で clone すると、AGENTS.md という1行だけが入った通常のテキストファイルが置かれる。Windows で core.symlinks が false のまま clone した場合がこれに当たります。その1行が CLAUDE.md の全内容になるため、Windows を含むチームではインポート方式に倒すのが安全です。

モノレポでは連結順がずれる

symlink とインポートのどちらを選ぶかとは別に、モノレポには置き場所の問題があります。AGENTS.md 標準の規定は「エージェントはディレクトリツリー上で最も近いファイルを読むので、一番近いものが優先される」。Claude Code の規定は違います。”How CLAUDE.md files load” にはこうあります。

All discovered files are concatenated into context rather than overriding each other.

見つかったファイルは上書きではなく全て連結されます。並び順はファイルシステムのルートから作業ディレクトリへ向かう方向で、起動位置に近いものが最後に来ます。

同じファイルでもツールごとに解釈が変わる

ルートとサブパッケージの両方に AGENTS.md を置いたモノレポで、それぞれに symlink を張ったとします。ルートに「このリポジトリでは pnpm を使う」、packages/api/ に「このパッケージは npm を使う」と書いてある場合。

  • Codex や Cursor: packages/api/AGENTS.md だけを読み、npm を使う
  • Claude Code: ルートと packages/api/ を両方連結し、pnpm と npm を同時に受け取る

後者について公式は明言しています。

If two rules contradict each other, Claude may pick one arbitrarily.

矛盾したルールが2つあれば、どちらが選ばれるかは保証されません。共有ファイルにするなら、上位ディレクトリの記述を下位が打ち消す前提で書かないこと。差分ではなく追加として書けば、連結されても壊れません。

サブディレクトリは起動時に読まれない

作業ディレクトリより下にある CLAUDE.md は、起動時ではなく Claude がそのディレクトリのファイルを読んだ時点で入ります。上位ディレクトリ側は起動時に全文が入る。同じディレクトリ内では CLAUDE.local.mdCLAUDE.md の後ろに付き、個人のメモが最後に読まれる並びになります。

/compact の後に再注入されるのはプロジェクトルートの CLAUDE.md だけで、ネストしたファイルや paths フロントマター付きのルールは対象外。圧縮を挟んだ途端に指示が効かなくなったら、まずここを疑います。

他チームのファイルを外す

巨大なモノレポでは、上位ディレクトリにある無関係な CLAUDE.md まで拾われます。claudeMdExcludes で除外できます。

{
  "claudeMdExcludes": [
    "**/monorepo/CLAUDE.md",
    "/home/user/monorepo/other-team/.claude/rules/**"
  ]
}

絶対パスに対する glob 判定。設定レイヤーは user / project / local / managed のどこでも指定でき、配列はレイヤーをまたいでマージされます。ただし管理ポリシーとして配置された CLAUDE.md は除外できません。

/import は AGENTS.md を見ていない

v2.1.213 以降には /import があります。他のコーディングエージェントの設定を Claude Code 側へ写すコマンド。公式の説明では、AGENTS.md のような指示ファイルを対応する CLAUDE.md へ一度だけ追記し、MCP サーバーやコマンド、サブエージェント、スキルも引き継ぐ、とされています。AGENTS.md を置いたリポジトリで実行しました。

No other AI coding agents detected (looked for: OpenAI Codex, Google Gemini CLI).

検出されませんでした。探しているのは OpenAI CodexGoogle Gemini CLI の設定であって、AGENTS.md 単体はスキャン対象外。.codex/config.toml を置いてから再実行すると応答が変わります。

OpenAI Codex の設定をスキャンした結果、インポート候補が 1 件見つかりました。

見つかったもの
- プロジェクトレベルの設定 1 件(このリポジトリの .codex/ ディレクトリ内)

ただしプロジェクトレベルの設定は、リポジトリへの書き込み権限を持つ誰でも
書き換えられるため、この場では一覧表示もインポートもされません
(--yes でも対象外です)。

検出はする、取り込みはしない。リポジトリに書き込める人なら誰でも中身を差し替えられる、という理由でプロジェクトスコープの設定は自動取り込みの対象外です。--yes を付けても変わりません。中身を見て判断するなら、ターミナルから claude import を実行してピッカーで1件ずつ選ぶ導線。

チームで共有した AGENTS.md を Claude Code に引き込む用途で /import は当てになりません。CLAUDE.md 側にインポート記法か symlink を置き、それをコミットするのが確実。CLAUDE.md 自体の運用設計はClaude Code memoryとは?CLAUDE.mdとの違いと運用設計の実例にまとめています。

まとめ

  • Claude Code v2.1.228 が読むのは CLAUDE.md のみ。AGENTS.md は同じディレクトリに置いても参照されない
  • 橋渡しは CLAUDE.md 先頭の @AGENTS.mdln -s AGENTS.md CLAUDE.md。Claude 固有の指示を足すならインポート、中身が完全に同じで Windows を考えなくてよいなら symlink
  • バッククォートで囲んだ @AGENTS.md は展開されない。コードスパンとコードブロックは解析対象外
  • 読み込みの確認は --tools "" での起動、/context の Memory files、InstructionsLoaded フック。フックにインポート先のファイルは出ない
  • モノレポでは AGENTS.md 標準の「最近接が優先」と Claude Code の「全て連結」がずれる。上位の記述を下位で打ち消す書き方は避ける
  • /import が探すのは Codex と Gemini CLI の設定。AGENTS.md 単体は検出されず、プロジェクトレベルの設定は取り込まれない
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!
目次