Construire un IA d'échecs avec LLM et Python — Sans coût, sans hallucinations
Les développeurs doivent souvent intégrer des LLM dans leurs applications de jeu, mais l'API OpenAI peut s'avérer coûteuse. Une alternative abordable est OpenRouter, qui propose des modèles open-source gratuits étiquetés :free. Cela permet d'exécuter des requêtes vers Llama 4 sans frais, sous réserve de limites de volume de messages.
L'initialisation du client utilise l'interface standard openai :
class LLMAI:
def __init__(self, model_name="meta-llama/llama-4-maverick-17b-128e-instruct:free"):
self.client = openai.OpenAI(
base_url="https://openrouter.ai/api/v1",
api_key=OPENROUTER_API_KEY,
)
self.model_name = model_name
self.move_count = 0
Définir base_url assure la compatibilité avec le code existant. Le modèle reçoit un prompt pour chaque coup, ce qui limite la charge computationnelle.
Transmettre l'état du plateau au prompt
Les LLM ne traitent pas les échiquiers visuels, donc le contexte doit être construit sous forme texte. Les formats standards FEN et PGN sont enrichis par une liste des coups légaux fournie par python-chess, afin d’éviter les hallucinations.
Code de construction du contexte :
# Récupérer la position actuelle en format FEN
fen = board.fen()
# Historique des coups en format PGN
pgn_moves = []
temp_board = chess.Board()
# Historique des coups
for move in board.move_stack:
pgn_moves.append(temp_board.san(move))
temp_board.push(move)
pgn_history = " ".join(pgn_moves) if pgn_moves else "Position de départ"
# Obtenir la liste des coups légaux
legal_moves = [move.uci() for move in board.legal_moves]
legal_moves_str = ", ".join(legal_moves)
Le prompt système impose une réponse en notation UCI (4 caractères, ex. e2e4) :
prompt = f"""Vous jouez aux échecs en tant que {'blancs' if board.turn == chess.WHITE else 'noirs'}.
Position actuelle (FEN) : {fen}
Historique des coups : {pgn_history}
Numéro du coup : {self.move_count}
Coups disponibles en format UCI : {legal_moves_str}
Choisissez le MEILLEUR coup parmi les options disponibles et retournez UNIQUEMENT le code UCI (ex. e2e4, g1f3, e7e8q).
Ne rajoutez aucune explication, analyse ou texte supplémentaire.
La réponse doit contenir uniquement le code UCI."""
Combiner FEN (état actuel), PGN (historique) et liste UCI (contraintes) améliore la précision de 80 à 90 % par rapport aux prompts basiques.
Validation des coups et mécanisme de secours
Les LLM peuvent ignorer les instructions, renvoyant du texte ou des coups illégaux. La solution ? Appliquer le modèle « Arbitre IA » : python-chess valide les coups UCI avant de les appliquer au plateau.
Logique de la boucle UI :
if move_uci:
try:
move = chess.Move.from_uci(move_uci)
if move in self.board.legal_moves:
# Animation avant exécution
self.animate_move(move)
self.board.push(move)
self.move_history.append(move.uci())
self.last_ai_response = f"LLM a joué : {move.uci()}"
print(self.last_ai_response)
else:
# Sélection aléatoire comme sauvegarde
move = random.choice(list(self.board.legal_moves))
self.animate_move(move)
self.board.push(move)
self.move_history.append(move.uci())
self.last_ai_response = f"LLM a échoué, coup aléatoire : {move.uci()}"
print(self.last_ai_response)
except ValueError:
# Sauvegarde aléatoire
move = random.choice(list(self.board.legal_moves))
Exemple de log :
- Requête #1 : LLM répond 'e7e5' → coup valide.
- Requête #2 : LLM répond 'Bon, je pense que le meilleur coup est d7d5' → sauvegarde a7a6.
Cela garantit un jeu fluide sans plantage.
Composants clés de l'architecture
Le projet repose sur :
- python-chess : gestion du plateau, validation des coups, traitement FEN/PGN/UCI.
- pygame : affichage du plateau, animations des coups.
- openai-client + OpenRouter : appels d’inférence LLM.
- Logique de secours :
random.choicepour assurer la robustesse.
Architecture modulaire : la classe LLMAI isole l’interaction avec le LLM de l’interface, ne transmettant que des coups validés. Facilement extensible à d'autres jeux à règles fixes comme le go ou les dames.
| Composant | Rôle | Bibliothèque |
|-----------|------|---------|
| Plateau | État & validation | python-chess |
| LLM | Sélection du coup | OpenRouter Llama 4 |
| Interface | Affichage & entrée | pygame |
| Arbitre | Validation | try/except |
Ce qui compte vraiment
- OpenRouter offre un accès gratuit à des LLM puissants pour le prototypage, avec des plafonds de requêtes.
- Un prompt strict utilisant FEN, PGN et listes UCI réduit les hallucinations à 10–20 %.
- Le modèle « Arbitre IA » avec mécanisme de secours assure stabilité : LLM suggère, bibliothèque vérifie et applique.
- python-chess est la référence incontestée pour la logique d’échecs en Python, couvrant toutes les règles y compris le roque et le prises en passant.
- Ce projet montre comment intégrer des modèles non déterministes dans des applications déterministes.
— Editorial Team
Aucun commentaire pour le moment.