🦙 Cloudflare OSをVRAM 8GBのゲーミングPCで動かしたら、三目並べ1個に5ラウンドかかった話

🔗 元記事 (Zenn) 🔖 はてブ 📅 2026-08-11 👥 22 users ✍️ 灯里(akari)

📋 記事の概要

2026年8月にCloudflareがオープンソース化した「Cloudflare OS」を、VRAM 8GBの一般的なゲーミングPC(RTX 5060)でローカル動作させ、ローカルLLM(Ollama + Qwen3)に三目並べゲームを作らせるまでの実測付き奮闘記です。

結論から言うと動いたものの、「三目並べを作って」の一言から遊べるものが出てくるまでに5ラウンド・約16,000トークン・1時間半を要しました。5回の失敗がすべて違う理由で発生し、Cloudflare OSの設計思想が失敗するたびに浮き彫りになっていくという、非常に面白く実践的な技術レポートです。

🔍 検証環境

項目内容
GPURTX 5060(VRAM 8GB)— ゲーミング用途で組んだPC
RAM32GB
OSWindows 11
Node.js24.13.0 / pnpm 11.15.1
Cloudflare OS2026年8月リリース(v2、早期アクセス版、Apache-2.0)
モデルOllama + Qwen3:8b → 途中から Qwen3:30b-a3b

🏗️ Cloudflare OSとは

Cloudflare社内で数千人が使っているAIエージェント環境をオープンソース化したもの。ドキュメント作成、アプリ開発、業務自動化を自社のCloudflareアカウント(またはローカル)にデプロイできる。2つのコア概念がある:

⚠️ Windows環境での問題

READMEでは pnpm run-local の一行で動くと書かれているが、Windowsでは spawnSync pnpm ENOENT で落ちる。原因はスクリプトが pnpm を直接spawnしているが、Windowsの実体は pnpm.cmd のため。

修正方法: 該当3ファイルで execFileSync("pnpm", ...)shell: process.platform === "win32" を追加するだけ。または手動で pnpm install → ビルド → node run-dev-server.js を実行。

ローカル版は http://localhost:8787 で立ち上がり、wrangler と workerd 上で動くため Cloudflare アカウントとは一切繋がらない。デフォルト認証は admin ユーザーのみ(ローカル専用)。

💡 興味深い発見: 起動ログに Wrangler detected this dev session is running in an AI agent. と出力され、KVやD1やDurable ObjectをHTTPで覗けるAPIが勝手に生える。「AIエージェント向けの導線が標準で用意されている時代」になったと筆者が感嘆。

🔌 モデルの接続

Cloudflare OSが対応するプロバイダは5種類:anthropic / openai / google(各社APIキー)、cloudflare(Workers AI)、そして ollama(API URLを自由指定)。ollama は実質「任意のOpenAI互換エンドポイント」を接続できる口になっている。

UIから qwen3:8b をOllama接続で登録。コスト表示は $0のまま。トークン消費や制限を気にしなくて良いのは財布とメンタルに良い。

なぜQwen3を選んだか

💻 実効リソースの罠

「RAM 32GBだから大丈夫」「VRAM 8GBだから8Bモデルいける」と思うが、実際は違う。

リソース公称実効(デスクトップ常駐分を引く)
RAM空き31.9GB約16GB(Edge 2.5GB, Chrome 2.0GB, VS Code 1.2GB, Memory Compression 5.0GB等)
VRAM空き8151 MiB約6.6GB(24個のGPUプロセスが1GB強を常時占有)

⚠️ 重要: ベンチマークは「全部閉じた状態」で測られるが、実際の作業はSlackやChromeを開きながら行われる。LLM用途ではGPUの世代や型番ではなくVRAMのGB数だけ見ればいい。5060の8GBと4060の8GBは、載るか載らないかではほぼ同じ振る舞い。

💣 最大の罠:デフォルト4096トークン

30b-a3bにモデル変更後、以下のような症状が現れた:

Ollamaサーバーログに決定的な一行:slot context shift, n_keep = 4, n_left = 4091, n_discard = 2045

⚠️ Ollamaのデフォルトコンテキスト長はVRAM量で決まる: 23GiB以上で32K、47GiB以上で256K、それ未満は4096。VRAM 8GB環境では当然4096。

Cloudflare OSのシステムプロンプト(ツール定義込み)は4千トークン級 → 会話開始時点でコンテキストが溢れ、システムプロンプトが丸ごと切り捨てられていたn_keep = 4(先頭4トークンのみ保護)は実質何も守っていない。

対処: setx OLLAMA_CONTEXT_LENGTH 16384(公式は64K以上推奨だが8GB環境では16Kが現実的)。

副作用: qwen3:8bのメモリ使用量が5.2GB→7.8GBに増加(KVキャッシュサイズ直結)。実効6.6GBに収まらず、CPU 27% / GPU 73%の混合実行に落ちた。

この「エラーも警告も出ずに黙ってトークンを捨てて動き続ける」挙動はローカルならではの罠。フロンティアAPIならコンテキスト超過でエラーで蹴られるので嫌でも気付ける。

🎮 三目並べ5ラウンドの記録

Rこちらが渡した情報結果
1「三目並べ作って」binding名をブラウザのグローバル変数として参照 → ReferenceError
2「このエラーが出てる」fetchでHTTPを叩く方式に変更 → CSPで全遮断
3「CSPで塞がれてる」CORSの問題と誤診して無限ループ → 手動停止
4Gadget RPCスタブの存在を明示クラス名を独自命名 → メソッドが見つからない
5完全なスケルトンを渡す✅ 完走

各ラウンドの詳細

ラウンド1: client.js(ブラウザ側)でサーバー側のbinding名をグローバル変数として参照。サーバーとクライアントの境界を混同。

ラウンド2: fetchでHTTPエンドポイントを叩く方式に書き換えるが、Gadgetのiframeには connect-src 'none' が効いていて fetch/XHR/WebSocket すべて不通。Gadgetは外の世界と直接喋れず、binding(Gatekeeper)経由のみ。

ラウンド3(山場): CSP違反をCORS問題と誤診し、Access-Control-Allow-Origin を延々と追加し続ける無限ループ。直らないので位置を変えてまた追加…10分眺めてから手動Stop。

ラウンド4: gadget グローバル変数と await gadget.method() のRPC方式を明示したが、クラス名を TIC_TAC_TOE と独自命名。Cloudflare OSではクラス名は Gadget 固定(筆者の伝え漏れが原因)。

ラウンド5: 完全なスケルトンコードを渡すと、正確に写経して完走。Durable ObjectでRPC経由のゲーム状態管理が動作。

🚫 なぜエージェントが止まれなかったのか

エージェントのターン停止判定(packages/workshop-backend/src/agent.tsshouldStopAfterTurn)は以下4条件のみ:

  1. 人間がStopを押した
  2. ターン数が30に達した
  3. 外部リソースの接続承認待ち
  4. 副作用のある操作の承認待ち

「失敗が繰り返されている」という概念が一つも入っていない。エージェント側から「詰まりました」と言う手段(giveUpツール)は、コールバック起点時のみ登録されるため、通常チャットでは使えない。

🔑 Gatekeeperの矛盾: 副作用は非同期化されているのに、失敗は同期的な人間の監視に依存したまま。「コーヒーを取りに行っていい」のに、その間誰がStopを押すのか。部品自体は揃っており、shouldStopAfterTurn に「直近N回のエラーが同種なら停止」を足すだけで解決する(難易度ではなく優先順位の問題)。

プロンプトで「2回失敗したら聞いて」と指示しても無理。失敗回数を数える主体がループ内の本人になるため。数える主体はループの外(ハーネス)にいる必要がある。

🤔 なぜ常識が全部裏目に出るのか

5ラウンドの失敗は全部「余計なことをした」。正解は毎回、書いたものより小さかった。

一般的なWeb開発の常識(fetchできる、localStorageがある、好きなクラス名を選べる、CORSで解決できる)をCloudflare OSは全部持っていない。「持たせない、渡さない、迂回させない」という設計思想(Unix哲学の「最小限で、余計なことをさせない」と同じ形)。

💡 実践的アドバイス: Cloudflare OSで開発させるなら、スケルトンと禁止事項を最初からプロンプトに持たせるべき。ラウンド5のスケルトンをラウンド1で渡していれば1ラウンドで終わっていたはず。

📝 まとめ(要点)

💭 著者の所感

「弱いモデルで通る設計は、強いモデルでも通る。逆は成り立たない」という非対称がある。フロンティアモデルの賢さは設計の粗を隠してしまう(一種の測定誤差)。

ローカルLLMの地味に大きな効能:CORS無限ループを従量課金環境で3ラウンド目で心が折れたが、ローカルなら電気代だけでニコニコ眺めていられた。「財布とトークンの忍耐力が無料になる」。

Cloudflare OS自体の評価は「もうこっとでいいんじゃないか」— ドキュメントもアプリも自動化も面倒なことの大半が完結する。ただし扱いこなすにはエンジニア要素が必要で、「安全である」と「作れる」は別の軸。