こんにちは、おうどんです🍜
Claude Code に、メモへ1行足してもらった。Codex にも、同じメモへ1行足してもらった
それで、メモは何行増えましたか
1行
2人に頼んで、1行ですか
(会話は説明用の架空の場面です)
AIエージェント(指示を受けて、ファイルを読む・書く・コマンドを動かすところまで自分で進める AI)を2つ使うと、こういうことが起きます。
片方の追記が、あとから書いたもう片方に消される。どちらもエラーは出さないし、どちらも「完了しました」と言う。
おうどんも、Claude Code と ChatGPT の Codex で、同じメモのフォルダを共有しています。ルールを書いたファイルも、Claude Code 用の CLAUDE.md と Codex 用の AGENTS.md に、同じ中身で置いています。
なので、まったく他人事ではありません。今日は、2つの AI に同じフォルダを触らせるときの、消えない書き方をまとめます。
厨房でいうと、仕込みメモを貼ったホワイトボードを、2人の板前が書き換える話です。
困るのは、2人とも「清書」が大好きなこと。
読者「字がきれいなのは、いいことでは」
字がきれいなのはいいんです。問題は、朝に自分のノートへ写したメモを清書して、ホワイトボードの上から貼り替えるところにあります。
今日のチェックリスト(初心者はここだけでも)
- AI には「ファイルを丸ごと書き直す」より「変えたい1か所だけ直す」を頼む
- 書く直前に、ファイルを読み直させる
- 2つの AI で共有するなら Git を使い、push を断られたら、pull してからやり直す(
--forceで押し込まない)
後から書いたほうが勝つ。朝に読んだ内容で丸ごと書くと、間の追記が消える
2人の板前の朝を、Python で再現します。
AI-A が 8:00 にメモを読み、8:05 に AI-B が1行足し、8:10 に AI-A が「朝に読んだ内容」を直して丸ごと書きます。
# t1_stale_rewrite.py 朝に読んだ内容で、ファイルを丸ごと書き戻すとどうなるか
from pathlib import Path
memo = Path("memo.md")
memo.write_text("# メモ\n- だしは昆布\n- 麺は茹で9分\n", encoding="utf-8")
# 8:00 AI-A が読む(ここで覚えた内容を、あとで使う)
a_snapshot = memo.read_text(encoding="utf-8")
# 8:05 AI-B が1行足す
memo.write_text(memo.read_text(encoding="utf-8") + "- ネギは九条ネギ\n", encoding="utf-8")
# 8:10 AI-A が、覚えている内容を直して丸ごと書く
memo.write_text(a_snapshot.replace("茹で9分", "茹で10分"), encoding="utf-8")
print("=== 丸ごと書き戻した結果 ===")
print(memo.read_text(encoding="utf-8"), end="")
python -X utf8 t1_stale_rewrite.py の出力です。
=== 丸ごと書き戻した結果 ===
# メモ
- だしは昆布
- 麺は茹で10分
(今回の検証環境:Windows の Python 3.13.1。時刻はコメントで、実際は上から順に一瞬で実行しています)
ネギが消えました。
AI-B は確かに書いた。AI-A も、直したいところ(9分→10分)はちゃんと直した。どちらも嘘はついていません。
AI-A に、悪気はないんだよね
悪気がないのが、いちばん困るタイプです。
AI-A の頭の中のメモには、ネギの行がそもそもない。ないものを消したつもりは、本人にはありません。
この形は、データベースの世界では lost update(更新の消失)と呼ばれます。2人が同じものを「読んで、変えて、書く」と、後から書いたほうが、先の人の変更ごと上書きしてしまう。
AIエージェントで起きやすいのは、読んでから書くまでが長いからです。人間なら数秒の「読んで、書く」の間に、AI は資料を調べたり、コードを試したり、考えたりします。その間に、もう1人が書く。
板前でいうと、朝ノートに写したメモを昼に清書して、ホワイトボードに貼り替えた。その間に同僚が書き足した「ネギは九条ネギ」は、新しい紙の下です。
読者「貼る前に、元の紙と見比べればいいのでは」
見比べるのは、人間なら5秒。AI に毎回やらせるなら、そもそも清書をやめるほうが早い。次の章です。
書く直前に読み直し、変えたい1か所だけ直す
直し方は、2つをセットにします。
- 書く直前に、ファイルを読み直す
- 丸ごと書かず、変えたい1か所だけを置き換える。置き換え元がちょうど1か所でなければ、止まる
# t2_partial_edit.py 書く直前に読み直し、変えたい1か所だけ置き換える
from pathlib import Path
def edit(path, old, new):
text = path.read_text(encoding="utf-8") # 書く直前に読み直す
count = text.count(old)
if count != 1:
raise ValueError(f"置き換え元が {count} か所あります: {old!r}")
path.write_text(text.replace(old, new), encoding="utf-8")
memo = Path("memo.md")
memo.write_text("# メモ\n- だしは昆布\n- 麺は茹で9分\n", encoding="utf-8")
# 8:05 AI-B が1行足す
memo.write_text(memo.read_text(encoding="utf-8") + "- ネギは九条ネギ\n", encoding="utf-8")
# 8:10 AI-A は、変えたい1か所だけ置き換える
edit(memo, "- 麺は茹で9分\n", "- 麺は茹で10分\n")
print("=== 1か所だけ置き換えた結果 ===")
print(memo.read_text(encoding="utf-8"), end="")
# 8:15 AI-B も同じ行を 11分 にしようとする。でも、もう 9分 の行はない
try:
edit(memo, "- 麺は茹で9分\n", "- 麺は茹で11分\n")
except ValueError as e:
print("AI-B の編集は止まった:", e)
=== 1か所だけ置き換えた結果 ===
# メモ
- だしは昆布
- 麺は茹で10分
- ネギは九条ネギ
AI-B の編集は止まった: 置き換え元が 0 か所あります: '- 麺は茹で9分\n'
(今回の検証環境:同じ。python -X utf8 t2_partial_edit.py で実行)
ネギが残りました。AI-A が置き換えたのは「麺は茹で9分」の1行だけなので、ほかの行は、書く直前のファイルの中身のままです。
そして、後半がこのコードの本命です。
AI-B も 8:15 に「9分を11分に」しようとした。でも、もう「9分」の行はない。edit は、置き換え元が 0 か所なら例外を出して止まります。2か所以上でも止まります(どこを直すつもりか、決められないため)。
止まっちゃったら、失敗じゃないですか
止まらないほうの失敗を、さっき見たでしょ。ネギが黙って消えるやつ
黙って消えるより、止まって知らせるほうが、ずっと直しやすい。AI-B は読み直して、「もう10分になっている。11分にしていいか確認しよう」と考え直せます。
清書をやめた板前は、赤ペンで1か所だけ直します。赤ペンの先に、直すつもりの文字がなければ、手が止まる。
読者「空振りしたら、その辺の空いているところに書けばいいのでは」
その辺に書いた「11分」が、「10分」と並んでホワイトボードに2つ。どっちで茹でればいいのか、麺のほうが聞きたいくらいです。
今日の下書きが、もうあったら上書きせずに止まる
新しくファイルを作るときにも、同じ事故があります。
2つの AI が「今日の下書き」を同じ名前で作ろうとすると、後から作ったほうが、先の下書きを上書きする。
おうどんが毎朝 Claude Code で回している記事のタスクは、その日の下書きがもうあれば、上書きせずに止まるようにしてあります。
Python なら、open() の "x" モードでこれが書けます。
# t4_exclusive.py 今日の下書きが、もうあったら上書きせずに止まる
import sys
from pathlib import Path
def save_draft(path, text, who):
try:
with open(path, "x", encoding="utf-8") as f: # x: ないときだけ作る
f.write(text)
print(f"{who}: 保存しました")
return 0
except FileExistsError:
print(f"{who}: もう下書きがあるので中止します(上書きしません)")
return 3
draft = Path("2026-11-03_draft.md")
if draft.exists():
draft.unlink()
r1 = save_draft(draft, "Claude の下書き\n", "Claude")
r2 = save_draft(draft, "Codex の下書き\n", "Codex")
print("中身:", draft.read_text(encoding="utf-8"), end="")
print("終了コードにするなら:", r1, r2)
Claude: 保存しました
Codex: もう下書きがあるので中止します(上書きしません)
中身: Claude の下書き
終了コードにするなら: 0 3
(今回の検証環境:同じ。python -X utf8 t4_exclusive.py で実行。3 は説明用に決めた番号で、決まりがあるわけではありません)
Python のドキュメントでは、"x" は「排他的に作る。ファイルがもうあれば失敗する」モード、"w" は「書き込み用に開き、先にファイルを空にする」モードです。
"w" は、開いた瞬間に中身を捨てます。
冷蔵庫を開けた瞬間に、中身を全部捨てる店員……
しかも、捨てたあとに自分の分だけ入れて、閉める
if path.exists(): で確かめてから "w" で開く書き方もありますが、確かめてから開くまでの間に、もう1人が作る余地が残ります。"x" なら、「なければ作る」を1回の open() で頼めます。
ただし、"x" が守ってくれるのは「作るとき」だけです。できたファイルを、あとからもう1人が丸ごと書き直すのは防げません。そこは前の章の「1か所だけ直す」の出番です。
読者「止まった日は、記事が1本も出ないのでは」
出ません。でも、2人で同じ丼に盛って、どっちの具か分からなくなるよりはいい。1杯は確実に残ります。
🔰 ここまで読めば今日から困らない
- 2つの AI が同じファイルを丸ごと書くと、後から書いたほうが勝ち、間の追記が消える。エラーは出ない
- 書く直前に読み直し、変えたい1か所だけ置き換える。置き換え元がなければ、止まって知らせる
- 新しく作るファイルは、もうあったら止まる作り方にする(Python なら
open()の"x")
3行なら、おうどんでも覚えられる
覚えるのは AI のほうです。おうどんは、AI に覚えさせる係。
AI への指示(CLAUDE.md・AGENTS.md など)に足すなら、たとえばこう書けます(説明用の例で、この文面で AI の動きを確かめたわけではありません)。
## 共有フォルダの編集
- 編集する直前に、そのファイルを読み直す。会話の最初に読んだ内容は古いことがある
- ファイル全体を書き直さない。変える箇所だけを置き換えるか、末尾に追記する
- 置き換えたい文が見つからない・2か所以上あるときは、推測で書かずに止まって報告する
- 自分が書いていない記述は、消さない・言い換えない
読者「4行目、人間の職場にも貼りたい」
どうぞ。厨房のホワイトボードの横あたりがおすすめです。
ここから先は中級者向け。2つの AI が本当に同時に動くときと、Git で共有するときの話です。
本当に同時に動くと、読み直しでも間に合わない。鍵ファイルで順番にする
書く直前に読み直しても、「読み直してから書くまで」の間はゼロになりません。2つの AI がほぼ同時に動くなら、その間にもう1人が書くことがあります。
2つのプロセスを本当に同時に動かして確かめます。Claude 役が読んで1秒考え、0.3秒遅れて Codex 役が読んで1秒考え、それぞれ「読んだ内容+自分の1行」を丸ごと書きます。lock を付けると、鍵ファイル(「今使っています」の札になるファイル)を作れた人だけが、読む・書くに進みます。
# t3_race.py 2つのプロセスが同時に「読む→考える→丸ごと書く」をする
# 使い方: python t3_race.py [nolock|lock]
import subprocess, sys, time
from pathlib import Path
MEMO = Path("race_memo.md")
LOCK = Path("race_memo.lock")
def worker(name, line, think, use_lock):
if use_lock:
while True:
try:
open(LOCK, "x").close() # 鍵ファイルを作れた人だけ進む
break
except FileExistsError:
print(f"{name}: 鍵がかかっているので待つ", flush=True)
time.sleep(0.2)
try:
text = MEMO.read_text(encoding="utf-8")
print(f"{name}: 読んだ({len(text.splitlines())}行)", flush=True)
time.sleep(think) # AI が考えている時間のつもり
MEMO.write_text(text + line + "\n", encoding="utf-8")
print(f"{name}: 書いた", flush=True)
finally:
if use_lock:
LOCK.unlink()
if __name__ == "__main__":
if len(sys.argv) > 1 and sys.argv[1] == "worker":
worker(sys.argv[2], sys.argv[3], float(sys.argv[4]), sys.argv[5] == "lock")
sys.exit(0)
mode = sys.argv[1] if len(sys.argv) > 1 else "nolock"
MEMO.write_text("# メモ\n", encoding="utf-8")
if LOCK.exists():
LOCK.unlink()
py = [sys.executable, "-X", "utf8", __file__, "worker"]
a = subprocess.Popen(py + ["Claude", "- Claude の追記", "1.0", mode])
time.sleep(0.3)
b = subprocess.Popen(py + ["Codex", "- Codex の追記", "1.0", mode])
a.wait(); b.wait()
print(f"=== 結果({mode}) ===")
print(MEMO.read_text(encoding="utf-8"), end="")
python -X utf8 t3_race.py nolock の出力です。
Claude: 読んだ(1行)
Codex: 読んだ(1行)
Claude: 書いた
Codex: 書いた
=== 結果(nolock) ===
# メモ
- Codex の追記
python -X utf8 t3_race.py lock の出力です。
Claude: 読んだ(1行)
Codex: 鍵がかかっているので待つ
Codex: 鍵がかかっているので待つ
Codex: 鍵がかかっているので待つ
Codex: 鍵がかかっているので待つ
Claude: 書いた
Codex: 読んだ(2行)
Codex: 書いた
=== 結果(lock) ===
# メモ
- Claude の追記
- Codex の追記
(今回の検証環境:同じ PC の同じフォルダで、2つの Python プロセスを動かしました。待つ回数は、タイミングで変わります)
鍵なしでは、2人とも「1行」のメモを読み、後から書いた Codex の分だけが残りました。1章と同じ形が、本当の同時実行でも起きています。
鍵ありでは、Codex は Claude が書き終わるまで待ち、2行になったメモを読んでから書いた。だから2行とも残っています。
Codex 役が「待つ」と4回言っているのは、0.2秒ごとに鍵を確かめているからです。
待っている間、ずっと独り言を言っている
板前でいうと、ホワイトボードの前に「使用中」の札を下げる仕組みです。札を下げられた人だけが、ペンを持てる。
便利ですが、前提が3つあります。
- 全員が同じ札を見ること。鍵ファイルは、守る約束をした人にしか効きません。鍵を確かめない AI や人がいれば、そのまま書けてしまう
- 札を下げた人が、必ず札を外すこと。上のコードは
finallyで外していますが、プロセスが強制終了されると外れないことがあります。残った鍵の扱いは、定期実行の完了判定の記事で触れています - 同じ場所の鍵ファイルが、両方から見えること。今回は同じ PC の同じフォルダでだけ試しました。片方の AI が別のマシンやクラウド上のコピーで作業しているなら、手元の鍵ファイルはそもそも見えません
読者「鍵を持ったまま、AI のほうが寝落ちしたら」
Codex は、律儀に待ち続けます。厨房の鍵を持ったまま店長が帰った翌朝と同じで、全員が店の前に並ぶことになります。
Gitで共有すると、消えずに止まる。ただし隣の行でもぶつかる
2つの AI が別々の場所(別のフォルダ、別のマシン)で作業するなら、鍵ファイルより Git が向いています。Git は、黙って上書きしません。代わりに、止まります。
確かめるスクリプトです。共有の置き場(bare リポジトリ)を作り、Claude 役と Codex 役が別々に clone して、先に Claude、あとから Codex が push します。直す行を変えて3通り試しました。
#!/bin/bash
# t5_git.sh 2つの AI が別々の clone から同じファイルを直して push する
W="$1"
export GIT_AUTHOR_DATE="2026-11-03T08:00:00+09:00" GIT_COMMITTER_DATE="2026-11-03T08:00:00+09:00"
g() { git -c user.name="$1" -c user.email="$1@example.com" -c init.defaultBranch=main -c core.autocrlf=false -c advice.skippedCherryPicks=false "${@:2}"; }
scenario() {
local title="$1" claude_sed="$2" codex_sed="$3" dir="$W/$4"
rm -rf "$dir"; mkdir -p "$dir"; cd "$dir" || exit 1
g setup init -q --bare shared.git
g setup clone -q shared.git claude 2>/dev/null
(cd claude && printf '# メモ\n- だしは昆布\n- 麺は茹で9分\n- 天ぷらはえび\n- 七味は少し\n- ネギは小口切り\n' > memo.md \
&& g setup add memo.md && g setup commit -q -m "first" && g setup push -q origin HEAD:main)
g setup clone -q shared.git codex
echo "=== $title ==="
(cd claude && sed -i "$claude_sed" memo.md && g Claude commit -qam "Claude" && g Claude push -q origin main && echo "Claude: push OK")
(cd codex && sed -i "$codex_sed" memo.md && g Codex commit -qam "Codex" \
&& { out=$(g Codex push -q origin main 2>&1); echo "Codex: push の終了コード=$?"; printf '%s\n' "$out" | grep rejected; })
(cd codex && g Codex pull -q --no-rebase origin main; echo "Codex: pull の終了コード=$?"; cat memo.md)
}
scenario "1. 離れた行を直す" 's/茹で9分/茹で10分/' 's/小口切り/斜め切り/' s1
scenario "2. 隣り合う行を直す" 's/えび/かしわ/' 's/少し/多め/' s2
scenario "3. 同じ行を直す" 's/だしは昆布/だしは昆布とかつお/' 's/だしは昆布/だしはいりこ/' s3
⚠️ 第1引数のフォルダの下(s1・s2・s3)を rm -rf で消してから作り直します。消えてもよい作業用のフォルダを渡してください。git -c で名前などをその場だけ指定しているので、ふだんの Git の設定は変えません。
bash t5_git.sh <作業用フォルダ> の出力です。
=== 1. 離れた行を直す ===
Claude: push OK
Codex: push の終了コード=1
! [rejected] main -> main (fetch first)
hint: Updates were rejected because the remote contains work that you do not
Auto-merging memo.md
Codex: pull の終了コード=0
# メモ
- だしは昆布
- 麺は茹で10分
- 天ぷらはえび
- 七味は少し
- ネギは斜め切り
=== 2. 隣り合う行を直す ===
Claude: push OK
Codex: push の終了コード=1
! [rejected] main -> main (fetch first)
hint: Updates were rejected because the remote contains work that you do not
Auto-merging memo.md
CONFLICT (content): Merge conflict in memo.md
Automatic merge failed; fix conflicts and then commit the result.
Codex: pull の終了コード=1
# メモ
- だしは昆布
- 麺は茹で9分
<<<<<<< HEAD
- 天ぷらはえび
- 七味は多め
=======
- 天ぷらはかしわ
- 七味は少し
>>>>>>> d53871a185100a73f5ae8ab579b1f8f18c63ed98
- ネギは小口切り
=== 3. 同じ行を直す ===
Claude: push OK
Codex: push の終了コード=1
! [rejected] main -> main (fetch first)
hint: Updates were rejected because the remote contains work that you do not
Auto-merging memo.md
CONFLICT (content): Merge conflict in memo.md
Automatic merge failed; fix conflicts and then commit the result.
Codex: pull の終了コード=1
# メモ
<<<<<<< HEAD
- だしはいりこ
=======
- だしは昆布とかつお
>>>>>>> e68105d5b15fb855fc6b76480358081382870cf0
- 麺は茹で9分
- 天ぷらはえび
- 七味は少し
- ネギは小口切り
(今回の検証環境:Git for Windows 2.45.1(git version 2.45.1.windows.1)の bash で実行)
3通りとも、まず Codex の push が断られています(終了コード 1)。
git push のドキュメントの「NOTE ABOUT FAST-FORWARDS」によると、ほかの人が先に push した上に、それを含まない自分の履歴を push すると、先の人の変更が失われる。だから git push は、既定ではこの更新(fast-forward にならない更新)を受け付けません。自分の変更も相手の変更も失いたくなければ、先に取り込んで(git pull か git pull --rebase)、両方を含む履歴を push し直す、という流れです。
1章の Python では黙って消えたネギが、Git では「断られる」に変わりました。
断られたら、--force で押し込めば通りますよね
通る。ホワイトボードの前に立っている同僚ごと、貼り替える技
同じドキュメントでも、--force はリモート(共有の置き場)のコミットを失わせうる、とされています。どうしても上書きが要る場面のために --force-with-lease(共有の置き場が、自分の知っている状態のままのときだけ上書きする)がありますが、AI に任せる作業で使う場面は、まずないと思います(おうどんの考えです)。
取り込んだあとは、3通りで結果が分かれました。
- 1. 離れた行:自動でまとまった(pull の終了コード 0)。麺もネギも、両方の直しが入っています
- 2. 隣り合う行:衝突した。天ぷらと七味、別々の行を直しただけなのに
- 3. 同じ行:衝突した。これは当然
git merge のドキュメントの「HOW CONFLICTS ARE PRESENTED」には、片方だけが変えた場所はそのまま結果に入り、両方が同じ場所(area)を変えたときは、Git がどちらかを勝手に選ばずに、<<<<<<<・=======・>>>>>>> で両方を残して解決を頼む、と書かれています。
今回の検証では、隣り合う2行の変更も、同じ場所の変更として衝突しました。別の行を直したから大丈夫、とは言い切れないわけです。
読者「隣の行を直しただけで、けんか扱い」
肩が触れただけで、けんか。厨房が狭いと、そういうことになります。
衝突したときの片付け方も、git merge のドキュメントにあります。
- やめる:
git merge --abortで、取り込む前に戻す - 直す:ファイルを正しい形に直して
git addし、git commit(またはgit merge --continue)
AI に任せるなら、「衝突したら、自分で片方を選ばずに止まって知らせる」と指示しておくのがおすすめです。<<<<<<< の行が残ったまま「解決しました」と commit されると、メモの中に矢印が住みつきます。AI がそれをメモの一部だと思って、清書を始めたら最悪です。
AIエージェントに共有フォルダを任せるときのチェックリスト
ここまでを、場面ごとにまとめます。
| 場面 | 起きること | 対処 |
|---|---|---|
| 朝に読んだ内容で、夕方に丸ごと書く | 間に入った追記が消える(エラーなし) | 書く直前に読み直す。変えたい1か所だけ置き換える |
| 置き換えたい文がもうない・2か所ある | 推測で書くと、二重の記述や上書きになる | 止まって知らせる |
| 同じ名前の新しいファイルを2人が作る | 後から作ったほうが上書きする | open() の "x" のように「もうあれば失敗」で作る |
| 同じ PC で、ほぼ同時に同じファイルを書く | 読み直しても間に合わない | 鍵ファイルで順番にする(全員が守る前提) |
| 別の場所・別のマシンから書く | 手元の鍵は見えない | Git で共有し、断られたら pull してからやり直す |
| pull で衝突した | 隣の行でも衝突することがある | 自分で選ばずに止まって知らせる |
この表、印刷して冷蔵庫に貼っておこう
冷蔵庫の紙も、清書して貼り替えると、家族が書き足した「牛乳 買う」が消えます。貼るなら、1枚目の横に。
これを全部 AI に覚えさせれば、完璧
全部書いたら、指示のファイルが長くなりませんか
長くなります。そして長いルールほど、一部が読み飛ばされる心配が出てきます。
いちばん効くのは、そもそも同じ行を2人に触らせない作り方です。AI ごとに書く欄を分ける、追記は末尾だけにする、日付ごとにファイルを分ける。ホワイトボードを2枚にすれば、清書しても隣の人の字は消えません。
ここから先は上級者向け。読み飛ばしてもOKです。
CLAUDE.md と AGENTS.md に同じルールを書くと、片方だけ古くなりうる
2つの AI で同じルールを守らせたいとき、おうどんのように、Claude Code 用の CLAUDE.md と Codex 用の AGENTS.md に同じ中身を置くことがあります。
ここで気をつけたいのは、それぞれの AI が、どちらのファイルを読むかです。
Claude Code のメモリーのドキュメントによると、Claude Code(v2.1.277 以降)は AGENTS.md も読めます。ただし既定では、作業フォルダかその上に CLAUDE.md(.claude/CLAUDE.md・CLAUDE.local.md を含む)があると、CLAUDE.md だけを読み、AGENTS.md は読みません。AGENTS.override.md は読まない、とも書かれています。
CLAUDE.md があると、AGENTS.md は見ないんですか。せっかく置いたのに
置いてあっても、見ない。冷蔵庫の奥の作り置きと同じです。
一方、Codex の AGENTS.md のドキュメントでは、Codex はプロジェクトのルート(ふつうは Git のルート)から今のフォルダまで下りながら、各フォルダで AGENTS.override.md → AGENTS.md → 設定した代わりの名前、の順に探し、1つのフォルダから読むのは1つだけ。見つけたものを上から順につなげ、合計が project_doc_max_bytes(既定 32 KiB)に達したら、それ以上は足しません。
つまり、両方を置いた既定の状態では、こうなります。
| ファイル | Claude Code | Codex |
|---|---|---|
| CLAUDE.md | 読む | 読まない(代わりの名前に設定していなければ) |
| AGENTS.md | 読まない(CLAUDE.md があるため) | 読む |
| AGENTS.override.md | 読まない | AGENTS.md より先に読む |
読者「同じ献立表を2枚貼っているから、どっちを見ても同じでしょ」
同じなのは、書いたその日だけです。片方だけ直した日から、Claude は昨日の献立、Codex は今日の献立で、仕込みを始めます。どちらも、エラーは出しません。
Codex だけに効かせたくて AGENTS.override.md を足した場合も、Claude Code はそれを読まないので、2人の指示はそこでずれます。
ずらさない手は、ドキュメントに2つあります。
- CLAUDE.md の中に
@AGENTS.mdと書いて、AGENTS.md を取り込む(import)。Claude 向けの指示は、その下に足す - Claude Code の設定(Project instructions)を
claude-md-and-agents-mdにして、CLAUDE.md と AGENTS.md を両方読ませる
1つ目の書き方は、たとえばこうです(未実行の設定例)。
@AGENTS.md
## Claude Code だけの指示
- (ここに Claude Code 向けの指示を足す)
シンボリックリンク(CLAUDE.md を AGENTS.md への別名にする)という手もありますが、同じドキュメントでは、Windows で作業する人がいるなら import を使うよう案内されています。リンクを作るのに管理者権限か開発者モードが要り、core.symlinks を有効にしていない clone では、リンクが1行のテキストファイルとして取り出されてしまうためです。
ルールのファイルにルールを書くための、ルールがある
その説明書は、どこに置けば
ここ(この記事)に置いておきます。
ルールは「始めたとき」に読まれる
もう1つ、読まれるタイミングの話です。
Claude Code のドキュメントでは、CLAUDE.md はセッションの開始時に読まれます(プロジェクトのルートの CLAUDE.md は、/compact のあとにも読み直される)。Codex のドキュメントでも、Codex は起動したときに指示のつながり(instruction chain)を組み立て、TUI(ターミナルの画面)ではふつう1セッションに1回、とあります。
ここから考えると、Codex が作業の途中で AGENTS.md を直しても、すでに動いている Claude Code のセッションに、その直しが指示として入るのは、次に始めたときです。逆も同じ。
2つの AI に「ルールを直したら、相手にも伝わる」と期待するなら、伝わるのは次の起動から、と考えておくのが安全です(ここは両方のドキュメントの読み込みタイミングから考えたことで、2つの AI を同時に動かして確かめてはいません)。
板前でいうと、朝礼で配られた献立表は、昼に本部で書き換えられても、自分の手元のは朝のままです。
読者「本部、電話くらいしてよ」
電話はありません。次の朝礼を待ちます。
設計の判断:読み直し・1か所編集・鍵・Git の使い分け
最後に、それぞれの手が何を防ぎ、何を防がないかを並べます。
| 手 | 防げること | 防げないこと・前提 |
|---|---|---|
| 書く直前に読み直す | 何分も前に読んだ内容での上書き | 読み直してから書くまでの、わずかな間の割り込み |
| 1か所だけ置き換え、なければ止まる | 間に入った他の行の追記を消すこと。同じ行の二重の直し | 置き換え元を自分で決め打ちしすぎると、止まる回数が増える |
open() の "x" で作る | 同じ名前の新しいファイルの上書き | できたあとの書き換え |
| 鍵ファイル | 同じ場所での同時の読み書き | 鍵を守らない相手。外し忘れ。別のマシン |
| Git(push が断られたら pull) | 別の場所からの変更が、黙って消えること | 衝突の解決そのもの(隣の行でも起きうる) |
全部やれば、最強ですか
全部やると、メモに1行足すのに会議が3回いる
おうどんの考えでは、まず「1か所だけ直す」と「書く直前に読み直す」を指示に入れる。2つの AI の作業場所が分かれているなら Git。同時に動く時間が重なるなら、時間をずらすか鍵。新しいファイルは「もうあれば止まる」。この順で足していけば、たいていの事故は防げると思います。
逆に、AI の性能が上がれば解決する話でもありません。どんなに賢い板前でも、自分が見ていない間に書かれた字は知りようがない。これは頭のよさではなく、段取りの話です。
読者「じゃあ、AI を1人に減らせば解決では」
それがいちばん確実です。ただ、おうどんは2人とも手放す気がないので、この記事を書いています。
ホワイトボードは、清書しないで赤ペンで
冒頭では、2人に頼んで、メモが1行しか増えませんでした。
犯人は、朝に写したメモで清書して、上から貼り替えた板前。悪気はゼロ、エラーもゼロ。
毎朝のタスクに『下書きがもうあったら止まる』を入れてあったのは、正解でしたね。おうどんさんにしては、慎重です
いま、ほめられた? メモしておこう。1か所だけ
2つの AI に同じファイルを触らせるなら、清書させずに、1か所だけ直させる。
書く直前に読み直して、直す場所がなければ止まる。それだけで、ネギは消えなくなります。
それでも、清書したくなりませんか
なります。ぐっとこらえて、赤ペンで。
まずは、AI への指示に「ファイル全体を書き直さない」の1行を足すところから🍜
参考資料
- Python ドキュメント:open()(組み込み関数) —
"w"は先にファイルを空にする、"x"はファイルがもうあれば失敗する - git push のドキュメント(NOTE ABOUT FAST-FORWARDS・–force・–force-with-lease) — fast-forward でない push を既定で断る理由、pull か pull –rebase で取り込んでから push する流れ、–force でコミットが失われうること
- git merge のドキュメント(HOW CONFLICTS ARE PRESENTED・HOW TO RESOLVE CONFLICTS) — 片方だけの変更はそのまま入り、同じ場所の変更は衝突の印で残ること、merge –abort と解決の手順
- Claude Code ドキュメント:How Claude remembers your project — CLAUDE.md があると AGENTS.md を読まない既定、AGENTS.override.md は読まない、@AGENTS.md の import、Windows では import を使う理由、セッション開始時と /compact 後の読み込み
- Codex ドキュメント:AGENTS.md — 探す順番(AGENTS.override.md・AGENTS.md・代わりの名前)、1フォルダ1つ、上からつなげる、既定 32 KiB の上限、起動時に組み立てること
2026年11月時点の内容です。










コメント