0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AGENTS.md と CLAUDE.md は解決規則が逆 — symlink する前に確認すること

0
Posted at

この記事は Zenn に投稿したもの の再掲です。内容は同じで、更新も両方に反映します。

AGENTS.md を置いているリポジトリで Claude Code も使いたい。
検索すると ln -s AGENTS.md CLAUDE.md が出てきて、実際これは公式が案内している手順です。

ただし、この1行で繋がるのはルートの1ファイルだけです。
そして繋いだ先の Claude Code は、AGENTS.md とは逆の規則でファイルを解決します。

モノレポで nested な AGENTS.md を使っている場合、ここが実務的な落とし穴になります。

3行で

  • AGENTS.md は「最も近い1つが勝つ」、CLAUDE.md は「見つかった全部を連結する」。上書きと累積で逆
  • 公式の接続手順は @AGENTS.md import か symlink。どちらもルートの1ファイルしか繋がらない
  • サブディレクトリの AGENTS.md に規約を置いているなら、Claude Code 側には別途 CLAUDE.md.claude/rules/ を用意する必要がある

以下、すべて公式ドキュメントの記述に基づきます(確認日: 2026-08-18)。
ツールの挙動は変わるので、読んだ時点で一次情報を当たってください。

AGENTS.md の現在地

agents.md は、コーディングエージェント向けの指示をツール非依存の1ファイルに置くための取り決めです。公式サイトは 「60k を超えるオープンソースプロジェクトで使われている」 と書いています。

対応を表明しているツールは Codex / Jules / Cursor / Copilot coding agent / Gemini CLI / Devin / Windsurf / Zed / Aider / Junie / Warp / VS Code など20以上。

このリストに Claude Code は入っていません。

Claude Code 側の公式見解

公式ドキュメントは明示的です。

Claude Code reads CLAUDE.md, not AGENTS.md.

そのうえで接続方法を2つ案内しています。

1. import する

CLAUDE.md
@AGENTS.md

## Claude Code

Use plan mode for changes under `src/billing/`.

@ 記法で AGENTS.md を展開し、その下に Claude Code 固有の指示を足せます。

2. symlink する

ln -s AGENTS.md CLAUDE.md

Claude 固有の追記が要らないならこちらで足ります。
ただし Windows では symlink の作成に管理者権限か開発者モードが必要なので、その環境では import 方式を使ってください。

繋がったかどうかは、セッション内で /context を実行して Memory files の一覧に出るかで確認できます。

ここまでは「解決済みの問題」に見えます。実際、単一ディレクトリのリポジトリならこれで終わりです。

本題: 解決規則が逆向き

問題は、複数の指示ファイルが存在するときです。

agents.md の規定はこうです。

Agents automatically read the nearest file in the directory tree, so the closest one takes precedence.

最も近いものが優先する。 つまり上書きモデルです。
公式サイトはモノレポでの nested 利用を推奨しており、その例として OpenAI 本体のリポジトリが AGENTS.md を88個持っていることを挙げています。

対して Claude Code はこうです。

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

上書きせず、全部を連結する。 累積モデルです。

順序まで規定されています。

content is ordered from the filesystem root down to your working directory

ルートから作業ディレクトリに向かって並び、近いものほど後ろに来ます。同じ階層では CLAUDE.local.mdCLAUDE.md の後ろに追加されます。

AGENTS.md Claude Code の CLAUDE.md
探索 ディレクトリツリーを遡る ディレクトリツリーを遡る
複数見つかったら 最も近い1つが勝つ 全部を連結する
順序 (1つしか使わない) root → cwd。近いものが後
同階層のローカル版 規定なし CLAUDE.local.md が後
サブディレクトリ側 同じ規則で最も近いものが勝つ 起動時ではなく、そのディレクトリのファイルを読んだ時点で読み込む

「同じ内容を読ませている」つもりでも、規約の効き方が変わります。

モノレポで何が起きるか

こういう構成を考えます。

repo/
├── AGENTS.md                    # 全体の規約
├── packages/
│   ├── api/
│   │   └── AGENTS.md            # API固有の規約
│   └── web/
│       └── AGENTS.md            # フロント固有の規約

AGENTS.md 対応ツールでは、packages/api/ を触るとき packages/api/AGENTS.md が効きます。設計どおりです。

ここでルートに symlink を張ります。

ln -s AGENTS.md CLAUDE.md

Claude Code から見えるのは repo/CLAUDE.md(= ルートの AGENTS.md)だけです。
packages/api/AGENTS.md は、Claude Code にとって存在しないファイルです。ファイル名が違うので探索対象に入りません。

@AGENTS.md import 方式でも同じです。import は書いたパスを展開するだけで、ツリーを走査してくれるわけではありません。

つまり、モノレポで nested AGENTS.md を使っているほど、symlink 1本で繋いだときの欠落が大きくなります。
しかもエラーは出ません。ルートの規約だけが効いた状態で、静かに動きます。

対処

Claude Code 側では、サブディレクトリの規約を2つのどちらかで持たせます。

(a) サブディレクトリに CLAUDE.md を置く

ln -s AGENTS.md packages/api/CLAUDE.md
ln -s AGENTS.md packages/web/CLAUDE.md

サブディレクトリの CLAUDE.md は起動時ではなく、Claude がそのディレクトリのファイルを読んだ時点で読み込まれます。必要なときだけコンテキストに入るので、この点は素直です。

(b) .claude/rules/paths: 付きで書く

.claude/rules/api.md
---
paths:
  - "packages/api/**/*.ts"
---

# API の規約

- すべてのエンドポイントで入力検証を行う
- エラーレスポンスは共通形式を使う

ディレクトリ単位ではなくファイルパターン単位で切れるので、packages/api/**/*.ts だけに効かせるといった指定ができます。層の切り方としてはこちらのほうが正確です。

どちらを選んでも、AGENTS.md とは別管理になります。 symlink 1本で終わる話ではなくなる、という点は最初に見積もっておいたほうがいいです。

「上書きされない」ことの副作用

もう一つ、移行時に効いてくる違いがあります。

AGENTS.md 前提で書かれた規約は、下位が上位を上書きすることを暗黙に想定していることがあります。

# ルートの AGENTS.md
- 新規コードは TypeScript で書く

# packages/legacy/AGENTS.md
- このパッケージは JavaScript のまま維持する。TypeScript 化しない

AGENTS.md の規則では、packages/legacy/ を触るとき下位だけが効くので、矛盾は起きません。

Claude Code では両方が同時にコンテキストに入ります。 そして公式はこう書いています。

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

矛盾したら、どちらが選ばれるかは決まりません。
AGENTS.md 側で「上書きされる前提」で書いていた規約は、Claude Code に持ってくる時点で矛盾しない書き方に直す必要があります。

上の例なら、ルート側をこう書き換えます。

- 新規コードは TypeScript で書く(`packages/legacy/` を除く)

地味ですが、nested を多用しているリポジトリほど書き換え箇所が増えます。

効いているかを確認する手段

「書いてある」と「効いている」は別です。確認手段は3つあります。

/context — セッション内で実行すると Memory files に読み込まれたファイルが並びます。ここに出ていないファイルは、Claude から見えていません。まずここです。

InstructionsLoaded フック — どのファイルが、いつ、なぜ読み込まれたかをログに出せます。paths: 付きルールや遅延読み込みされるサブディレクトリのファイルを追うときはこちらが確実です。

claudeMdExcludes — 逆に、モノレポで他チームの CLAUDE.md が拾われてしまう場合に、パスやグロブで除外できます。

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

コンパクションでもう一段ずれる

長いセッションでは、さらに差が出ます。公式の記述です。

Project-root CLAUDE.md survives compaction: after /compact, Claude re-reads it from disk and re-injects it into the session. Nested CLAUDE.md files in subdirectories and rules with paths: frontmatter are not re-injected automatically.

ルートの CLAUDE.md は再注入されるが、サブディレクトリのものと paths: 付きルールは再注入されない。
そのディレクトリのファイルを次に読んだとき、あるいはパターンに合うファイルに触れたときに、初めて戻ります。

上の対処 (a)(b) はどちらもこの影響を受けます。
**長いセッションの後半で「サブディレクトリの規約だけ効かなくなる」**という現象は、これが原因のことがあります。

対策は単純で、判断を要する作業はセッションを切ることです。作業の途中で「だんだん言うことを聞かなくなった」と感じたら、まず /context を見てください。

移行するときの最小手順

  1. AGENTS.md がルートに1つだけなら、symlink か @AGENTS.md import で終わり。/context で確認する
  2. nested な AGENTS.md があるなら、それを列挙するfind . -name AGENTS.md)。ここで漏れた分がそのまま欠落になる
  3. 各 nested を .claude/rules/paths: 付きルールに移すか、同階層に CLAUDE.md を置く
  4. 「下位が上書きする前提」で書かれた行を探し、矛盾しない書き方に直す
  5. 長いセッションで挙動が変わったら、/compact の再注入対象を疑う

補足: 自動で取り込む手段

Claude Code v2.1.213 以降には /import があり、対応ツールの設定を取り込めます。AGENTS.md などの指示ファイルを対応する CLAUDE.md1回だけコピーし、MCP サーバー・コマンド・サブエージェント・スキルも引き継ぎます。

/init も、CLAUDE_CODE_NEW_INIT=1 を設定すると AGENTS.md / .devin/rules/ / .windsurf/rules/ / .clinerules を読んで生成に反映します(デフォルトでも .cursor/rules/.github/copilot-instructions.md は読みます)。

ただしどちらも1回きりのコピーです。継続的な同期ではないので、AGENTS.md を更新したら反映は自分で行う必要があります。ここを継続同期だと思って運用すると、時間とともにズレていきます。

まとめ

  • AGENTS.md(最も近い1つが勝つ)と CLAUDE.md(全部を連結する)は、解決規則が逆
  • 公式の接続手順はルートの1ファイルだけを繋ぐ。nested は別途対応が要る
  • 「下位が上書きする前提」の規約は、Claude Code では矛盾として残る
  • 読み込まれたかは /context、読み込まれた経緯は InstructionsLoaded フックで確認する

ファイル名を揃えることと、規約が効くことは別の問題です。


関連記事

指示ファイルを繋いだのに規約が守られない、という段階の話は別記事にまとめています。
AIエージェントが「知っているはず」を間違える理由 — コンテキスト設計の実務

層をどこで切るか、規約が効かなくなる4つのパターンの見分け方、構成パターン別の実例までまとめた本もあります。
AIコンテキスト設計ガイド ── 規約を配ったのに守られない理由(2,000円)

第3章「規約が効かなくなる4つのパターン」まで無料で読めます。
/compact の後もルートの CLAUDE.md は再注入されるが、サブディレクトリと paths: 付きは再注入されない ── 長いセッションで静かに落ちるのはどちらか、という章です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?