{"slug": "finechess", "title": "FineChess...!!", "summary": "A developer built FineChess, a chess coaching tool that pairs Stockfish engine analysis with an LLM coach called Coach Rex, which is restricted to commenting only on a strict JSON fact sheet of engine-verified moves. The system classifies moves by win-probability loss rather than raw centipawn drops and grounds a global coach's advice in public-domain chess literature retrieved via a local TF-IDF index. The design principle is that Stockfish decides what is true while the LLM decides how to teach it.", "body_md": "Stockfish can tell you that `17...Bh6` dropped your win chance from 72% to 31%.\n\nWhat it *won't* tell you is the part that actually makes you better:\n\nYou were trying to create a kingside attack. That idea is fair but Black's reply `Bxd5` wins a pawn immediately, and the cleaner try was `Nf3`, checking every check before you commit.\n\nThat gap between **engine truth** and **human understanding** is why I built **FineChess**.\n\nIf you've ever clicked **Game Review** after a Chess.com or Lichess game, you know the ritual:\n\n`Nf3 Bxd5 cxd5 Qe2`\nThe engine is brilliant at **measuring** decisions. Humans need help **interpreting** them.\n\nClub players (roughly 800 to 1800, the range FineChess coaches for) don't lose because they can't read an eval graph. They lose because:\n\nExisting tools give you a verdict. I wanted a **coach sitting across the board**.\n\nSo FineChess does three things traditional analysis usually separates:\n\nFineChess doesn't ask the LLM to \"look at a board and think.\" That would be asking a language model to do an engine's job.\n\nInstead the pipeline is deliberately asymmetric:\n\n```\nPGN / Chess.com / Lichess\n        │\n        ▼\n   Stockfish analysis\n   (eval, multipv lines, mate scores)\n        │\n        ▼\n   Move classifier\n   (brilliant → blunder, win% loss)\n        │\n        ▼\n   MoveFacts sheet  ← ground truth\n        │\n        ▼\n   Coach Rex (LLM)  ← may only talk about these facts\n```\n\nFor each position we run Stockfish (python-chess and a cached engine wrapper) and keep:\n\nResults are cached by FEN and depth so replaying a game doesn't recompute the same positions forever.\n\nRaw centipawn drops lie in unbalanced positions. Going from +600 to +400 looks huge on paper and often feels like \"still completely winning\" over the board.\n\nSo FineChess classifies with **win-probability loss** from the mover's perspective, then labels moves across the familiar spectrum: brilliant, great, best, excellent, good, book, inaccuracy, miss, mistake, blunder.\n\nBrilliant detection is its own mini-pipeline: sacrifice candidates, SEE filters, PV lookahead, and guards against calling something \"brilliant\" when you were already completely winning.\n\nBefore Coach Rex speaks, the backend builds a strict JSON fact sheet, roughly:\n\nThat sheet is the coach's **only allowed chess reality**.\n\nRex's system prompt is blunt about it:\n\nENGINE FACTS are ground truth. Never invent moves, evaluations, or lines that are not in them.\n\nAnd the answer shape is coaching, not commentary:\n\nNo \"centipawns.\" No lecture. Roughly club-player English in about 120 words.\n\nThat is the whole bet of FineChess:\n\n**Stockfish decides what is true. The LLM decides how to teach it.**\n\nMove-by-move analysis is only half the product.\n\nFineChess also has a **global coach** that remembers patterns across your games: recurring weaknesses, opening mastery gaps, fix plans, recent accuracy. When you ask something like:\n\n\"I keep hanging pieces after I castle queenside. What should I watch for?\"\n\nthe coach shouldn't answer from generic LLM chess folklore.\n\nSo we retrieve.\n\nUnder `backend/knowledge/` we keep public-domain chess literature (starting with Capablanca's *Chess Fundamentals* from Project Gutenberg). At startup the service:\n\n`.txt` book`CHESS KNOWLEDGE REFERENCE`\nThe instruction to the model is intentionally narrow:\n\nUse them to ground your explanation. Explain in your own coaching voice but let these principles guide your reasoning.\n\nWhy TF-IDF instead of a fancy vector database on day one?\n\nBecause chess coaching retrieval is often **lexical and conceptual** (\"isolated pawn\", \"opposition\", \"back rank\"), the corpus is small and high-signal, and a local sklearn index is fast, free, and easy to reason about. We can graduate to embeddings later. The product win was already having **literature in the loop**.\n\nSo FineChess uses grounding at two layers:\n\n| Layer | Source of truth | Purpose | \n|---|---|---|\n| Move coach (Rex) | Stockfish `MoveFacts` | Don't invent tactics | \n| Global coach | Player memory and RAG literature | Don't invent principles | \n\nBoth are anti-hallucination strategies. They just fight different failure modes.\n\nHere's the uncomfortable truth about putting an LLM next to a chessboard:\n\n**It will confidently invent a move that isn't legal, wasn't played, and wasn't in the engine line, and it will sound *great* doing it.**\n\nEarly prototypes of FineChess did exactly that.\n\nRex would say you \"dropped a rook\" when the PV only lost a pawn.\n\nOr cite `Qh5` as the refutation when Stockfish's best line never touched the queen.\n\nOr end a sentence on `17...` like a broken PGN printer.\n\nThat is not a tone problem. That is a **trust** problem. One fake move and the coach is dead.\n\nCoach Rex now runs a cheap but ruthless grounding check *after* generation:\n\n`played_san`, `best_san`, `best_line_san`, or `played_line_san`\nThere is also a separate claim verifier path for structured tactical claims (legality, hanging pieces, simple SEE-style material checks) used when generating richer mistake explanations, with verifier outcomes logged so we can see whether an explanation passed, retried, or fell back to facts.\n\nIn other words:\n\nThe model is allowed to be eloquent.\n\nIt is not allowed to be creative about the board.\n\nThat single constraint changed FineChess from \"fun demo\" into something I'd trust with my own blunders.\n\nA second, quieter challenge was **latency**. Users click a move and expect a coach, not a research paper. So Rex asks for short answers, uses tight timeouts, and always has a fact-sheet fallback. Correct and slightly plain beats poetic and wrong every time.\n\nUnder the hood it's FastAPI, Stockfish, Gemini/Groq coaching, Supabase auth/data and a React analysis UI. On the surface it should feel like a sharp human coach who somehow watched every game you've uploaded.\n\nIf you've ever stared at an eval bar and thought *\"okay but what was I supposed to think?\"* that's the product.\n\n**Live app:** [https://finechess.vercel.app](https://finechess.vercel.app)\n\nImport a recent loss. Click the move that hurt. Ask Rex why.\n\nI'd love feedback from other builders working on grounded LLM systems, especially if you've fought the same \"confident nonsense\" problem in a domain where facts are non-negotiable.\n\n```\nEngine truth  →  Fact sheet  →  LLM narration  →  Grounding check\nLiterature    →  TF-IDF RAG  →  Coach principles\nPlayer memory →  Pattern context → Personalized habits\n```\n\nChess improvement doesn't need more numbers.\n\nIt needs numbers that can explain themselves.", "url": "https://wpnews.pro/news/finechess", "canonical_source": "https://dev.to/manuelyator/finechess-45e7", "published_at": "2026-11-09 20:17:39+00:00", "updated_at": "2026-11-09 20:25:30.431849+00:00", "lang": "en", "topics": ["artificial-intelligence", "large-language-models", "ai-products", "ai-tools"], "entities": ["FineChess", "Stockfish", "Coach Rex", "Chess.com", "Lichess", "Capablanca", "Project Gutenberg"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/finechess", "markdown": "https://wpnews.pro/news/finechess.md", "text": "https://wpnews.pro/news/finechess.txt", "jsonld": "https://wpnews.pro/news/finechess.jsonld"}}