# Claude CodeにあなたのChatGPTサブスクリプションで自動画像生成させる：API key不要、Turnstileをどう回避しているのか

![ノートPCで1行コマンドから画像生成、API key不要](https://img.leeguoo.com/media/7be1dfdf-039e-4266-9ce7-fc0f5f1385a3/cover.png)

Claude CodeにREADMEや{技術文書|ぎじゅつぶんしょ}を書かせるとき、ついでに{挿絵|さしえ}も{生成|せいせい}できるでしょうか？できます。しかも `OPENAI_API_KEY` は不要で、{追加|ついか}でお金を払う{必要|ひつよう}もありません。すでに{支払|しはら}っているChatGPTサブスクリプションを使います。この記事のdoodle{風|ふう}の{挿絵|さしえ}も、Claude Codeがこの記事を書いているときに自分で呼び出したものです。

画像{生成|せいせい}{機能|きのう}をagentに{接続|せつぞく}するには2つのルートがあります。{違|ちが}いは、サブスクリプション内のどの{枠|わく}を使うか、そして{無料|むりょう}アカウントで使えるかどうかです。この記事では、その{背後|はいご}でいちばん{面白|おもしろ}いルート、つまりwebバックエンドと、それがchatgpt.comのアンチスクレイピングをどう{回避|かいひ}しているかを{説明|せつめい}します。

## まず、よくある{誤解|ごかい}を{訂正|ていせい}します

多くの人は「ChatGPTサブスクリプションで{画像|がぞう}を{生成|せいせい}する」{節約|せつやく}{方法|ほうほう}は1つだけだと思っています。つまり、Codex CLIのOAuth tokenを{再利用|さいりよう}して、`backend-api/codex/responses` に{直接|ちょくせつ}POSTする方法です。私の前の記事[『ChatGPTサブスクリプションを画像生成APIに変える』](https://blog.leeguoo.com/ja/posts/chatgpt-imagegen/)で{説明|せつめい}したのは、まさにこのルートです。

そこには、きちんと{説明|せつめい}しきれていなかった点が2つあります。

1つ目は、Codexの{計量|けいりょう}{枠|わく}を{消費|しょうひ}することです。サブスクリプションは1つのバケツではなく、2つの{独立|どくりつ}した{制限|せいげん}バケツです。1つはChatGPTのWebページでチャットするときの{枠|わく}、もう1つはCodexの{使用量|しようりょう}です。`codex/responses` を通ると{後者|こうしゃ}を使います。つまり、Codex CLIでコードを書くときに、いちばん{無駄|むだ}にしたくない{枠|わく}です。

2つ目は、Codex CLIをインストールして、`codex login` したことがある{必要|ひつよう}がある点です。無料のChatGPTアカウントにはCodexがないので、このルートはそもそも使えません。

![チャット{枠|わく}とCodex{使用量|しようりょう}は2つの{独立|どくりつ}したバケツ](https://img.leeguoo.com/media/47e5fdd7-c3a8-4ec6-bfe9-8fc605bb4154/two-buckets.png)

そこで{問題|もんだい}はこうなります。「Webページの{会話|かいわ}」のラインで画像を生成できないか？そのラインは無料アカウントにもあり、無料ユーザーはChatGPTのWebページ内でもともと画像を生成できます。使うのはチャット{枠|わく}で、Codex{使用量|しようりょう}にはまったく触れません。

できます。ただし、その{代償|だいしょう}として、本当に「Webページ」側へ行って画像を生成する{必要|ひつよう}があります。これが [`chatgpt-imagegen`](https://github.com/leeguooooo/chatgpt-imagegen) の **webバックエンド**であり、この記事の{主役|しゅやく}です。

## なぜ codex バックエンドのように直接 POST できないのか

直感的な案はこうです。Webページの画像生成も HTTP リクエストを送っているのだから、パケットを取って、cookie を持ってきて、リプレイすればいいのでは？

試した人はみんな chatgpt.com のスクレイピング対策で詰まります。ここでは防御ラインを分解して見る価値があります。というのも、本当にあなたを止めている層は、多くの人が想像するものとは違うからです。

| 防御ライン | 何か | 裸のクライアントで通れるか |
| --- | --- | --- |
| Cloudflare エッジチェック | 通常の CF bot 検出 | ✅ 通れる |
| Sentinel 作業量証明 | `backend-api/sentinel/chat-requirements` + ページ内の `sentinel/sdk.js` で PoW token を計算 | ✅ 通れる。アルゴリズムはページ JS 内にあり再現できる |
| **Cloudflare Turnstile token** | インタラクティブ認証で生成される一回限りの token | ❌ **通れない** |

前の二層は、純粋な Python クライアントでもシミュレートできます。本当の壁は第三層です。Turnstile token は、本物のインタラクティブなブラウザがその場でしか生成できず、しかも一回限り有効です。「先にブラウザで token をひとつ取って、あとで headless に持っていってリプレイする」という近道はありません。token は一度使えば無効になり、次のリクエストにはまた新しいものが必要で、新しい token を生成するには本物のブラウザがその場にいなければなりません。

![三つの門。前二つは開いていて、三つ目の Turnstile がロックしている](https://img.leeguoo.com/media/959571a6-2a9f-4bce-a389-1554a98c46d3/turnstile-wall.png)

だから結論はかなり直感に反します。回避はできないので、「中に入る」しかありません。ブラウザでしか生成できないものを偽造するより、本物のブラウザを直接操作するほうがよいのです。

## 解決策：自分がログイン済みの Chrome を駆動する

web バックエンドは [`chrome-use`](https://github.com/leeguooooo/chrome-use)（Chrome 拡張付きのブラウザ自動化 CLI）を通じて、すでに chatgpt.com にログインしている本物の Chrome に接続し、通常の会話内で画像を生成します。手動で app に入力して「一枚描いて」と頼むのと、同じ画面、同じ cookie、同じ Turnstile コンテキストです。

全体の流れ：

```
chatgpt-imagegen --backend web
   │
   ├── chrome-use がログイン済みの Chrome に接続し、https://chatgpt.com/ を開く
   │     （通常の会話である必要があります。Temporary Chat では画像生成ツールが無効になります）
   │
   ├── ChatGPT プロジェクトを解決する（--project、デフォルトは imagegen）
   │     ページ内 fetch でプロジェクト一覧を取得；なければ POST /backend-api/projects で作成
   │     画像生成用の会話はこのプロジェクトにアーカイブし、メイン履歴を汚さない
   │
   ├── 本物のキーボードイベントでプロンプトを入力欄に打ち込む
   │     ChatGPT の ProseMirror/React 入力欄は単純な DOM の .value= / fill を認識しないため、
   │     逐キー入力をシミュレートする必要がある。そうしないと空のまま送信される
   │
   ├── ページをポーリング：ストリーミング出力が終わり、かつ新しい <img> リソースが安定するまで待つ
   │
   └── ページ内でその画像のバイト列を fetch（credentials:'include'）→ base64 → ファイル保存
         （署名付きの estuary/content URL はブラウザ自身の cookie で認可され、token はブラウザの外に出ない）
```

いくつかの細部は、実際に踏んでわかったものです。

ProseMirror の入力欄は、直接 `value` を設定したり、自動化ツールの `fill` を使ったりしても効きません。React がそれをユーザー入力として扱わないため、本物のキーボードイベントを送るしかありません。

「画像ができた」と判断するには、ストリーム終了を見るだけでは不十分です。会話の main コンテナ内に新しく現れた `<img>` リソースが安定し、URL が変わらなくなるまで待つ必要があります。そうしないと、プレースホルダー画像や前回の画像を拾ってしまいます。

画像のバイト列も外側から `curl` しません。その画像 URL は署名付きで、ダウンロードには cookie が必要なので、ページ内で `fetch(..., {credentials:'include'})` し、ブラウザ自身のセッションで認可させます。token は最初から最後までブラウザの外に出ません。

## 避けて通れないエンジニアリング上の落とし穴

「動く」から「安定して動く」にするまでの間にある、これらは実際に踏んで得た知見です。

**web バックエンドの並行数は 1 にするしかありません。** 同じログイン済み Chrome を共有するため、初期の並行画像生成では画像が混線していました（[#7](https://github.com/leeguooooo/chatgpt-imagegen/issues/7)、v0.6.0 で修正し、検出対象をその会話の main コンテナ内に限定）。さらに chatgpt.com 側のレート制限もかなり厳しいです（"Too many requests… temporarily limited access to your conversations"）。そのため web はプロセスをまたいで直列化し、複数 fire されたプロセスは flock のスロットで待ちます。安全ですが、実時間はほぼ直列合計になります。本当に並列化したい（最大 4）なら明示的に `--backend codex` を使います。その代わり Codex の利用枠を消費します。これは枠を節約するか、画像生成を速くするかのトレードオフであり、ツールが勝手に決めるものではありません。`--backend`、またはデフォルトの `auto` に従います。

**レート制限は fail fast すべきで、黙ってリトライしてはいけません。** ページに "Too many requests" が表示されたら、web バックエンドはそのポップアップを検出して即座にエラーにします。送信前にぶつかった場合、`auto` モードでは codex にフォールバックします。送信後なら、きれいに停止し、重複して課金されるようなことはしません。その画像は後から会話に表示される可能性があるので、自分で確認してください。

**デフォルトでは履歴を残しません。** 画像生成の会話はデフォルトで `PATCH is_visible:false` により削除されます。プロジェクト内に一時的に入れて受け渡しするだけで、実行後に ChatGPT の履歴には残りません（`--keep-conversation` で保持できます）。

**画像から画像への生成も同じ流れです。** `-i/--ref` は参考画像を ChatGPT の入力欄に渡してから編集プロンプトを送ります。手動で画像をドラッグして、それを変更させるのと同じ仕組みです。必要なのはこれまでどおりサブスクリプションで、key は不要です。

## 2つの新機能：スタイルプリセット + ドキュメントへの能動的な図版追加

スタイルプリセットは、再利用できるプロンプト断片です。名前を付けて保存し、1つの引数で適用できます。

```bash
chatgpt-imagegen "a robot mascot" --style doodle
chatgpt-imagegen style add brand "flat vector, bold shapes, white bg"
chatgpt-imagegen style use brand        # デフォルトに設定し、以後毎回自動で適用
```

組み込みで `doodle` スタイルが1つ入っています。わざとかなり下手に、昔のペイントソフトでマウスをこすって描いたような感じにしてあります。このリポジトリの README にある「ブサかわ」系の挿絵（この記事の数枚も含む）は、このスタイルを使って自分で生成したものです。初期状態ではデフォルトスタイルはありません。明示的に使わなければ、以前と同じ動作です。

能動的な図版追加は、AI agent 向けです。skill としてインストールすると、agent がブログ、技術提案、設計ドキュメントを書くときに、自分から図版を提案し、バックグラウンドで並行生成します。あなたが「画像がほしい」と言うのを待ちません。並行度はバックエンド設定によって変わります。`web` はクォータ節約のため直列、`codex` はクォータを消費して並列です。

## 2つのバックエンドをどう選ぶか

| シーン | 使うバックエンド | 理由 |
| --- | --- | --- |
| ノートPC/デスクトップで、Chrome を開いていてログイン済み | **web**（デフォルト） | Codex のクォータを消費しない。無料アカウントでも使える |
| サーバー / ヘッドレスな agent マシン | **codex** | そこにはブラウザがないので、`auto` が自動でフォールバックする |
| 本当に並列でまとめて画像生成したい | codex | web は直列、codex は最大4並列。ただしクォータを消費する |

デフォルトの `auto` は、まず web を試し、だめなら codex にフォールバックします。つまりデフォルトで Codex のクォータを節約してくれます。

## これを使わず、公式 API に直接行くべきとき

サブスクリプション経路は API の無料版ではなく、別のプロダクト形態であり、独自の境界があります。

厳密に `quality=high` が必要な場合や透明背景が必要な場合、サブスクリプションでは対応できないため、`OPENAI_API_KEY` を使って `/v1/images/generations` を呼ぶ必要があります。

外部向けの本番サービスで、個人サブスクリプションを使ってエンドユーザー向けに画像生成するのは [OpenAI の規約](https://openai.com/policies/row-terms-of-use/) に違反しますし、自分が ChatGPT で使う分の上限も使い切ってしまいます。もう一点、このツールは未公開の内部エンドポイントに乗っているため、大規模に濫用すると、その入口が最速で塞がれる原因になります。塞がれたら全員が使えなくなります。

安定して 10 枚/分を超える生成が必要なら、サブスクリプションのレート制限は API より厳しいです。

チーム向けで、リモートから呼び出せる HTTP ゲートウェイが必要な場合は、姉妹プロジェクト [agent-cli-to-api](https://github.com/leeguooooo/agent-cli-to-api) を使い、同じサブスクリプションを OpenAI 互換インターフェイスとして公開してください。

## 上級者向け

```bash
# chrome-use をインストール（web バックエンド用）。chatgpt.com にログイン済みの Chrome に接続
curl -fsSL https://raw.githubusercontent.com/leeguooooo/chrome-use/main/install.sh | sh
chrome-use extension install   # その後 Chrome 拡張を入れて、再起動し、chatgpt.com にログイン

# CLI をインストール（agent 用。いちばん手軽）
npx skills add leeguooooo/chatgpt-imagegen -g

# または単体で使う
git clone https://github.com/leeguooooo/chatgpt-imagegen
./chatgpt-imagegen "a watercolor cat on a windowsill" -o cat.png
```

chrome-use を入れていなくても問題ありません。`auto` は自動で codex にフォールバックし、stderr に「chrome-use を入れると Codex の枠を消費せずに画像を出せます」と一言だけ表示します。

## よくある質問

**アカウント停止される？** 可能性は低いですが、レッドラインはあります。web バックエンドは、自分がログイン済みのブラウザを操作して、手動でも行うことを実行するだけなので、トラフィックはアプリ内で数回クリックするのと変わりません。codex バックエンドは本物の auth token で Codex CLI プロトコルを再生するため、通常の Codex 利用に見えます。本当にリスクがあるのは 2 つです。1 つ目は量です。継続的に 10 枚/分を超える、または一度に数十枚の大きな fan-out を行うとレート制限に当たり、長期的に強引に回し続けると目を付けられやすくなります。2 つ目は、個人サブスクリプションで外部向けの画像生成サービスを提供することです。これは明確に規約違反のレッドラインです。ツールはデフォルトでフットプリントを抑えています。画像生成の会話はデフォルトで削除、プロジェクトにまとめる、レート制限ポップアップに当たったら fail-fast で再試行しない、並行数に上限あり。個人のローカル利用で通常の量ならリスクは低いですが、非公開エンドポイントに乗っているものなので自己責任です。濫用しないでください。

**chrome-use は token をかなり浪費する？** このツールに関しては、画像生成の過程で LLM token は一切消費しません。web バックエンドは、AI に画面を見せながらブラウザを一歩ずつ操作させているわけではなく、固定の Python スクリプトが決め打ちの手順で chrome-use を呼び出しているだけで、その途中にモデル推論はありません。本当に token を消費するのは、スクリーンショット駆動で、各ステップを大モデルに渡すやり方です。chrome-use 自体はむしろその逆で、アクセシビリティツリーのスナップショットとコンパクトな `@eN` 参照を使うため、1 回あたり約 200〜400 token で済み、agent 用としても生の HTML やスクリーンショットを投げるよりずっと節約できます。

## 最後に

codex バックエンドは公式プロトコルをリプレイする方式で、web バックエンドは本物のブラウザ内で処理を実行する方式です。後者は遠回りですが、その代わりに 3 つの利点があります。API key が不要、Codex の利用枠を消費しない、無料アカウントでも使えることです。難所は Cloudflare のエッジではなく、本物のブラウザでしか生成できず、しかも 1 回使うと無効になる Turnstile token です。この点を理解すれば、方針は「偽造」ではなく「中で直接操作する」になります。

- GitHub: [leeguooooo/chatgpt-imagegen](https://github.com/leeguooooo/chatgpt-imagegen)
- HTTP ゲートウェイの姉妹プロジェクト: [agent-cli-to-api](https://github.com/leeguooooo/agent-cli-to-api)
- skill のインストール: `npx skills add leeguooooo/chatgpt-imagegen -g`

免責事項: 本ツールは ChatGPT 内部の `backend-api` エンドポイント（Codex CLI が使っているものと同じ）を呼び出すもので、ドキュメントで保証された公開 API ではありません。OpenAI はいつでも変更または制限を行う可能性があります。[OpenAI サービス利用規約](https://openai.com/policies/row-terms-of-use/)で許可される範囲内で、個人利用または agent のローカル利用に限って使用し、外部向けの商用画像生成サービスとして提供しないでください。
