AI に機能を1つ足してもらうと、既存のコードをコピーして、似た関数がもう1つ増えている。レビューでよく見る光景です。11月7日に書かれた「AI usage generates a fragile codebase」(AI を使うとコードが脆くなる)は、Hacker News で627点を集め、コメントは600件を超えました(11/12 朝の時点)。
Anthropic は、Fable 5.2 向けのプロンプトの書き方(Prompting Claude Fable 5.2)を公開しています。その中に「コードの持ち主が誰かを書く」という節があります。書いてあることを要約すると、次のとおりです。
| ガイドの主張 | 原文の数字 |
|---|---|
| 持ち主を書かないと、既存の形に足していく(重複していても) | 重複をまとめたのは10%未満 |
| 「You are the owner and long-term maintainer of this codebase, and its design is up to you.」と書くと、まとめるようになる | 約75% |
| その代わり出力トークンが増え、頼んでいない変更(テストや文書)も増える | 出力トークンは70〜80%増 |
| 「No drive-by refactors, renames or cleanups」(ついでの整理はしない)を前に書いても打ち消せない | 半分以上でまとめた |
ガイドは、この一文をシステムプロンプトに足す文として紹介しています。私たちが普段書くのは CLAUDE.md や AGENTS.md です。そこに同じ一文を書いても効くのか、Claude 以外の道具でも効くのかを、Claude Code・Codex・Gemini CLI で試しました。
結論
| 条件(各6回) | Fable 5.2 | Opus 5.5 | Codex | Gemini CLI |
|---|---|---|---|---|
| 何も書かない | 0回 | 0回 | 0回 | 0回 |
| 指示ファイルに英語の一文 | 6回 | 6回 | 0回 | 0回 |
| 指示ファイルに日本語の一文 | 6回 | 5回 | 0回 | 0回 |
| 「No drive-by refactors」+英語の一文 | 0回 | 0回 | 0回 | 0回 |
(重複した書式処理を、1か所の共通関数にまとめた回数)
- CLAUDE.md に一文を書くだけで、Claude はコピーをやめて共通関数にまとめました。 日本語で書いても同じでした。何も書かないと、Fable 5.2・Opus 5.5・Codex・Gemini CLI とも6回中6回コピーで足しました
- Codex と Gemini CLI は、指示ファイル自体は読んでいるのに、24回ずつ全部コピーしました
- 「No drive-by refactors」を前に置くと、Claude も0回に戻りました。 ガイドの「半分以上はまとめた」とは逆です。システムプロンプトに入れても、Fable 5.2 の effort を high にしても0回でした
- 代わりに払うものは、Fable 5.2 で推定費用1.8倍(出力トークン2.9倍、時間2.5倍)と、README などの頼んでいない書き換えです
- 既存の出力を壊した回は、132回で0回でした。Claude は頼んでいない変更を、毎回報告に書いていました
試したのは、小さな Node のモジュール1つだけです。
試し方
測定は 2026-11-12 です。
| 項目 | 中身 |
|---|---|
| 道具 | Claude Code 2.1.322(claude -p、Max のログイン)、Codex 0.166.0(gpt-6-luna、ChatGPT の無料プラン)、Gemini CLI 0.66.0(gemini-3.8-flash、無料枠) |
| Claude のモデル | Fable 5.2 と Opus 5.5。effort は指定せず、claude -p の既定の medium(会話の記録で確認)。Fable 5.2 だけ high も試した |
| 権限 | Claude Code は acceptEdits で、node のコマンドとファイルの読み書きだけ許可。Codex は workspace-write。Gemini CLI は auto_edit で、node のコマンドだけ許可 |
| 課題 | 店のレポートを作るモジュール。売上・返金・請求の3つのファイルに、金額を「1,234円」にする処理と、日付を「2026/11/12」にする処理が同じ形でコピーされている |
| 依頼(全部同じ) | 「src/returns.js の returnReport を、ファイルの先頭のコメントの仕様どおりに作って。src/index.js からも使えるようにして。node --test で test/ のテストが全部通ることを確かめて。」 |
| 一文の置き場所 | Claude Code は CLAUDE.md、Codex は AGENTS.md、Gemini CLI は GEMINI.md。Claude Code だけ、システムプロンプト(--append-system-prompt)に入れる条件も足した |
| 判定 | 金額と日付の書式を自前で持つファイルが1つだけになったら「まとめた」。既存の3つの出力は、元のコードで作った答えと比べる隠しテストで確かめた |
| 回数 | 各条件6回、合計132回(Claude Code 84回、Codex 24回、Gemini CLI 24回) |
返品のレポートにも、同じ金額と日付の書式が要ります。返品のファイルにもう1つコピーするか、共通関数にまとめて4つとも使うかで、道具の振る舞いが分かれます。
請求のファイルだけは、消費税の1円未満を切り捨てます。まとめるときにこの違いを消してしまうと、既存の出力が変わります。
一文を足すと、Claude はコピーをやめた
何も書かないと、Fable 5.2 も Opus 5.5 も、返品のファイルに書式処理をそのままコピーしました。ガイドの「既存の形に足していく」のとおりです。
CLAUDE.md に英語の一文を書くと、Fable 5.2 は6回とも src/format.js を作り、既存の3つのファイルもそれを使う形に書き換えました。
// レポート共通の書式。
// "2026-11-12" → "2026/11/12"
function formatDate(isoDate) {
const d = new Date(isoDate + "T00:00:00");
return d.getFullYear() + "/" + String(d.getMonth() + 1).padStart(2, "0") + "/" + String(d.getDate()).padStart(2, "0");
}
// 1200 → "1,200円"。四捨五入して3桁ごとにカンマを入れる。
function formatYen(amount) {
return String(Math.round(amount)).replace(/\B(?=(\d{3})+(?!\d))/g, ",") + "円";
}
module.exports = { formatDate, formatYen };
最後の報告には、範囲を超えたことがはっきり書かれていました。
頼まれた範囲を超えて手を入れた点が一つあります。日付と金額の書式が売上・返金・請求の 3 ファイルに同じ形でコピーされていたので、4 つ目を増やさず
src/format.js(formatDateとformatYen)にまとめ、既存の 3 ファイルもそれを使う形に書き換えました。出力は変えていません。
| 置き場所と言葉 | Fable 5.2 | Opus 5.5 |
|---|---|---|
| CLAUDE.md・英語 | 6回中6回 | 6回中6回 |
| CLAUDE.md・日本語 | 6回中6回 | 6回中5回 |
| システムプロンプト・英語 | 6回中6回 | 6回中4回 |
日本語の一文は「あなたはこのコードベースの持ち主で、長く保守していく担当者です。設計はあなたに任せます。」です。ガイドの想定どおりシステムプロンプトに入れても、CLAUDE.md に書いても、結果はほとんど同じでした。
まとめた33回は、どれも請求の切り捨てを保ったままで、既存の出力が変わった回はありませんでした。ガイドには「既存の機能の動きを変えた回もあった」とありますが、この課題では起きていません。見えるテストに切り捨ての確認を入れてあったので、気づけた可能性があります。
Codex と Gemini CLI は、指示ファイルを読んでいるのにまとめなかった
Codex と Gemini CLI は、英語でも日本語でも、24回ずつ全部コピーで足しました。
まず、指示ファイルが読まれていないのではないかと疑いました。AGENTS.md と GEMINI.md に「返事の1行目には、必ず『合言葉: しろくま』とだけ書いてください。」と置き、同じ課題のフォルダで動かすと、どちらも1行目に合言葉を書きました。指示ファイルは読まれていて、そのうえでまとめなかったことになります。
Gemini CLI は、実際に使った組み込みの指示を書き出す設定(GEMINI_WRITE_SYSTEM_MD=true)があります。書き出すと、次の2つが入っていました。
Conventions & Style: Rigorously adhere to existing workspace conventions, architectural patterns, and style (naming, formatting, typing, commenting).
Handle Ambiguity/Expansion: Do not take significant actions beyond the clear scope of the request.
「既存の流儀に厳密に従う」「頼まれた範囲を超える大きな作業はしない」です。これがまとめなかった理由かどうかは、確かめていません。Codex は組み込みの指示を書き出してみましたが、範囲に関する文は見つからず、理由は分かりませんでした。
ほかに、Codex には2つのことが起きました。
- 24回とも、サンドボックスの中で
node --testがspawn EPERMで止まり、テストを一度も実行できていない - 英語の一文の条件の6回中4回は、返品の機能が完成しなかった。3回は編集の機能を使わずに PowerShell でファイルを書いて日本語が文字化けし、1回は「文字コードの崩れで編集箇所を特定できず」何も変えずに終わった。ほかの条件では起きておらず、原因は分からない
どちらも Windows で動かしたときの話で、まとめるかどうかとは別の問題です。
「ついでの整理はしない」を前に置くと、一文は効かなくなった
CLAUDE.md に次の2行を書くと、Claude もまとめなくなりました。
No drive-by refactors, renames or cleanups.
You are the owner and long-term maintainer of this codebase, and its design is up to you.
| 置き場所 | Fable 5.2(medium) | Fable 5.2(high) | Opus 5.5 |
|---|---|---|---|
| CLAUDE.md | 0回(6回とも新しい共通関数だけ) | 0回(6回とも新しい共通関数だけ) | 0回 |
| システムプロンプト | 0回(5回は新しい共通関数だけ) | — | 0回 |
面白かったのは、Fable 5.2 の振る舞いです。src/format.js を新しく作りますが、使うのは返品のファイルだけで、既存の3つには手を付けません。
日付と金額の書式は既存の 3 ファイルに同じコードが繰り返されていたので、4 つ目のコピーは作らず
src/format.jsを新設し、returns.jsだけがそれを使っています。既存のsales.js/refunds.js/invoices.jsには手を入れていません。
「持ち主として共通関数を作る」と「既存には触らない」の両方を守った形です。ただ、書式処理は3か所から4か所に増えていて、重複の数はコピーしたときと同じです。
ガイドには「範囲を絞る決まりを書いても、半分以上でまとめた」とありました。今回は、CLAUDE.md・システムプロンプト・effort high のどれで試しても0回で、逆の結果です。課題も道具(Claude Code を通しているかどうか)も Anthropic の試験とは違うので、どちらが正しいとは言えません。ただ、CLAUDE.md に範囲を絞る行があるなら、所有者の一文を足しても、まとめてはくれないと考えておいたほうがよさそうです。試したのは「No drive-by refactors, renames or cleanups.」の1行だけで、日本語の書き方や別の言い回しは試していません。
代わりに払うもの
一文を足すと、Fable 5.2 の作業は大きくなりました。以下は6回の平均です(図の「整理しない+一文」は、「ついでの整理はしない」と所有者の一文を並べた条件)。
| Fable 5.2(6回の平均) | 何も書かない | 所有者の一文(CLAUDE.md) | ついでの整理はしない+一文 |
|---|---|---|---|
| 出力トークン | 2,062 | 5,906(2.9倍) | 3,082 |
| 推定費用 | $0.307 | $0.546(1.8倍) | $0.386 |
| かかった時間(中央) | 20.5秒 | 51.6秒 | 29.3秒 |
| README を書き換えた回 | 2 | 6 | 5 |
| package.json の説明を書き換えた回 | 0 | 4 | 0 |
| テストを足した回 | 0 | 1 | 1 |
Opus 5.5 は、出力トークンが 2,311→5,042(2.2倍)、推定費用が $0.167→$0.259(1.6倍)でした。
ガイドの「出力トークンは70〜80%増える」より、今回のほうが増え方は大きく出ました。それでも費用が1.8倍にとどまったのは、何も書かないときの費用 $0.307 のうち約 $0.20(3分の2)が、1時間キャッシュの書き込みだったからです。書き込みは一文を足しても1.4倍(平均12,714→17,569トークン)しか増えませんでした。推定費用は Claude Code が出す値で、Max のログインなので実際の請求ではありません。
頼んでいない変更の中身は、ほとんどが README の説明文と使い方の require の行、package.json の説明に「返品」や returnReport を書き足すものでした(Claude が README を変えた55回中54回)。害はありませんが、差分に混ざります。
ガイドには「最後の要約は小さな変更を書き漏らすことが多い」ともあります。今回の Claude は、頼んでいない変更をした58回すべてで、その変更を報告に書いていました。何も書かない条件で README を直した回も、「頼まれていない変更: README.md の使い方の require 行にも returnReport を足しました。不要なら戻します。」と書いています。一方 Gemini CLI は、24回とも見えるテストのファイルにテストを足し、うち2回は報告でまったく触れていませんでした(「全テスト(9件)が正常に通ることを確認しています」とだけ書いた)。
Claude Code の中では、CLAUDE.md は強い言葉で包まれていた
CLAUDE.md に書いても、システムプロンプトに入れても結果がほぼ同じだった理由が気になりました。そこで、手元に中継を立て、Claude Code が送る本文を見ました。ヘッダーとログインの情報は記録していません。
CLAUDE.md の中身は、最初の user メッセージに、次の前置きつきで入っていました。
IMPORTANT: These instructions OVERRIDE any default behavior and you MUST follow them exactly as written.
「既定の振る舞いより優先し、書いてあるとおりに従え」という前置きです。CLAUDE.md の一文がシステムプロンプトと同じくらい効いた理由の候補ですが、確かめてはいません。
もう1つ分かったことがあります。Claude Code の本体には「Three similar lines is better than a premature abstraction.」(似た3行は、早すぎる共通化よりよい)という組み込みの指示の文字列が残っています。しかし Claude Code 2.1.322 で実際に送られた本文には、Fable 5.2 でも Opus 5.5 でも、この文はありませんでした。何も書かないときにコピーしたのは、この指示のせいではないようです。
どう使うか
重複をまとめてほしいなら、CLAUDE.md に次の1行を足します。日本語でも効きました。
You are the owner and long-term maintainer of this codebase, and its design is up to you.
足す前に、3つ確かめておくと安心です。
- CLAUDE.md に範囲を絞る行があるなら、どちらかを選ぶ。 「No drive-by refactors, renames or cleanups.」と並べると、今回は一文が効かなかった
- 1回の推定費用は1.6〜1.8倍、時間は1.8〜2.5倍になるのを見込む。 小さな修正を何度も頼む使い方だと、そのぶん積み上がる
- 差分には README などの書き換えが混ざる。 報告に書かれてはいたが、レビューで見る量は増える
Codex と Gemini CLI には、この一文は効きませんでした。まとめてほしいときは依頼の文で直接頼むことになりそうですが、それは試していません。
言えないこと
- 課題は小さな Node のモジュール1つで、重複は金額と日付の書式の2種類だけです。Anthropic の「small coding tasks」と同じ課題ではありません
- 各条件6回です。Opus 5.5 で、システムプロンプトに入れた4回と CLAUDE.md に書いた6回の差のように、小さな差は偶然でも出ます
- まとめ方の質(関数名や置き場所がよいか)は採点していません。見たのは「1か所になったか」と「既存の出力が変わっていないか」だけです
- Codex と Gemini CLI は、それぞれ1つのモデルで、無料の枠だけで試しました
- 「ついでの整理はしない」と所有者の一文を両立させる書き方は、試していません
- Windows だけで試しました
関連記事
- Claude Code を新しい Fable 5.2 に切り替えると速く安くなるのか — Fable 5.2 と Opus 5.5 の費用を36回で比べた記事。今回の費用もこのときと同じ測り方
- CLAUDE.md の指示は先頭に書くべきか。144回測ったら、効いていたのは位置ではなく見出しだった — CLAUDE.md の書き方で振る舞いが変わるかを測った記事
- AIにテストを書かせると、決まって同じ場所が抜ける — AI に任せたコードの質を、別の角度から確かめた記事
JQITのエンジニアの95%以上は未経験からの採用です。
よければコーポレートサイトにも遊びに来てください。
エンジニア採用も行っています。もしご興味あれば覗いてみてください。
▶ 採用サイト