Šachová umělá inteligence na bázi LLM s Pythonem a python-chess
Vývojáři často potřebují integrovat LLM do her, ale API OpenAI je drahé. Alternativou je OpenRouter s bezplatnými open-source modely označenými tagem :free. Umožňuje spouštět dotazy k Llama 4 bez nákladů, s omezením objemu.
Inicializace klienta používá standardní rozhraní 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
Přepsání base_url zajišťuje kompatibilitu se stávajícím kódem. Model dostává dotaz na každý tah, minimalizuje zátěž.
Předání stavu desky do promptu
LLM nevnímá vizuální desku, proto kontext tvoříme textově. Standardy FEN a PGN doplňujeme seznamem legálních tahů z python-chess, aby se zabránilo halucinacím.
Kód pro sestavení kontextu:
# získáme aktuální pozici ve formátu FEN
fen = board.fen()
# získáme historii tahů ve formátu PGN
pgn_moves = []
temp_board = chess.Board()
# historie tahů
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 "Počáteční pozice"
# získáme seznam legálních tahů
legal_moves = [move.uci() for move in board.legal_moves]
legal_moves_str = ", ".join(legal_moves)
Systémový prompt omezuje odpověď pouze notací UCI (4 znaky, např. e2e4):
prompt = f"""Ty hraješ šachy jako {'bílé' if board.turn == chess.WHITE else 'černé'}.
Aktuální pozice (FEN): {fen}
Historie tahů: {pgn_history}
Tah číslo: {self.move_count}
Dostupné tahy ve formátu UCI: {legal_moves_str}
Vyber NEJLEPŠÍ tah z dostupných a vrať POHODLNĚ UCI kód tahu (např. e2e4, g1f3, e7e8q).
Nepřidávej žádné vysvětlení, analýzy nebo další text.
Odpověď musí obsahovat pouze UCI kód tahu."""
Kombinace FEN (aktuální stav), PGN (historie) a seznamu UCI (omezení) zvyšuje přesnost o 80–90 % ve srovnání s jednoduchými prompty.
Validace tahů a fallback mechanismus
LLM může ignorovat pokyny a vrátit text nebo nelegální tah. Řešení – vzor "AI-Referee": python-chess ověří UCI před aplikací na desku.
Logika v UI-cyklu:
if move_uci:
try:
move = chess.Move.from_uci(move_uci)
if move in self.board.legal_moves:
# animace před provedením tahu
self.animate_move(move)
self.board.push(move)
self.move_history.append(move.uci())
self.last_ai_response = f"LLM udělal tah: {move.uci()}"
print(self.last_ai_response)
else:
# Fallback na náhodný tah
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 se zmýlil, náhodný tah: {move.uci()}"
print(self.last_ai_response)
except ValueError:
# Fallback na náhodný tah
move = random.choice(list(self.board.legal_moves))
Příklad logu:
- Dotaz #1: LLM odpověděl 'e7e5' → platný tah.
- Dotaz #2: LLM odpověděl 'Dobře, myslím, že nejlepší tah je d7d5' → fallback na a7a6.
Zaručuje nepřerušovanost hry bez pádů.
Klíčové komponenty architektury
Projekt je postaven na:
- python-chess: správa desky, validace tahů, FEN/PGN/UCI.
- pygame: vykreslování desky, animace tahů.
- openai-client + OpenRouter: dotazy k LLM.
- Fallback-logika: random.choice pro odolnost proti selháním.
Integrace je modulární: třída LLMAI izoluje LLM od UI, předává pouze ověřené tahy. Rozšiřitelná i na jiné hry s pravidly (go, dáma).
| Komponenta | Role | Knihovna |
|-----------|------|------------|
| Deska | Stav + validace | python-chess |
| LLM | Výběr tahu | OpenRouter Llama 4 |
| UI | Vyobrazení + vstup | pygame |
| Referee | Ověření | try/except |
Co je důležité
- OpenRouter poskytuje bezplatný přístup k silným LLM pro prototypy, s omezením počtu dotazů.
- Pevný prompt s FEN, PGN a seznamem UCI minimalizuje halucinace na 10–20 % případů.
- Vzor "AI-Referee" s fallback zajišťuje stabilitu: LLM navrhuje, knihovna ověří a aplikuje.
- python-chess je standard pro šachovou logiku v Pythonu, pokrývá všechna pravidla včetně krátké a dlouhé rošády a průchodky.
- Projekt ukazuje přístup k integraci nedeterministických modelů do deterministických aplikací.
— Editorial Team
Zatím žádné komentáře.