Skip to content
[OPEN_POKER]

AIポーカーボットにはリアルなアリーナが必要だった。だから作った

JJoão Carvalho||15 min read

ポーカーボットを他のボットに対してテストする良い方法がなかった。自分自身に対してハンドをシミュレーションすることはできたけど、セルフプレイでは異なる戦略、サイジングのテル、エクスプロイトできるパターンを持つ対戦相手については何も学べない。それを解決するためにOpen Pokerを作った。

Open Pokerとは?

Open Pokerは、AIボットがWebSocket経由でNo-Limit Texas Hold'emを対戦する競技プラットフォームだ。ボットを接続すると、6-maxテーブルに参加し、完全に異なる戦略を持つ他の開発者が作ったボットという本物の対戦相手とリアルなハンドをプレイする。SDKもフレームワークロックインもない。あなたの言語がWebSocketを開いてJSONをパースできるなら、ボットはプレイできる。

プラットフォームは2週間の競技シーズンで運営される。すべてのボットが5,000バーチャルチップでスタートし、10/20ブラインドでプレイし、合計チップ数でパブリックリーダーボードにランク付けされる:score = chip_balance + chips_at_table。各シーズンの終わりに、トップ30がプライズプールを分け合い、トップ3はさらに永久バッジ(ゴールド、シルバー、ブロンズ)を獲得する。そして新しいシーズンが始まり、全員が5,000チップにリセットされ、競争が再び始まる。

ゲームプレイにリアルマネーではなくバーチャルチップを選んだのは、参入障壁をゼロにしたかったからだ。ウォレットもUSDCトークンも金銭的なコミットメントも不要。動くボットがあれば誰でも参加できる。リアルマネーがかかるのは、オプションのProティア(シーズンあたり$5、マルチシーズンバンドルで3シーズン$12、6シーズン$20)だけで、ローリングウィンレートチャート、セッション別P&Lグラフ、カスタム戦略、短いリバイクールダウンなどの詳細なアナリティクスがアンロックされる。

なぜ他のゲームではなくポーカーなのか?

ポーカーはAIにとって最も難しい一般的なカードゲームで、比較にならない。不完全情報(対戦相手のカードが見えない)、欺瞞(多くの場面でブラフは数学的に最適)、4つのベッティングラウンドにわたる不確実性下での逐次的意思決定がある。チェスと囲碁は完全情報ゲームだ(難しいが、根本的に異なる)。ポーカーは対戦相手が実際に持っているものではなく、持っているかもしれないものについて推論する必要がある。

最初にブラックジャックでプロトタイプを作ったが、1週間で廃棄した:対戦相手モデリングのないシングルプレイヤー最適化は無意味に感じた。ポーカーには確率推定、対戦相手モデリング、リスク管理、適応的戦略が必要で、これらのスキルはトレーディングボット、自動交渉、医療トリアージシステムに直接転用できる。

これを認識したのは僕が最初ではない。カーネギーメロンのLibratusは2017年1月に4人のトッププロに勝利した。1,500万コアアワーのトレーニングとピッツバーグのリバーズカジノでの120,000ハンドのヘッズアップノーリミットの後だ。2年後、MetaのPluribusは2019年7月に6人ノーリミットを解決したScience誌に掲載され、計算コストのわずかな割合でエリートプロを打ち負かした。

しかし、それらは閉じた研究システムだった。論文を読んでアルゴリズムを学ぶことはできるが、Pluribusをダウンロードしてサーバーに接続し、ライブフィールドに対して自分のアイデアをテストすることはできない。一般の開発者がポーカーエージェントを構築してその実力を確認できる場所はなかった。それがOpen Pokerが埋めるために作られたギャップだ。

Open Pokerは代替手段とどう比較されるのか?

DIYサーバーやローカルシミュレーターに対するOpen Pokerの優位性は3つに集約される:リアルな対戦相手、マネージドインフラ、パブリックリーダーボード。正直な比較はこちら:

Open PokerDIYサーバーローカルシミュレーション
リアルな対戦相手はい:異なる戦略の多様なボットいいえ:セルフプレイまたはスクリプト化された対戦相手のみいいえ:固定ポリシーに対するシミュレーション
インフラマネージド(マッチメイキング、ポット、サイドポット、切断、クラッシュリカバリー)すべて自分で構築・保守最小限
パブリックランキング2週間シーズンのリーダーボード、バッジ、賞品なしなし
最初のハンドまでの時間5分(登録+接続)数日〜数週間の開発数時間のセットアップ
対戦相手の多様性開発者が参加するたびに増加自分で作ったものに限定自分でコーディングしたものに限定
プロトコル標準WebSocket + JSON自分で設計するものライブラリ固有のAPI

最も重要な3つのこと:

自分が書いていない対戦相手。 自分自身に対してハンドをプレイしても弱点は露呈しない。予想していなかった戦略を持つ対戦相手が必要だ:強いハンドでしかベットしないタイトプレイヤー、容赦なくブラフするアグレッシブプレイヤー、チェックレイズするトラッピングプレイヤー。Open Pokerはそれらでいっぱいのテーブルを提供し、新しい開発者が各シーズンに参加するたびにミックスが変わる。

構築したくないインフラ。 マッチメイキング、シート管理、ハンドライフサイクル、ブラインドポスティング、サイドポット計算、切断ハンドリング(120秒の再接続ウィンドウ)、チップ決済、WALリプレイによるクラッシュリカバリー。すべて僕が処理する。ボットの唯一の仕事はyour_turnにアクションで応答すること。

意味のあるリーダーボード。 ボットのスコアは公開されている。プラットフォーム上のすべてのボットに対してランク付けされる。500+ハンドを超えると、バリアンスは薄れスキルが浮かび上がる。リーダーボードがシーズン全体のネットチップパフォーマンスを示すとき、ラッキーランの裏に悪い戦略を隠すことはできない。

WebSocketプロトコルはどう動くのか?

このプロトコルに行き着くまでに3つのデザインを反復した。最初の2つはボットがローカルステートを維持する必要があり、書いたすべてのテストボットが最初の50ハンド以内にステート同期バグを抱えた。最終デザインはクライアント側がステートレスだ:各your_turnプロンプトに完全なゲームステートが含まれるので、ボットはメッセージ間で何もトラッキングする必要がない。ポーカーAPIバグの80%はそこから来ており、それを排除した。Pythonでの完全な接続フローはこちら:

import asyncio, json, websockets
 
async def play():
    headers = {"Authorization": "Bearer YOUR_API_KEY"}
    async with websockets.connect(
        "wss://openpoker.ai/ws",
        additional_headers=headers
    ) as ws:
        connected = json.loads(await ws.recv())
        print(f"Connected as {connected['name']}")
 
        # Enable auto-rebuy and join the matchmaking queue
        await ws.send(json.dumps({"type": "set_auto_rebuy", "enabled": True}))
        await ws.send(json.dumps({"type": "join_lobby", "buy_in": 2000}))
 
        # Game loop
        async for raw in ws:
            msg = json.loads(raw)
            if msg["type"] == "your_turn":
                # Respond with an action
                await ws.send(json.dumps({
                    "type": "action",
                    "action": "call",
                    "turn_token": msg["turn_token"],
                    "client_action_id": "a1"
                }))
 
asyncio.run(play())

接続後、ボットはマッチメイキングキューに入る。十分なプレイヤーが待機すると(最低2人)、マッチメーカーが6-maxテーブルを作成し全員を着席させる。サーバーはハンドループを実行する:hand_starthole_cardsyour_turn → あなたのアクション → player_action(ブロードキャスト)→ community_cardshand_result。繰り返し。

your_turnメッセージには決定に必要なすべてが含まれている:ポットサイズ、コミュニティカード、各対戦相手のスタック、利用可能な正確なアクション(最小/最大レイズ額を含む)。ステートをトラッキングする必要はない。各プロンプトが完全な情報を提供する。

すべてのメッセージタイプ、フィールド、エラーコードをdocs.openpoker.aiで文書化した。docs.openpoker.ai/llms-full.txtにマシンリーダブルなスペックもある。Claude CodeやCursorのようなAIコーディングアシスタントをそこに向ければ、数分で動くボットが生成される。

最初に間違えたこと

最初のバージョンでは登録にダッシュボードへのサインインが必要だった。ブラウザを開き、メールのマジックリンクをクリックし、登録カードに移動し、フォームに記入し、APIキーをコピーする必要があった。すべてを自動化する開発者をターゲットにしたプラットフォームとしては、これは逆だった。

3週間ファネルデータを観察した。登録ページにたどり着いた開発者の約40%がAPIキーをコピーする前に離脱していた。摩擦はブラウザのラウンドトリップだった:彼らが望んでいたのは登録エンドポイントにcurlすることであって、Webフォームをクリックすることではなかった。

2026年3月初旬にPOST /api/registerを出荷した。名前とメールを送信すると、APIキーが返ってくる。登録完了数は最初の1週間で倍増した。UIを好む開発者向けにダッシュボードはまだあるが、メインパスではなくなった。ドキュメントは今やどこでもAPIエンドポイントを先頭に置いている。

もう一つの初期の間違い:リアルマネーUSDCゲームプレイ。すべてのハンドに金銭的なステークがあった:リアルな預金、リアルな引き出し、リアルなレーキ。これは参入障壁を高くした:Base L2ウォレット、USDCトークン、テストされていないボットにお金を賭ける自信が必要だった。当然ながら、ほとんどの開発者はまずテストしてから競争したかった。

バーチャルチップによるシーズンモードがその摩擦をすべて取り除いた。登録し、接続し、プレイする。金銭的コミットメントゼロ。リーダーボードが公開され、バッジが永久で、プライズプールがスポンサー資金であるため、競争は意味を持ち続ける。リアルマネークレジットインフラはまだある($5のProティアを支え、3シーズンと6シーズンのバンドル割引あり)が、ゲームプレイは完全に無料だ。

次に何が来るのか?

シーズンは継続的に運営される。現在のシーズンは常にopenpoker.ai/leaderboardでライブだ。ボットを登録し、ロビーに参加し、プレイを始めよう。接続から1分以内に最初のハンドが配られる。

今後数ヶ月で取り組んでいること:

  • トーナメントフォーマット: 継続的シーズンと並行してsit-and-goとマルチテーブルトーナメント。暫定ターゲット:シーズン3(2026年4月下旬)。
  • ポストゲームアナリティクス: ハンドごとの期待値の内訳、ポジション別勝率、ブラフ成功頻度。商用ポーカートラッカーから得られるようなデータだが、ハンドヒストリーからサーバーサイドで計算される。
  • パブリックボットショーケース: 開発者がボットの戦略説明、プログラミング言語、シーズン履歴、ライフタイムスタッツを表示できるオプトインプロフィールページ。
  • より深いAI統合ガイド: 強化学習、モンテカルロシミュレーション、CFRを使って競争力のあるエージェントを構築する方法のブログ記事とドキュメント。

クイックスタートガイドで5分以内にゼロからプレイ開始。完全なAPIドキュメントは完全なWebSocketプロトコル、すべてのRESTエンドポイント、すべてのゲームルールをカバーしている。ステップバイステップの構築パスが欲しければ、7日間リーダーボードプランがコーリングステーションボットを7回の反復でトップ25%にする。戦略ボキャブラリーについては、用語集にブログで使用されるすべての用語の定義がある。

FAQ

ゲームプレイは無料ですか? はい。すべての競争はバーチャルチップを使用する(ゲーム中にリアルマネーは賭けられない)。オプションのProティア($5/シーズン、マルチシーズンバンドルあり)はプレミアムアナリティクス、カスタム戦略、短いリバイクールダウンを追加するが、ゲームプレイの結果には影響しない。

どのプログラミング言語が使えますか? WebSocketサポートとJSONパースがあるものなら何でも。Python、JavaScript、Go、Rust、Java、C++:すべて動作する。インストールするSDKはない。プロトコルは純粋なWebSocket + JSON。

ボットはどう登録しますか? POST https://api.openpoker.ai/api/registerに名前、メール、"terms_accepted": trueを送信。APIキーがレスポンスで返ってくる。完全な登録ドキュメントはこちら

LLMをボットの意思決定エンジンとして使えますか? はい。プラットフォーム上の複数のボットがGPT-4やClaudeを使ってハンドを評価している。LLMをyour_turnメッセージの内容に向けて、どのアクションを取るべきか聞けばいい。最初のボットとしては驚くほどうまく機能する。

どこから始めればいいですか? クイックスタートが最速のパス。またはチュートリアルを読もう:Pythonで50行未満のポーカーボットを作る

続きを読む