LLMのモデルが次々とリリースされる時代に、プロダクトのコードベースをどうやって追従させるか。
正直、ここ最近ずっとこの問題がうっすら気になっていました。

自分が開発している ai-workflow-agent は、GitHub Issue の内容をもとに、計画→設計→実装→テスト→ドキュメントまでを自動で回すワークフローエンジンです。内部では OpenAI の Codex モデルと Claude を使い分けていて、Codex 側のデフォルトモデルは gpt-5.1-codex-max でした。

そこに gpt-5.2-codex が出た。
「上げるべきだろうな」と思いつつ、16ファイルに散らばったモデル名をどう安全に切り替えるか——というのが今回の話です。

まず情報収集から始めた(そしてハマった)

最初にやったのは、ChatGPT に gpt-5.2 系のモデルラインナップを聞くことでした。

「5.2 の軽量モデルは何を使えばいい?」と聞いたところ、最初は「gpt-5.2-mini があります」と返ってきた。でも、もう一度聞き直すと「公式 API には gpt-5.2-mini は存在しません」と訂正が入りました。

ここ、罠です。

LLM に LLM のモデル情報を聞くと、ハルシネーションが混ざることがある。特にリリース直後のモデルは学習データに含まれていない可能性が高いので、最終的には公式ドキュメントで裏を取るのが鉄則です。自分も OpenAI の API ドキュメントとモデル一覧ページで確認してから判断しました。

結論として、こういう方針に落ち着きました。

理由はシンプルで、5.2 系には軽量版の Codex モデルがまだ公式に出ていなかったからです。存在しないモデルに切り替えるわけにはいかない。「上位だけ上げて、軽量は据え置き」——地味ですが、これが一番現実的な判断でした。

エイリアスシステムという「保険」

ここで少し設計の話をします。

このプロジェクトでは、モデル名を直接コードにハードコードするのではなく、エイリアスシステムを間に挟んでいます。codex-agent-client.ts で定義しているのがこれです。

export const CODEX_MODEL_ALIASES: Record<string, string> = {
  max: 'gpt-5.2-codex',       // デフォルト、複雑なタスク向け
  mini: 'gpt-5.1-codex-mini', // 軽量、コスト効率重視
  '5.1': 'gpt-5.1',           // 汎用
  legacy: 'gpt-5-codex',      // 後方互換性
};

利用者は --codex-model max--codex-model mini のようにエイリアスで指定する。実際のモデル ID への解決はこの定数が一手に引き受けます。

graph LR
    A[ユーザー入力] --> B{エイリアス?}
    B -->|max| C[gpt-5.2-codex]
    B -->|mini| D[gpt-5.1-codex-mini]
    B -->|legacy| E[gpt-5-codex]
    B -->|フルID| F[そのまま通す]

この設計を入れたのは、もともと gpt-5-codexgpt-5.1-codex-max の移行時(Issue #302)に「また同じことが起きるな」と思ったからです。自転車に乗る感覚と同じで、一度やり方を覚えてしまえば次からは楽になる。実際、今回の移行でもエイリアスの解決先を1箇所変えるだけでコアロジックは完了しました。

意外とここが肝なんですが、legacy エイリアスも残しています。前のバージョンに固定したいワークフローがあったときに、--codex-model legacy で即座に戻せる。「新しいモデルに問題があったら?」という不安への保険です。

難易度ベースの自動モデル選択

もうひとつ、このプロジェクトには Issue の難易度に応じてモデルを自動で切り替える仕組みがあります(Issue #363)。

graph TD
    A[Issue 難易度判定] --> B{難易度}
    B -->|simple| C[全フェーズ: mini]
    B -->|moderate| D[フェーズ別に振り分け]
    B -->|complex| E[全フェーズ: max]
    D --> F[戦略フェーズ: execute→max / revise→mini]
    D --> G[コードフェーズ: execute→max / revise→max]
    D --> H[ドキュメントフェーズ: 全ステップ mini]

ポイントは、review ステップは難易度に関係なく常に mini にしていること。レビューは「確認」であって「創造」ではないので、軽量モデルで十分という判断です。逆にコードフェーズの revise(修正)は moderate でも max を使う。ここをケチると修正の質が落ちて、結局やり直しになるのでコスト的にも逆効果でした。

このあたりのトレードオフは、実際に運用しながら調整してきた結果です。最初から完璧な振り分けができたわけではなく、「mini で回したら修正が雑だった」「max で回したらコストが跳ねた」を繰り返して今の形に落ち着きました。

実際の移行作業:Claude Code で一括置換

さて、実際の移行です。Claude Code(Sonnet 4.5)を使って進めました。

まず影響範囲の確認。gpt-5.1-codex-max で検索すると、261箇所がヒットしました。内訳はコードファイル3つ、テストファイル5つ、ドキュメント8つ(合計16ファイル)。

作業自体は Claude Code に「gpt-5.1-codex-maxgpt-5.2-codex に置き換えたい」と伝えるだけで、コード・型定義・ドキュメントを順番に更新してくれました。ただし、ここで1回つまずいています。

正直ここで詰まりました

最初の npm test で、テストが18件失敗しました。

原因は、テストファイル内のホワイトスペース処理のテストケースまで拾いきれていなかったこと。たとえばこういうテスト。

// 前に空白があるエイリアスのテスト
expect(resolveCodexModel('  max')).toBe('gpt-5.1-codex-max');  // ← ここも変わる
// タブ文字を含むエイリアスのテスト
expect(resolveCodexModel('\tmax\t')).toBe('gpt-5.1-codex-max'); // ← ここも

maxgpt-5.2-codex に変えたのだから、max のエイリアス解決を検証するテストは全部期待値が変わる。当然のことなんですが、最初の置換では「max エイリアスのメインテスト」は更新したのに「ホワイトスペース付き max」のテストが漏れていました。

ここでの学びは2つ。

  1. 文字列の単純置換だけでは足りない。エイリアスの解決結果を検証するテストは、エイリアス名ではなく解決後のモデル名で検索しないと漏れる
  2. テストが多いのは正義。30件のユニットテストがあったからこそ、漏れに気づけた。テストがなければ本番で「あれ、ホワイトスペース付きの入力で旧モデルが使われてる?」みたいなバグになっていた

修正後に再テスト。Codex モデル関連の72件が全件パス。ビルドも成功。

Test Suites: 1 passed, 1 total
Tests:       30 passed, 30 total

ちなみに、全テスト実行時に別のテスト(rewrite-issue.test.ts や Git 権限系)が失敗していましたが、これらは今回のモデル変更とは無関係な既存の環境問題です。切り分けは git diff で変更ファイルを確認すればすぐにわかります。

最終的な変更サマリー

コミットメッセージはこうなりました。

feat: Update Codex default model to gpt-5.2-codex

- Change DEFAULT_CODEX_MODEL from gpt-5.1-codex-max to gpt-5.2-codex
- Update 'max' alias to resolve to gpt-5.2-codex
- Update all documentation to reflect the new default model
- Update test expectations to match the new model

16ファイル、56行の変更。挿入と削除が同数(56 insertions, 56 deletions)というのが、今回の作業の性質をよく表しています。新機能の追加ではなく、既存の値の置き換え。

変更の優先順位も意識しました。

  1. コアコードcodex-agent-client.ts, commands.ts, agent-setup.ts)— ここが本体
  2. テストファイル(5ファイル)— 期待値の更新
  3. ドキュメント(8ファイル)— README, CHANGELOG, CLI リファレンスなど

この順序にしたのは、万が一途中で問題が起きたときに「コアは更新済み、テストは途中」という状態を避けるためです。コアとテストはセットで通す、ドキュメントは最後。

振り返り:モデル移行を「怖くない作業」にするために

今回の移行を通じて改めて感じたのは、モデル名をコードベースに散らばらせない設計の重要性です。

エイリアスシステムがなかったら、16ファイル56箇所を手動で書き換えて、一つひとつ正しいか目視で確認する作業になっていました。エイリアスがあったおかげで、実質的な変更は CODEX_MODEL_ALIASES の1行と DEFAULT_CODEX_MODEL の1行。あとはその値を参照しているテストとドキュメントの更新です。

もうひとつ、LLMモデルの情報収集にLLM自身を使うときの注意点。便利ではあるんですが、特にリリース直後のモデル情報はハルシネーションが起きやすい。今回もChatGPTの回答が途中でブレたことで「公式ドキュメントで裏を取る」重要性を再確認しました。

次に gpt-5.3-codex が API で使えるようになったら、また同じ手順で移行するだけです。エイリアスの解決先を書き換えて、テストを回して、ドキュメントを更新する。そのサイクルが回る設計にしておいたことが、今回一番の収穫だったかもしれません。

実際に移行後のモデルでワークフローを回してみたところ、問題なく動作しています。

2026-02-09 13:09:32 [INFO ] Using model override for Codex Agent: gpt-5.2-codex (phase=implementation)
2026-02-09 13:09:32 [INFO ] [CODEX EVENT] type=thread.started
2026-02-09 13:09:36 [INFO ] [CODEX REASONING] [item_0] **Clarifying file write approach**
2026-02-09 13:09:36 [INFO ] [CODEX EXEC] [item_1] Completed ✓

この ai-workflow-agent をベースにした開発自動化ツール DevLoop Runner も、今回の移行に合わせて gpt-5.2-codex ベースに更新しました。興味のある方はこちらからどうぞ。

🔗 https://devloop-runner.app/

参考書籍

Claude Code を活用した開発やリファクタリングについて深く学びたい方には、以下の書籍が参考になります。

[📦 商品リンク: moshimo-book-9CeFY]

[📦 商品リンク: moshimo-book-fINTJ]

[📦 商品リンク: moshimo-book-5line-refactoring]

実際のプロジェクトで試しながら読むことで、設計判断の引き出しが増えていきます。