Triumvirate4LLM

Docs / LLM Bot

LLM Bot

A GUI client that bridges any LLM provider to the Triumvirate chess server. Version 2.2. View on GitHub →

Priority: Triumvirate Notation for LLM Prompts
When building prompts for LLM-powered bots, always prefer Triumvirate v4.0 notation over classical server notation (A1–L12). Generative models understand hexagonal board geometry significantly better with sector-ring-depth coordinates (e.g., W2/R2.3) than with the classical notation that has irregular bridges and gaps between segments. The LLM Bot client supports both notations natively and includes built-in converters. See the full Triumvirate v4.0 specification for complete mapping tables and coordinate formulas.

Overview

Triumvirate LLM Bot v2.2 is an autonomous, fully graphical client-bot for playing three-player chess. On each turn the bot:

  1. Gets the board state from the server
  2. Builds a multi-layered, configurable prompt
  3. Sends the request to the chosen LLM
  4. Parses the response and extracts a valid chess move
  5. Sends the move to the server

After pressing Start, the bot plays fully automatically until the game ends.

Key Features

Installation & Setup

# Clone the repository
git clone https://github.com/fortser/Triumvirate_LLMbot.git
cd Triumvirate_LLMbot/examples/decomp

# Install dependencies
pip install -r requirements.txt

# Set API keys (optional, depending on provider)
export OPENAI_API_KEY=sk-...
export ANTHROPIC_API_KEY=sk-ant-...
export OPENROUTER_API_KEY=sk-or-...

# Run (desktop window)
python main.py

# Run as web server
python main.py --web --port 8090

# Run headless (no GUI)
python main.py --headless

Command-Line Options

FlagDescription
--webLaunch as web server instead of desktop window
--host HOSTWeb server host (default: 0.0.0.0)
--port PORTWeb server port (default: 8090)
--settings FILEPath to separate config file
--headlessNo GUI, console output only
--bots NRun N parallel bots (multi-bot mode)
--models M1 M2Explicit model list for multi-bot
--models-pool FILEJSON file with model pool for multi-bot
--start-delay NSeconds between bot launches

LLM Providers

ProviderBase URLAPI Key Env
Ollamahttp://localhost:11434/v1Not required
OpenAIhttps://api.openai.com/v1OPENAI_API_KEY
AnthropicNative protocol (not OpenAI-compatible)ANTHROPIC_API_KEY
OpenRouterhttps://openrouter.ai/api/v1OPENROUTER_API_KEY
LM Studiohttp://localhost:1234/v1Not required
Custom URLAny OpenAI-compatible endpointConfigurable

Prompt System

The bot builds prompts from configurable templates stored in prompts/:

Template Placeholders

PlaceholderReplaced With
Current move number
Your color (white/black/red)
Dict of legal moves
Board state (piece list)
Check information
Position in 3PF format
Previous move details
Use Triumvirate notation in prompts. Replace classic coordinates with sector-ring-depth notation in and placeholders. Models produce significantly more accurate moves when board geometry is described with the radial-ring coordinate system. The LLM Bot converter handles the translation automatically. See the full specification for coordinate format details.

Response Formats & Parsing

Simple Text

Model responds with plain text like E2 E4. Parser uses regex to extract coordinates.

JSON

Model responds with {"move_from": "E2", "move_to": "E4"}. Parser extracts keys directly.

JSON with Thinking

Model includes analysis: {"thinking": "Analysis...", "move_from": "E2", "move_to": "E4"}. Thinking is saved in trace logs for analysis.

Double parsing: The response is first parsed as JSON, then as text via regex. This dual approach maximizes compatibility across different LLM output styles.

Reliability & Fallbacks

Cost Tracking

For OpenRouter, pricing is automatically loaded from the API. Per-move cost is calculated from input, output, and reasoning tokens. Cumulative stats are shown when the bot stops.

Move Tracing

Every move is saved as a JSON file in logs/game_<id>/move_NNN.json containing:

Trace Analyzer

A separate web app + CLI tool for analyzing trace logs:

# Launch trace viewer
cd trace_analyzer && python app.py --logs ../logs --port 8091

# Generate metrics and model rankings
python -m trace_analyzer.metrics

# With SmartBot objective evaluation
python -m trace_analyzer.metrics --smartbot

The viewer has 4 tabs: Overview (dashboard), Moves Table, Thinking Gallery, Move Detail.

Multi-Agent Evaluation

A system of three components for analyzing LLM play quality:

ComponentTypePurpose
metrics.pyPython CLIAutomated metrics, model rankings
Model EvaluatorClaude Code agentChess evaluation, model suitability
Prompt OptimizerClaude Code agentPrompt analysis, recommendations

Composite Score

Models are ranked by a composite score (0–1):

ScoreRating
0.70+Excellent — suitable for production use
0.50–0.70Average — works with limitations
0.30–0.50Weak — needs prompt optimization
<0.30Unsuitable — can't follow format or produce legal moves

Components (without SmartBot): Reliability 35% + Activity 30% + Tactical 20% + Efficiency 15%

Components (with SmartBot): Reliability 20% + SmartBot Quality 35% + Tactical 15% + Efficiency 10% + Win Rate 20%

Triumvirate Notation in the LLM Bot

The LLM Bot supports two notation modes for prompts. The notation mode is configured in the settings panel or via the config file.

Notation Comparison in Prompts

AspectServer (Classic)Triumvirate v4.0 (Recommended)
Cell format E2, A1, L12 W2/R2.3, W3/B3.0, R3/B3.0
Piece names King, Queen, Rook, Bishop, Knight, Pawn Leader, Marshal, Train, Drone, Noctis, Private
Board geometry Column-row grid with gaps (E5–H8, I1–L4, A9–D12 invalid) Seamless radial-ring system; all 96 cells addressable without gaps
Sector awareness Implicit (must memorize which columns belong to which segment) Explicit (sector letter W/B/R is part of every coordinate)
LLM accuracy Lower — models struggle with irregular bridge geometry Higher — models understand radial/ring spatial relationships natively

How the Converter Works

The bot's notation_converter.py module translates between the two systems. When Triumvirate mode is active:

  1. Server sends /state response in classic notation (e.g., E2)
  2. Converter translates board and legal_moves to Triumvirate (e.g., W2/R2.3)
  3. Prompt is built with Triumvirate coordinates and piece names
  4. LLM responds with a Triumvirate move (e.g., W2/R2.3 to W1/R1.3)
  5. Converter translates back to classic notation for the /move API call

Key Positions in Both Notations

DescriptionClassicTriumvirate
White Leader (King)E1W3/R3.3
White Marshal (Queen)D1W3/B3.3
Black Leader (King)I8B3/R3.3
Red Leader (King)I12R3/W3.3
Rosette (White-Black)D4C/W.B
Rosette (White-Red)E4C/W.R
Rosette (Black-Red near Black)D5C/B.R
Rosette (Black-Red near Red)I9C/R.B

Multi-Bot Mode

# Run 3 bots with random models from pool
python main.py --headless --bots 3

# Run 5 bots with specific models
python main.py --headless --models openai/gpt-4o anthropic/claude-haiku-4-5-20251001

# Custom model pool with staggered start
python main.py --headless --bots 5 --models-pool custom_pool.json --start-delay 10