Arquitectura de software para bots de póker: guía práctica
El software de un bot de póker es un sistema de decisión basado en eventos, no una simple llamada a un modelo. Un bot fiable separa el protocolo, el estado de la mesa, la equity, la estrategia, los controles de riesgo y la telemetría. Así puedes probar la lógica de póker sin una mesa en vivo y sustituir una estrategia sin reescribir el cliente de red.
Conclusiones clave
- Mantén el código de transporte separado de las decisiones de póker.
- Trata el estado del servidor como fuente de verdad y aplica las actualizaciones de forma idempotente.
- Sitúa los controles de acciones legales y los timeouts fuera del modelo estratégico.
- Prueba en local, compara con un rival estable y después entra en una arena que permita bots.
¿Qué es el software de un bot de póker?
El software de un bot de póker lee el estado de la partida, elige una acción legal y la devuelve antes del límite de tiempo. El sistema completo incluye recuperación de la conexión, seguimiento de la mano, evaluación, estrategia, reglas de bankroll, logs y despliegue. Un modelo o un solver es solo un componente.
Este artículo aborda bots utilizados en investigación y en plataformas que permiten expresamente agentes autónomos. No es una guía para automatizar clientes de póker destinados a personas ni para eludir sistemas de integridad. Las principales salas prohíben ese uso y, al margen de las normas, el enfoque produce software frágil.
El modelo mental más claro es una tubería:
event -> normalized state -> features -> decision -> guardrails -> action -> telemetry
Cada flecha marca un límite que puedes probar. Si el bot intenta subir una cantidad ilegal, debes saber si falló el normalizador de estado, la estrategia o el validador de acciones. Si las seis tareas viven dentro de una única función decide(), todos los fallos parecen iguales.
¿Cuáles son las seis capas de la arquitectura de un bot de póker?
Un bot de póker listo para producción necesita seis capas: protocolo, estado, matemáticas, estrategia, controles y telemetría. Las dos primeras convierten los eventos en una mano comprensible; las dos intermedias eligen una acción; y las dos últimas impiden que un fallo termine la sesión.
| Capa | Posee | No debe poseer |
|---|---|---|
| Adaptador de protocolo | Autenticación, mensajes, reconexiones | Estrategia de póker |
| Almacén de estado | Mano, stacks, board, historial de acciones | Reintentos de red |
| Matemáticas del póker | Ranking de manos, pot odds, equity, rangos | Ejecución de apuestas |
| Política estratégica | Intención de fold, call o raise | Escrituras directas en el socket |
| Controles de seguridad | Acciones legales, límites de tamaño, plazo | Estadísticas del rival |
| Telemetría | Decisiones, latencia, resultados, errores | Mutación de decisión en vivo |
El límite más importante separa la intención estratégica de la acción ejecutable. Una estrategia puede indicar «subir medio bote». La capa de control debe traducir esa intención a una cantidad permitida por el mensaje actual. Así protege cualquier estrategia, ya se base en reglas, Monte Carlo, aprendizaje por refuerzo o llamadas a un LLM.
¿Cómo debería gestionar un motor de póker el estado de la mesa?
La capa de estado debe reconstruir el contexto de decisión a partir de eventos del servidor e ignorar los duplicados de forma segura. Debe seguir el ID de la mano, el token de turno, los asientos, los stacks, la calle, el board, el bote, el historial, las acciones legales y la posición del bot. La estrategia nunca debe interpretar mensajes sin procesar.
Usa un snapshot inmutable y pequeño para cada decisión. Es más fácil de probar que un objeto mutable de larga duración y evita que un evento tardío cambie los datos mientras se ejecuta una llamada al modelo.
from dataclasses import dataclass
from typing import Literal
Action = Literal["fold", "check", "call", "raise"]
@dataclass(frozen=True)
class DecisionContext:
hand_id: str
turn_token: str
street: str
hole_cards: tuple[str, str]
board: tuple[str, ...]
pot: float
stack: float
to_call: float
min_raise: float | None
max_raise: float | None
legal_actions: tuple[Action, ...]Guarda el registro de eventos separado del snapshot actual. El registro sirve para depurar y reproducir; el snapshot, para decidir. Esta separación también permite repetir una mano fallida con otra estrategia sin abrir un WebSocket.
Open Poker incluye hand_id y turn_token en el flujo en vivo. El token impide que una respuesta tardía de una decisión anterior se aplique a otro turno. La referencia del protocolo WebSocket documenta el ciclo de los mensajes, mientras que la guía del ciclo de vida del bot cubre la reconexión y los estados de saldo bajo.
¿Cómo encajan los servicios de equity y rangos?
Las matemáticas de póker deben vivir en un servicio puro que reciba cartas y rangos y devuelva datos. No le corresponde decidir si farolear. Como mínimo, debe proporcionar ranking de manos, pot odds, estimaciones de equity, stack efectivo, relación stack-to-pot y posición.
Empieza por cálculos deterministas. Las pot odds y los tamaños legales de apuesta son baratos y exactos. Añade equity Monte Carlo cuando el board y los rangos rivales hagan costosa la enumeración. Nuestra calculadora de equity en Python muestra el patrón de simulación, y matemáticas de póker para bots explica las fórmulas relacionadas.
Para trabajar con cartas y estados, PokerKit es una biblioteca útil. Permite simular variantes de póker y procesar historiales de manos sin pretender ser un runtime de despliegue completo. OpenSpiel y RLCard encajan mejor en aprendizaje por refuerzo local o investigación de teoría de juegos.
Mantén explícitos los rangos rivales. Un rango es una entrada incierta, no un hecho que descubre el evaluador. El modelo de oponentes puede estimarlo a partir de las acciones observadas y el servicio de equity puede calcular contra él. Si mezclas ambas tareas, será difícil saber si una mala decisión provino de las matemáticas o de una lectura equivocada.
¿Cómo debería separarse la estrategia del transporte?
La capa estratégica debe recibir un DecisionContext y devolver una intención. Nunca debe llamar directamente a websocket.send(). Esta regla permite ejecutar la misma política en una prueba unitaria, una reproducción de manos, un benchmark contra Slumbot o una arena de bots en vivo.
@dataclass(frozen=True)
class DecisionIntent:
action: Action
amount: float | None = None
reason: str = ""
def decide(context: DecisionContext) -> DecisionIntent:
if context.to_call == 0 and "check" in context.legal_actions:
return DecisionIntent("check", reason="free action")
if context.to_call > context.stack * 0.25:
return DecisionIntent("fold", reason="price exceeds risk cap")
return DecisionIntent("call", reason="within risk cap")El ejemplo es deliberadamente simple. La interfaz importa más que la política. Puedes reemplazar la función con rangos por posición, modelado de oponentes, una política CFR o un LLM. El protocolo y los controles se mantienen sin cambios.
Nuestros primeros bots eran más difíciles de depurar porque mezclaban el estado del socket con el estado de póker. Una reconexión podía reiniciar una variable que parecía memoria estratégica. Al separar ambas capas, las reproducciones de manos se volvieron deterministas y los fallos de conexión pasaron a ser pruebas de protocolo, no misterios de la estrategia.
¿Qué controles de fiabilidad son más importantes?
La capa de control debe asumir que la estrategia fallará alguna vez. Las API de modelos agotan el tiempo de espera, las simulaciones superan su presupuesto y una respuesta obsoleta puede llegar cuando la mesa ya avanzó. Un bot fiable gestiona estos fallos antes de enviar cualquier acción.
Usa estos controles en cada turno:
- Margen antes del plazo: Detén la estrategia antes del límite del servidor, no al alcanzarlo.
- Comprobación del token de turno: Descarta resultados que no correspondan al turno activo.
- Filtro de acciones legales: Rechaza cualquier acción ausente de la lista del servidor.
- Límite de tamaño: Mantén los raises entre el mínimo y el máximo indicados.
- Política alternativa: Ejecuta
checkcuando sea legal; en caso contrario, usafoldsi falla la estrategia principal. - Idempotencia: No proceses dos veces un evento duplicado.
El protocolo actual de Open Poker permite 20 mensajes WebSocket por segundo por conexión y mantiene un asiento desconectado durante 120 segundos. Esos límites son lo suficientemente generosos para un bot, pero solo si el cliente trata los reintentos y las reconexiones como transiciones de estado en lugar de abrir bucles incontrolados.
La guía de errores de WebSocket cubre códigos de cierre y errores de mensajes. El artículo sobre timeouts se centra en la latencia del modelo, los errores asíncronos y las políticas alternativas. Lee ambos antes de conectar una API de modelos externa.
¿Cómo deberías probar el software de un bot de póker?
Prueba de dentro hacia fuera. Las matemáticas puras y los validadores de acciones deben ejecutarse en milisegundos sin servidor. Las reproducciones de manos grabadas deben validar la reconstrucción del estado. Un rival de referencia debe medir la estabilidad de la estrategia. La integración final corresponde a una sala en vivo que permita bots.
Usa cuatro niveles de prueba:
| Nivel | Prueba | El fracaso lo atrapa |
|---|---|---|
| 1 | Pruebas unitarias de matemáticas y dimensionamiento | Errores de fórmulas y límites |
| 2 | Repeticiones de eventos grabados | Errores de estado e idempotencia |
| 3 | Sesiones largas locales o de benchmark | Fugas de estrategia y crecimiento de la memoria |
| 4 | Sesiones de bot-arena en vivo | Momento, reconexión y diversidad de oponentes |
No promociones una política porque ganó 20 manos. Los resultados del póker tienen mucha varianza y una buena racha breve puede ocultar problemas de arquitectura. Promociónala cuando cumpla sus invariantes: cero acciones ilegales, latencia acotada, reconexiones limpias, memoria estable y decisiones reproducibles para el mismo snapshot.
Slumbot resulta útil como rival heads-up estable. Para probar la integración multijugador, Open Poker ofrece mesas en vivo y un grupo cambiante de bots. La comparación entre Open Poker y Slumbot explica por qué ambas etapas responden a preguntas distintas.
¿Qué deberías construir y qué deberías pedir prestado?
Crea la política que diferencie a tu agente. Reutiliza evaluadores de manos, clientes de protocolo, logs, métricas y utilidades de prueba cuando exista una biblioteca mantenida adecuada. Reescribir un evaluador rara vez mejora la estrategia y sí crea otro lugar para errores silenciosos.
| Componente | Construir | Pedir prestado o adaptarse |
|---|---|---|
| Política de estrategia única | Sí | Línea de base opcional |
| Diseño de características del oponente | Generalmente | Primitivas estadísticas |
| Evaluador de mano | Rara vez | PokerKit u otra biblioteca probada |
| Transporte WebSocket | Envoltorio fino | Biblioteca cliente estándar |
| Reintentos y backoff | Configurar | Utilidad mantenida |
| Logs y métricas | Configurar | Stack de observabilidad estándar |
| Servidor de juegos y emparejamiento | No para la mayoría de los equipos | Plataforma de bots explícita |
Los límites cambian para la investigación. Si estás probando una nueva abstracción o representación de juego, el punto puede ser construir más motor. Si está intentando mejorar un agente en vivo, dedique ese tiempo a decisiones, datos y evaluación.
¿Cuál es un orden práctico de implementación?
Construye primero el segmento vertical más pequeño: conecta, normaliza un turno, elige una alternativa legal, envíala y registra el resultado. Después profundiza en una capa cada vez. Así detectarás límites mal definidos antes de que una estrategia compleja encarezca cualquier cambio.
- Implementa el adaptador de protocolo y una alternativa de check o fold.
- Añade snapshots inmutables y pruebas con reproducciones grabadas.
- Incorpora pot odds, ranking de manos y una política básica de rangos.
- Añade validadores de acciones, cancelación por plazo y recuperación tras reconexiones.
- Incorpora características de los rivales y cálculos de equity más costosos.
- Añade un LLM o una política aprendida solo cuando el runtime sea estable.
La guía para crear un bot de póker en Python ofrece el primer segmento vertical. La guía de cero a la clasificación muestra cómo iterar cuando el bot ya puede completar manos. Mantén estable la interfaz entre capas mientras cambias la política.
Preguntas frecuentes
¿Qué es el software de un bot de póker?
Es un programa que convierte el estado de una partida de póker en acciones legales. Un sistema completo incluye protocolo, seguimiento de estado, matemáticas, estrategia, controles de seguridad y telemetría. El modelo estratégico es una capa, no el producto completo.
¿Qué es un motor de póker?
Un motor de póker aplica las reglas y mantiene un estado válido. Reparte cartas, registra apuestas, resuelve botes y aplica acciones legales. El bot consume ese estado y elige acciones. Algunas bibliotecas combinan ambas funciones, pero conviene mantener separados los conceptos.
¿Qué lenguaje de programación es mejor para un bot de póker?
Python suele ser el punto de partida más rápido gracias a su ecosistema de redes, datos y machine learning. Rust, Go, JavaScript y Java también funcionan bien. Open Poker solo requiere WebSocket y JSON, así que la compatibilidad con el protocolo importa más que el lenguaje elegido.
¿Debería un bot de póker utilizar un LLM?
Un LLM puede ocupar la capa estratégica, pero necesita controles deterministas a su alrededor. Impón acciones legales, limita la latencia, valida la salida estructurada y conserva una alternativa barata. No encargues a un modelo remoto el estado de la conexión ni la validación de apuestas.
¿Cómo pruebo un bot de póker de forma segura?
Empieza con pruebas unitarias y reproducciones de manos; continúa con un benchmark estable o un simulador local. Ejecuta el bot en vivo solo en una plataforma que permita expresamente agentes autónomos. Nunca pruebes automatización oculta en una cuenta de póker para personas.
Una arquitectura limpia vuelve predecible la iteración estratégica. Puedes sustituir una regla por equity Monte Carlo o por un LLM sin tocar la lógica de reconexión. Empieza con la guía rápida de Open Poker, mantén sencilla la primera política y haz observable cada capa antes de añadir inteligencia.