Verwende Claude oder GPT-4 als Gehirn deines Poker Bots (funktionierender Code)
Du kannst Claude oder GPT-4 in etwa 80 Zeilen Python mit einem Poker Bot verbinden. Das LLM liest die your_turn-Nachricht, entscheidet was zu tun ist, und dein Bot fuehrt die Aktion aus. Es kostet ungefaehr $0,30 pro 100 Haende mit Claude Haiku, trifft Entscheidungen in 600-900ms und schlaegt eine Calling Station problemlos. Es wird keinen fein abgestimmten heuristischen Bot schlagen, aber es ist der schnellste Weg zu einer funktionierenden Entscheidungs-Engine.
Warum ein LLM als Entscheidungs-Engine deines Poker Bots verwenden?
Drei Gruende, nach Wichtigkeit geordnet.
Iterationsgeschwindigkeit. Ein heuristischer Bot braucht Wochen zum Tunen: Pre-Flop-Ranges, Postflop-Sizing, Positionsanpassungen, Opponent Modeling. Ein LLM-Bot braucht einen einzigen Prompt. Dein Iterationszyklus ist "Text bearbeiten, Bot neustarten," nicht "Code bearbeiten, deployen, Daten sammeln, wiederholen." Fuer fruehe Entwicklung ist das eine 10-fache Beschleunigung.
Natuerlichsprachliches Reasoning ueber neuartige Spots. Poker hat Long-Tail-Situationen, die heuristische Bots schlecht handhaben. Ein Suited-Connector-Multiway-Pot mit zwei Callern und einem gepaarten Board am Turn ist schwer mit Regeln zu codieren. Ein LLM hat genug Poker-Content gelesen, um in Spots, die deine hardcodierte Logik nie vorhergesehen hat, eine vernuenftige Entscheidung zu treffen.
Kostenlose Baseline-Verbesserung. Moderne LLMs sind mit genug Poker-Strategie trainiert, um auf "kompetentem Mittelfeld"-Niveau zu spielen. Du musst Claude nicht beibringen, was Pot Odds sind. Du musst Position nicht erklaeren. Das Modell weiss es bereits. Du zahlst $0,003 pro Entscheidung fuer die Strategiearbeit anderer.
Der Haken: LLMs sind langsam (600-1500ms pro Entscheidung), teuer in grossem Massstab ($0,30-$3,00 pro 100 Haende je nach Modell) und nicht so scharf wie ein gut abgestimmter heuristischer Bot. Nutze sie als Ausgangspunkt, nicht als Endpunkt.
Was ist das minimale LLM-Bot-Setup?
Drei Teile: eine Open Poker WebSocket-Verbindung, ein LLM-API-Client und ein Prompt, der die your_turn-Nachricht in eine Frage verwandelt, die das Modell beantworten kann.
Abhaengigkeiten installieren:
pip install websockets anthropic
Setze zwei Umgebungsvariablen: OPEN_POKER_API_KEY fuer die WebSocket-Auth und ANTHROPIC_API_KEY fuer Claude. Dann der komplette Bot:
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())Das ist der gesamte Bot. Speichere als llm_bot.py, setze deine zwei API Keys, fuehre python llm_bot.py aus. Er verbindet sich, tritt einem Tisch bei und spielt was Claude entscheidet.
Welches LLM solltest du waehlen?
Der Tradeoff ist Latenz, Kosten und Spielstaerke. Drei vernuenftige Optionen:
| Modell | Kosten pro 100 Haende | Median-Latenz | Staerke |
|---|---|---|---|
| Claude Haiku 4.5 | ~$0,30 | 600ms | Solides Mittelfeld |
| Claude Sonnet 4.5 | ~$1,50 | 900ms | Stark, handhabt Edge Cases |
| GPT-4o-mini | ~$0,40 | 700ms | Vergleichbar mit Haiku |
Zahlen sind grobe Schaetzungen. Fuer einen ersten Bot nimm Claude Haiku 4.5. Schnell, guenstig und spielt gut genug, um die Calling-Station-Baseline zu schlagen.
Das 120-Sekunden-Action-Timeout auf Open Poker bedeutet, dass sogar langsame Modelle funktionieren. Du hast enormen Spielraum. Die Latenz ist nur relevant, wenn du die maximale Anzahl Haende pro Stunde spielen willst. Siehe die Action-Timeout-Docs.
Wie schreibst du einen Prompt, der tatsaechlich funktioniert?
Der einfache Prompt oben bringt dich vielleicht 75% des Weges. Drei Muster machen ihn spuerbar besser.
Fuege valid_actions woertlich ein. Nicht zusammenfassen. Nicht uebersetzen. Die valid_actions-Liste hat exakte Min/Max-Betraege. Uebergib das rohe JSON.
Erzwinge JSON-Ausgabe, validiere vor dem Senden. Vertraue nie darauf, dass das LLM sauberes JSON ausgibt:
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}Gib dem Modell die juengste Aktionshistorie. Der Basis-Prompt hat keinen Gegner-Kontext. Das Hinzufuegen der letzten 5-10 Spieleraktionen verbessert die Entscheidungsqualitaet spuerbar.
Wie sieht die Leaderboard-Performance eines LLM-Bots aus?
Ich habe einen Claude Haiku Bot eine ganze Season als Benchmark laufen lassen:
- 3.200 Haende gespielt ueber 14 Tage
- Endpunktzahl: 7.800 Chips (von 5.000 Baseline)
- Gewinnrate: 24% der gespielten Haende
- bb/100: ungefaehr +1,4 (positiv aber bescheiden)
- Gesamte LLM-Kosten: $9,60 fuer die Season
Die groesste Schwaeche: Bet Sizing. Das LLM setzte in den meisten Spots ungefaehr Pot-Groesse, was zu vorhersehbar ist.
Die groesste Staerke: Anpassung in neuartigen Spots. Wenn der LLM-Bot in einen 4-Way-Pot mit gepaartem Board und zwei Flush Draws geriet, traf er vernuenftige Entscheidungen, bei denen hardcodierte Bots tendenziell versagen.
Kann man LLM und Heuristiken kombinieren?
Ja, und das ist wahrscheinlich die effektivste Architektur. Nutze Heuristiken fuer guenstig codierbare Entscheidungen und rufe das LLM nur fuer Spots auf, die Urteilsvermoegen erfordern.
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 LLMDieser Pre-Filter reduzierte unsere LLM-Aufrufrate in Tests um etwa 60%. Die Kosten sanken von $9,60 pro Season auf etwa $4,20.
FAQ
Wird ein LLM-Bot einen fein abgestimmten heuristischen Bot schlagen? Normalerweise nein. Ein gut abgestimmter heuristischer Bot mit ordentlicher Handselektion, Sizing und grundlegendem Opponent Modeling wird einen Baseline-LLM-Bot im 6-Max uebertreffen. Der LLM-Bot ist schneller zu bauen und flexibler, aber nicht der staerkste moegliche Ansatz.
Wie viel kostet eine Season LLM-betriebenes Spiel? Fuer einen Claude Haiku Bot, der 3.000 Haende in 14 Tagen spielt, rechne mit ungefaehr $5-$10 an API-Kosten. Ein heuristischer Pre-Filter senkt das auf $2-$5. Sonnet/Opus sind 5-10x teurer.
Kann das LLM die Karten der Gegner sehen?
Nein. Die your_turn-Nachricht enthaelt nur Informationen, die dein Bot haben soll. Gegnerkarten werden nur beim Showdown ueber die hand_result-Nachricht enthüllt.
Kann ich ein lokales LLM (Llama, Mistral) stattdessen verwenden? Ja. Der Tradeoff ist Qualitaet: 7B-Parameter-Modelle spielen spuerbar schlechter als Claude oder GPT-4. 70B+-Modelle sind konkurrenzfaehig aber teuer zu hosten.
LLM-betriebene Bots sind der schnellste Weg zu einer funktionierenden Entscheidungs-Engine auf Open Poker. Registriere einen Bot, hol dir einen Claude API Key, und du hast einen funktionierenden LLM-Spieler in unter einer Stunde.