共通ルールの原本を、~/.claude/rules/の1か所にまとめました。
Codex用のAGENTS.mdは、そこから自動で作る形です。
(~は、自分のホームディレクトリのことです)
🎥 この記事の内容は動画でも解説しています。
Claude CodeはCLAUDE.md、CodexはAGENTS.mdを読みます。
同じルールを2つのファイルに書いていた状態から、どう変えたか。
公式で確認した選び方、コピペで試せるスクリプト、自動で反映するフックを載せます。
きっかけは、手作業コピーでした
noteのコメントで、別の人が「AGENTS.mdを複数のAIに読ませている」と書いていました。
それを見て、自分の構成を見直しました。
自分の環境は、Claude Codeが~/.claude/CLAUDE.mdとrules/、Codexが~/.codex/AGENTS.mdを読む形です。
AGENTS.mdは、rulesの中身を手作業でコピーしたものでした。
片方だけ直すと、もう片方がズレます。
そういう構成でした。
見直しは、Claude Codeに頼みました。
まず、どの方法を使うか
どこに置くルールか。
あとは、AIごとに文面を変えたいかで決まります。
3通りです。
- リポジトリ(プロジェクト)単位なら、AGENTS.mdを原本にして、CLAUDE.mdに
@AGENTS.mdと1行書く。または、CLAUDE.mdを置かない - ユーザー全体で文面が同じなら、Claude Code側からCodexのファイルを
@で読む(公式に例あり。未検証) - ユーザー全体で、Codex向けに言い換えるなら、原本から生成する(自分はこれ)
公式の内容は、読み直して確認しています。
リポジトリ単位なら、公式のやり方で足ります
Claude Codeは、AGENTS.mdをそのまま読めます。
ただし、読むのはCLAUDE.mdが作業ディレクトリとその上に無いときだけです(v2.1.277以降)。
CLAUDE.mdがあると、そちらだけが読まれます。
CLAUDE.mdも置きたいときは、中で読み込みます。
公式ドキュメントにある書き方です。
@AGENTS.md
## Claude Code
(Claude Code専用の指示は、ここに書く)
Claude専用の指示が要らなければ、シンボリックリンクでも動きます。
ln -s AGENTS.md CLAUDE.md
ただし公式には、注意が2つ書かれています。
- Edit・Writeツールは、リンク越しの書き込みを断る。リンク先を直すよう案内される
- Windowsで使う人がいるなら、公式が推奨している
@AGENTS.mdの読み込みを使う
設定したら、次のセッションで/contextを実行して、CLAUDE.mdが「Memory files」に出ているか確認できます。
ユーザー全体のルールは、読み込み方を分けて考える
自分のPC全体に効かせたいルールは、リポジトリの外に置きます。
Claude Codeは~/.claude/CLAUDE.mdと~/.claude/rules/、Codexは~/.codex/AGENTS.mdです。
公式ドキュメントを読むと、こうなっていました。
- Claude CodeのAGENTS.md直読みは、作業ディレクトリとその上が対象。
~/.claude/は出てこない - Codexの説明に、Claude Codeの
@のような読み込み方法は載っていなかった - 探す順番は、グローバル、プロジェクトの順。合計32KiBの上限もある
Claude Code側から、Codexのファイルを@で読む方法はあります。
公式に、ホームディレクトリのファイルを読み込む例があるんです。
文面が同じでいいなら、これでも足りそうです。ただ、自分では試していません。
自分の環境では、共通のルール文に「Claude自身が」のようなClaude向けの書き方が混ざっていて、Codexに渡す版では言い換えたかった上に、Codex専用のルール(記事の品質チェックなど)も入れたかったので、rulesから生成する形にしました。
rulesから生成する形にした
原本は~/.claude/rules/に置いて、Codex用の~/.codex/AGENTS.mdはスクリプトで作ります。
作ったのは、Claude Codeです。
自分は、頼んで確認しました。
- 原本:
~/.claude/rules/の共通ルール5本 - Codex専用の部分と冒頭の説明は、別のファイルに分ける
- スクリプトが、これらをつないでAGENTS.mdを書き出す
- Claude向けの言い回し(「Claude自身が」など)は、Codex向けに置き換える
置き換える言葉が原本から消えたときは、警告が出るようにしました。
原本の文を直して、置き換えが空振りしても気づけるようにするためです。
Claude Codeには、次の3点を確認してもらいました。
- 生成したファイルは、元のAGENTS.mdと、冒頭の説明1段落以外が完全に一致した
- サイズは24,554バイトで、32KiB(32,768バイト)に収まった
- Codexに質問して、新しいヘッダーの説明と、言い換えた文を正しく答えられた
どれも、問題ありませんでした。
ルールを連結する最小版のスクリプト
自分の運用版は、共通5本の指定、Codex専用ファイルの結合、言い換え、警告が入っていて長いです。
ここには、最小版を載せます。~/.claude/rules/の.mdを全部つないで、~/.codex/AGENTS.mdに書き出すだけです。
Python 3が使えれば動きます。
先に、mkdir -p ~/.codex/agents-srcで保存先のフォルダを作っておきます。
すでに~/.codex/AGENTS.mdがある人は、先にバックアップを取ってください。
上書きされます。.mdが1つもないときは、何も書き込みません。
#!/usr/bin/env python3
"""~/.claude/rules/*.md を束ねて ~/.codex/AGENTS.md を生成する(原本は rules 側)。
python3 build.py 生成して書き込む
python3 build.py --check 今のAGENTS.mdとズレていれば終了コード1
"""
import re
import sys
from pathlib import Path
HOME = Path.home()
RULES = sorted((HOME / ".claude/rules").glob("*.md"))
OUT = HOME / ".codex/AGENTS.md"
HEADER = "<!-- 自動生成。直接編集しない。原本は ~/.claude/rules/ -->"
def shift_headings(text: str) -> str:
"""見出しを1段下げる(コードブロックの中は触らない)。"""
out, fence = [], False
for line in text.split("n"):
if line.startswith("```"):
fence = not fence
if not fence and re.match(r"^#{1,5} ", line):
line = "#" + line
out.append(line)
return "n".join(out)
def build() -> str:
body = "nn---nn".join(shift_headings(p.read_text(encoding="utf-8").strip()) for p in RULES)
return f"{HEADER}nn{body}n"
if __name__ == "__main__":
if not RULES:
sys.exit("~/.claude/rules/ に .md がありません。何も書き込みません")
text = build()
size = len(text.encode("utf-8"))
if size > 32 * 1024:
print(f"[警告] {size} bytes: Codexの標準上限(32KiB)を超えています")
if "--check" in sys.argv:
current = OUT.read_text(encoding="utf-8") if OUT.exists() else ""
print("ズレなし" if current == text else "ズレあり")
sys.exit(0 if current == text else 1)
OUT.parent.mkdir(parents=True, exist_ok=True)
OUT.write_text(text, encoding="utf-8")
print(f"生成しました: {OUT} ({size} bytes)")
~/.codex/agents-src/build.pyとして保存して、python3 ~/.codex/agents-src/build.pyで実行します。
この最小版には、Codex専用ルールの追加と言い換えは入っていません。
自分の運用版では、workflow.mdだけを対象に言い換えています。
言い換えたい言葉があれば、build()の中で、つなぐ前にreplace()を足してください。
テスト用のフォルダで、書き出しとズレの検出、.mdが0件のときの停止が動くことを確かめてあります。
rulesを直したら、自動で作り直すフック
原本を直すたびに、スクリプトを手で実行するのは忘れそうです。
Claude Codeの「フック」で、自動にしました。
フックは、特定の操作の前後に、決めたコマンドを動かす設定です。
ここでは、ファイルを編集・作成した直後(PostToolUse)に、動かします。
~/.claude/settings.jsonに、次のhooksを足します。
すでにhooksがある人は、既存の項目を残したまま、PostToolUseの配列に追加してください。
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "bash ~/.codex/agents-src/hook_rebuild.sh",
"timeout": 30
}
]
}
]
}
}
呼ばれるスクリプトは、~/.codex/agents-src/hook_rebuild.shとして保存します(jqが必要です)。~/.claude/rules/の.mdが変わったときだけ、生成を動かします。
結果は、Claude Codeの画面に出ます。
32KiBを超えたときの警告も、ここです。
#!/bin/bash
# Claude CodeのPostToolUseフックから呼ばれる。~/.claude/rules/*.md が変わったときだけ再生成する。
f=$(jq -r '.tool_input.file_path // empty' 2>/dev/null)
case "$f" in
"$HOME"/.claude/rules/*.md)
out=$(python3 "$HOME/.codex/agents-src/build.py" 2>&1); rc=$?
msg=$(printf '%s' "$out" | tail -2 | tr 'n' ' ' | sed 's/"/\"/g')
if [ $rc -eq 0 ]; then
echo "{"systemMessage":"Codex用のAGENTS.mdを再生成しました: $msg"}"
else
echo "{"systemMessage":"AGENTS.mdの再生成に失敗しました: $msg"}"
fi
;;
esac
exit 0
これもテスト用のフォルダで確かめてあります。
rules内のファイルを直すと再生成され、関係ないファイルでは何も起きませんでした。
狙いどおりです。
実環境での確認も、Claude Codeに頼みました。
rulesの1ファイルに一時的に1行足して、AGENTS.mdに反映されるのを確認してから、元に戻してもらっています。
ハマったところ
フックは、Claude CodeのEdit・Writeで直したときしか動きません。
ターミナルのsedのようなBashで直したときは、動かないんです。
フックを通らないので。
そのときは、手でbuild.pyを実行します。
ズレていないかは、build.py --checkで確かめられます。
もう1つは、生成したAGENTS.mdを直接直さないことです。
次の生成で消えます。
冒頭に「自動生成。直接編集しない」と書いて、Codex側にも伝えました。
32KiBの上限もあります。
Codexの標準の上限は、プロジェクトのAGENTS.mdも含めた合計です。
生成したファイルは24,554バイトでした。
プロジェクトにもAGENTS.mdを置く人は、その分も足して見ます。
同じことをやるときの確認順
5つです。
- 置く場所を決める。リポジトリ単位なら
@AGENTS.md。ユーザー全体なら、文面を変えるかで分ける - Claude Codeで
/contextを実行して、「Memory files」に意図したルールのファイルが出ているか確認する - Codexに、新しく足したルールを質問して、答えられるか確かめる
- 生成方式なら、原本を直したあとに
build.py --checkでズレを確認する - 生成したファイルのサイズを見る。プロジェクトのAGENTS.mdも含めた合計が、32KiBを超えていないか確かめる
原本は1か所です。
共通ルールを直す場所は、~/.claude/rules/だけです。
Edit・Write以外で直したときは、手でbuild.pyを実行する必要があります。
参考(公式ドキュメント)
- Claude Code: How Claude remembers your project(CLAUDE.mdとAGENTS.mdの扱い、
@の読み込み) - Codex: AGENTS.md(探す順番と32KiBの上限)