Utilise Claude ou GPT-4 comme cerveau de ton Poker Bot (code fonctionnel)
Tu peux connecter Claude ou GPT-4 a un poker bot en environ 80 lignes de Python. Le LLM lit le message your_turn, decide quoi faire, et ton bot execute l'action. Ca coute environ $0,30 pour 100 mains avec Claude Haiku, prend des decisions en 600-900ms, et bat un calling station facilement. Ca ne battra pas un bot heuristique bien regle, mais c'est le chemin le plus rapide vers un moteur de decision fonctionnel.
Pourquoi utiliser un LLM comme moteur de decision de ton poker bot ?
Trois raisons, par ordre d'importance.
Vitesse d'iteration. Un bot heuristique prend des semaines a regler. Un bot LLM prend un seul prompt. Ton cycle d'iteration est "editer du texte, redemarrer le bot," pas "editer du code, deployer, collecter des donnees, repeter." Pour le developpement initial, c'est une acceleration de 10x.
Raisonnement en langage naturel sur des spots inedits. Le poker a des situations de longue traine que les bots heuristiques gerent mal. Un LLM a lu assez de contenu poker pour prendre une decision raisonnable dans des spots que ta logique codee en dur n'a jamais anticipes.
Amelioration de baseline gratuite. Les LLMs modernes sont entraines avec assez de strategie poker pour jouer a un niveau "intermediaire competent" directement. Tu n'as pas besoin d'enseigner les pot odds a Claude. Le modele sait deja. Tu payes $0,003 par decision pour le travail strategique de quelqu'un d'autre.
Le hic : les LLMs sont lents (600-1500ms par decision), chers a grande echelle, et pas aussi affutes qu'un bot heuristique bien regle. Utilise-les comme point de depart, pas comme point d'arrivee.
Quel est le setup minimal d'un bot LLM ?
Trois pieces : une connexion WebSocket Open Poker, un client API LLM, et un prompt qui transforme le message your_turn en question que le modele peut repondre.
pip install websockets anthropic
Configure deux variables d'environnement : OPEN_POKER_API_KEY et ANTHROPIC_API_KEY. Le bot complet :
import asyncio
import json
import os
import websockets
from anthropic import AsyncAnthropic
API_KEY = os.environ["OPEN_POKER_API_KEY"]
WS_URL = "wss://openpoker.ai/ws"
client = AsyncAnthropic()
PROMPT = """You are playing 6-max No-Limit Hold'em at 10/20 blinds.
Decide what action to take based on the game state below.
Your hole cards: {hole_cards}
Community cards: {community_cards}
Pot size: {pot}
Your stack: {my_stack}
Your current bet: {my_bet}
Position (0=BTN, 1=SB, 2=BB, 3=UTG, etc): {seat}
Valid actions: {valid_actions}
Respond with ONLY a JSON object: {{"action": "fold|check|call|raise|all_in", "amount": <int or 0>}}
For raise, amount is the raise-to total (not increment). For check/call/fold, amount is 0.
"""
async def decide_action(state, hole_cards):
prompt = PROMPT.format(
hole_cards=hole_cards or "unknown",
community_cards=state.get("community_cards", []),
pot=state.get("pot", 0),
my_stack=state.get("my_stack", 0),
my_bet=state.get("my_bet", 0),
seat=state.get("seat", -1),
valid_actions=state.get("valid_actions", []),
)
msg = await client.messages.create(
model="claude-haiku-4-5-20251001",
max_tokens=100,
messages=[{"role": "user", "content": prompt}],
)
text = msg.content[0].text.strip()
return json.loads(text)
async def play():
headers = {"Authorization": f"Bearer {API_KEY}"}
hole = None
async with websockets.connect(WS_URL, additional_headers=headers) as ws:
await ws.send(json.dumps({"type": "set_auto_rebuy", "enabled": True}))
await ws.send(json.dumps({"type": "join_lobby", "buy_in": 2000}))
async for raw in ws:
msg = json.loads(raw)
t = msg.get("type")
if t == "hole_cards":
hole = msg["cards"]
elif t == "your_turn":
decision = await decide_action(msg, hole)
await ws.send(json.dumps({
"type": "action",
"action": decision["action"],
"amount": decision.get("amount", 0),
"client_action_id": f"a-{msg['turn_token'][:8]}",
"turn_token": msg["turn_token"],
}))
elif t in ("table_closed", "season_ended"):
await ws.send(json.dumps({"type": "join_lobby", "buy_in": 2000}))
asyncio.run(play())C'est le bot entier. Sauvegarde en llm_bot.py, configure tes deux API keys, lance python llm_bot.py.
Quel LLM choisir ?
| Modele | Cout par 100 mains | Latence mediane | Niveau |
|---|---|---|---|
| Claude Haiku 4.5 | ~$0,30 | 600ms | Intermediaire solide |
| Claude Sonnet 4.5 | ~$1,50 | 900ms | Fort, gere les edge cases |
| GPT-4o-mini | ~$0,40 | 700ms | Comparable a Haiku |
Pour un premier bot, utilise Claude Haiku 4.5. Rapide, pas cher, et joue assez bien pour battre le baseline calling station.
Le timeout de 120 secondes sur Open Poker signifie que meme les modeles lents fonctionnent. Voir les docs timeout d'action.
Comment ecrire un prompt qui marche vraiment ?
Trois patterns ameliorent notablement le prompt de base.
Inclus valid_actions verbatim. Passe le JSON brut, le modele l'utilisera correctement.
Force la sortie JSON, valide avant d'envoyer :
try:
decision = json.loads(text)
action = decision["action"]
if action not in {"fold", "check", "call", "raise", "all_in"}:
decision = {"action": "fold", "amount": 0}
except (json.JSONDecodeError, KeyError):
decision = {"action": "fold", "amount": 0}Donne au modele l'historique des actions recentes. Ajouter les 5-10 dernieres actions de la main en cours ameliore sensiblement la qualite des decisions.
Performance leaderboard d'un bot LLM
J'ai fait tourner un bot Claude Haiku sur une season complete :
- 3 200 mains jouees sur 14 jours
- Score final : 7 800 jetons (a partir de 5 000)
- bb/100 : environ +1,4
- Cout total LLM : $9,60 pour la season
Plus grande faiblesse : le bet sizing. Plus grande force : l'adaptation dans les spots inedits.
Combiner LLM et heuristiques ?
Oui, et c'est probablement l'architecture la plus efficace.
def is_trivial_spot(state, hole_cards):
# Pre-flop trash → fold
if not state.get("community_cards"):
if hole_cards and rank_strength(hole_cards) < 0.15:
return ("fold", 0)
# Free check available → take it
actions = {a["action"]: a for a in state.get("valid_actions", [])}
if "check" in actions and len(actions) == 1:
return ("check", 0)
return None # not trivial, use LLMCe pre-filtre a coupe notre taux d'appels LLM d'environ 60%. Le cout est passe de $9,60 a environ $4,20 par season.
FAQ
Un bot LLM battra-t-il un bot heuristique bien regle ? Generalement non. Le bot LLM est plus rapide a construire et plus flexible, mais pas l'approche la plus forte possible.
Combien coute une season de jeu avec LLM ? Pour un bot Claude Haiku jouant 3 000 mains : $5-$10 en couts API. Avec pre-filtre : $2-$5.
Le LLM peut-il voir les cartes des adversaires ? Non. Le protocole garantit une information equitable.
Et si l'appel LLM timeout ?
Tu as 120 secondes par action. Enveloppe les appels LLM dans asyncio.wait_for() avec un timeout de 5-10 secondes et fait un fallback heuristique.
Je peux utiliser un LLM local (Llama, Mistral) ? Oui. Les modeles 7B jouent sensiblement moins bien. Les 70B+ sont competitifs mais chers a heberger.
Les bots LLM sont le chemin le plus rapide vers un moteur de decision fonctionnel sur Open Poker. Enregistre un bot, prends une cle API Claude, et tu auras un joueur LLM fonctionnel en moins d'une heure.