Codex で DeepSeek モデルを使う2つの方法:ローカルゲートウェイと OpenRouter BYOK

Codex CLI を DeepSeek に接続する2つの現実的な方法を整理する。ローカルゲートウェイでプロトコルを橋渡しする方法と、OpenRouter BYOK をオンラインプロキシとして使う方法、そして base_url だけの変更が失敗しやすい理由。

Codex で DeepSeek を使いたいとき、まず思いつくのは ~/.codex/config.toml を書き換えることです。

1
2
model = "deepseek-chat"
base_url = "https://api.deepseek.com"

この考え方は、古いバージョンや通常の OpenAI SDK の場面では成り立つことがあります。しかし現在の Codex CLI では、低レイヤーの不一致にぶつかりやすいです。Codex のカスタムモデルプロバイダーは OpenAI Responses プロトコルを使う一方で、DeepSeek の公式 API は主に OpenAI 互換の Chat Completions 形式で提供されています。

手元の環境は codex-cli 0.111.0 です。codex --help では --config--model--profile などの設定入口が確認できます。OpenAI 公式の Codex 設定リファレンスでも、model_providers.<id>.wire_api は現在 responses のみをサポートし、省略時も responses が既定だと明記されています。

一方、DeepSeek の公式ドキュメントでは呼び出し先が https://api.deepseek.com/chat/completions とされ、例も client.chat.completions.create(...) です。つまり問題は DeepSeek が OpenAI 風のツールから呼べないことではありません。Codex が送るリクエストの意味論と、DeepSeek のネイティブ API が理解する意味論が完全には一致しないことです。

そのため、base_url をそのまま https://api.deepseek.com に変えると、次のような症状が出ることがあります。

  • リクエストパスが合わず、404 になったり想定外の形式が返ったりする。
  • 複数ターンの会話、ツール呼び出し、パッチ生成で解析に失敗する。
  • tool_calls の順序、メッセージ構造、ストリーミングイベント形式が合わない。
  • 普通の一問一答は返せるのに、Codex が実作業を始めるとエラーになる。

より安定した方法は、Codex と DeepSeek の間に「翻訳層」を置くことです。よく使われるルートは2つあります。

方法1:ローカルゲートウェイで DeepSeek を橋渡しする

ローカルゲートウェイの役割は単なる転送ではありません。Codex 側の Responses 形式のリクエストを、DeepSeek が処理できる Chat Completions 形式に変換し、DeepSeek の結果を Codex が扱える形式に戻します。

ccx のようなローカルゲートウェイを使う場合、設定の考え方はおおむね次のようになります。

1
2
3
4
5
6
7
8
[profiles.deepseek-ccx]
model = "deepseek-v4-flash"
model_provider = "ccx-bridge"

[model_providers.ccx-bridge]
name = "Local CCX Gateway"
base_url = "http://localhost:3000/v1"
env_key = "DEEPSEEK_API_KEY"

次にターミナルで DeepSeek Key を設定し、この profile で起動します。

1
2
export DEEPSEEK_API_KEY="your-deepseek-key"
codex --profile deepseek-ccx

PowerShell では次のようにします。

1
2
$env:DEEPSEEK_API_KEY="your-deepseek-key"
codex --profile deepseek-ccx

ここでは2つの点に注意します。

第一に、base_url は DeepSeek の公式アドレスではなく、Codex に対してゲートウェイが公開しているアドレスを指します。DeepSeek への呼び出しはゲートウェイ側で行います。

第二に、env_key に何を書くかはゲートウェイの認証方式次第です。DeepSeek 公式 Key を直接読むゲートウェイもあれば、ローカルプロキシ用の Key を渡し、DeepSeek Key はゲートウェイの管理画面に保存するものもあります。その場合、env_key はゲートウェイが要求する環境変数名に変更します。

このルートの利点はローカルで制御でき、遅延やコストも把握しやすいことです。欠点は、そのゲートウェイが Codex の現在の Responses 意味論を本当にサポートしているか確認する必要があることです。単なる Chat Completions プロキシでは不十分な場合があります。

方法2:OpenRouter BYOK をオンラインブリッジとして使う

ローカルゲートウェイを動かしたくない場合は、OpenRouter の BYOK も選択肢になります。BYOK は、自分の上流プロバイダー Key を OpenRouter に紐づけ、OpenRouter にルーティングと転送を任せる仕組みです。

ここで一番間違えやすいのは環境変数です。Codex がアクセスする相手は OpenRouter なので、env_key は通常 DEEPSEEK_API_KEY ではなく OPENROUTER_API_KEY にします。DeepSeek Key は OpenRouter の BYOK または provider key の設定に追加します。

設定例です。

1
2
3
4
5
6
7
8
[profiles.deepseek-openrouter]
model = "deepseek/deepseek-chat"
model_provider = "openrouter"

[model_providers.openrouter]
name = "OpenRouter"
base_url = "https://openrouter.ai/api/v1"
env_key = "OPENROUTER_API_KEY"

起動方法は次の通りです。

1
2
export OPENROUTER_API_KEY="your-openrouter-key"
codex --profile deepseek-openrouter

PowerShell では:

1
2
$env:OPENROUTER_API_KEY="your-openrouter-key"
codex --profile deepseek-openrouter

そのうえで OpenRouter の管理画面に DeepSeek の provider key を追加します。OpenRouter の BYOK ドキュメントによると、紐づけられた provider key は暗号化して保存され、対応するプロバイダーへのルーティングに使われます。

このルートはローカルゲートウェイの運用コストを省け、通常のサードパーティ API プロキシに近い感覚で設定できます。一方で、間にオンラインサービスが1つ増えるため、トラブルシュートでは Codex、OpenRouter、DeepSeek の三者のエラーを見る必要があります。

deepseek-chat というモデル名を使い続けるべきか

2026年5月時点の DeepSeek 公式ドキュメントでは、推奨モデル名として deepseek-v4-flashdeepseek-v4-pro が出ており、deepseek-chatdeepseek-reasoner の互換エイリアスは 2026-07-24 以降に廃止されると案内されています。

そのため新しい設定では、まず次を試すのがおすすめです。

1
model = "deepseek-v4-flash"

OpenRouter 経由の場合は、OpenRouter のモデル命名規則に従います。たとえば:

1
model = "deepseek/deepseek-chat"

実際に使える名前は、利用しているゲートウェイまたは OpenRouter のモデルページを基準にしてください。モデル名が間違っていると、通常は model not found、404、または provider が対応する endpoint を見つけられない形で失敗します。

DeepSeek 公式 base_url への直指定をおすすめしない理由

もちろん、実験として次のように書くことはできます。

1
2
3
4
5
6
7
8
[profiles.deepseek-direct]
model = "deepseek-v4-flash"
model_provider = "deepseek"

[model_providers.deepseek]
name = "DeepSeek"
base_url = "https://api.deepseek.com"
env_key = "DEEPSEEK_API_KEY"

ただしこれは安定運用の設定というより、切り分け用の実験に近いです。Codex はカスタム provider と Responses プロトコルで会話しますが、DeepSeek の公式例は /chat/completions を使っています。将来 DeepSeek または Codex が互換層を補えば、直結も簡単になるかもしれません。それまでは橋渡し層を置く方が堅実です。

設定後も OpenAI に接続される場合

まず設定ファイルの場所を確認します。グローバル設定は次の場所です。

1
~/.codex/config.toml

プロジェクト内の .codex/config.toml は、model_providermodel_providers のようなマシン単位の provider 設定を置く場所としては適していません。OpenAI 公式ドキュメントでも、プロジェクト単位の設定はローカル provider や認証関連のフィールドを上書きしないと説明されています。

Codex がまだ Web ログインを要求する場合や、既定の OpenAI モデルを使っているように見える場合は、まず現在のログイン状態を解除します。

1
codex logout

古いチュートリアルではインタラクティブ画面内の /logout と書かれていることがあります。現在の CLI では、ターミナルで直接 codex logout を実行する方が安定です。

一時的な引数で素早く確認することもできます。

1
codex --profile deepseek-ccx

または:

1
codex -c model_provider=ccx-bridge -c model=deepseek-v4-flash

これで有効になるなら、設定自体は読み込めています。うまくいかない場合は、profile 名、TOML 構文、環境変数が現在の shell セッションだけに存在していないかを優先して確認します。

トラブルシュート一覧

  • 401:Key が違う、または env_key が間違った環境変数を指している。
  • 404base_url またはモデル名が違う。あるいは Responses リクエストを Chat Completions しか対応していないアドレスへ送っている。
  • tool_calls、patch、ストリーミング解析のエラー:プロトコル橋渡しが不完全な可能性が高い。
  • OpenAI へのログインをまだ求められる:codex logout を実行し、正しい profile を使っているか確認する。
  • PowerShell で設定した環境変数が新しいウィンドウで消える:$env:... は現在のセッションにしか効かない。永続化するならユーザー環境変数を設定する。
  • OpenRouter BYOK が自分の DeepSeek Key を使っていない:OpenRouter 側で provider key が紐づいているか、現在の OpenRouter API Key がそれを使えるか、fallback が有効になっていないかを確認する。

まとめ

Codex で DeepSeek を使うために config.toml を変更すること自体は可能です。ただし base_url だけを変えてすべてが自動的に互換になると考えるのは危険です。

現在より安定しているルートは次の2つです。

  1. ローカルゲートウェイでプロトコルを橋渡しする。Codex はローカルゲートウェイへ接続し、ゲートウェイが DeepSeek へ接続する。
  2. OpenRouter BYOK をオンライン転送として使う。Codex は OpenRouter へ接続し、DeepSeek Key は OpenRouter の管理画面に紐づける。

短時間で試すだけなら OpenRouter の方が手軽です。Key、コスト、ログをできるだけ自分で管理したいなら、長期的にはローカルゲートウェイの方が向いています。

参考資料:

记录并分享
Hugo で構築されています。
テーマ StackJimmy によって設計されています。