<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Emmanuel Yator</title>
    <description>The latest articles on DEV Community by Emmanuel Yator (@manuelyator).</description>
    <link>https://dev.to/manuelyator</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4235751%2F3e4bf81a-35bc-4bbc-bdc0-b4f7f3ecddc2.png</url>
      <title>DEV Community: Emmanuel Yator</title>
      <link>https://dev.to/manuelyator</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/manuelyator"/>
    <language>en</language>
    <item>
      <title>FineChess...!!</title>
      <dc:creator>Emmanuel Yator</dc:creator>
      <pubDate>Mon, 09 Nov 2026 20:17:39 +0000</pubDate>
      <link>https://dev.to/manuelyator/finechess-45e7</link>
      <guid>https://dev.to/manuelyator/finechess-45e7</guid>
      <description>&lt;p&gt;Stockfish can tell you that &lt;code&gt;17...Bh6&lt;/code&gt; dropped your win chance from 72% to 31%.&lt;/p&gt;

&lt;p&gt;What it &lt;em&gt;won't&lt;/em&gt; tell you is the part that actually makes you better:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You were trying to create a kingside attack. That idea is fair but Black's reply &lt;code&gt;Bxd5&lt;/code&gt; wins a pawn immediately, and the cleaner try was &lt;code&gt;Nf3&lt;/code&gt;, checking every check before you commit.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That gap between &lt;strong&gt;engine truth&lt;/strong&gt; and &lt;strong&gt;human understanding&lt;/strong&gt; is why I built &lt;strong&gt;FineChess&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://finechess.vercel.app" rel="noopener noreferrer"&gt;Try it live&lt;/a&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  The problem I wanted to solve
&lt;/h2&gt;

&lt;p&gt;If you've ever clicked &lt;strong&gt;Game Review&lt;/strong&gt; after a Chess.com or Lichess game, you know the ritual:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Eval bar jumps&lt;/li&gt;
&lt;li&gt;Moves light up: Brilliant, Mistake, Blunder&lt;/li&gt;
&lt;li&gt;A principal variation appears: &lt;code&gt;Nf3 Bxd5 cxd5 Qe2&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;You nod politely&lt;/li&gt;
&lt;li&gt;You queue the next game with the &lt;em&gt;exact same blind spot&lt;/em&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The engine is brilliant at &lt;strong&gt;measuring&lt;/strong&gt; decisions. Humans need help &lt;strong&gt;interpreting&lt;/strong&gt; them.&lt;/p&gt;

&lt;p&gt;Club players (roughly 800 to 1800, the range FineChess coaches for) don't lose because they can't read an eval graph. They lose because:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;They don't know &lt;em&gt;what the move was trying to do&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;They don't see &lt;em&gt;how the opponent punishes it&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;They don't leave with a &lt;em&gt;reusable habit&lt;/em&gt; for next time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Existing tools give you a verdict. I wanted a &lt;strong&gt;coach sitting across the board&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So FineChess does three things traditional analysis usually separates:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Stockfish&lt;/strong&gt; scores every move and finds the best lines&lt;/li&gt;
&lt;li&gt;An &lt;strong&gt;LLM coach ("Coach Rex")&lt;/strong&gt; turns those facts into plain-language lessons&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;RAG&lt;/strong&gt; pulls principles from chess literature so advice isn't just vibes. It's grounded in real chess knowledge&lt;/li&gt;
&lt;/ol&gt;




&lt;h2&gt;
  
  
  How Stockfish feeds the AI coaching pipeline
&lt;/h2&gt;

&lt;p&gt;FineChess 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.&lt;/p&gt;

&lt;p&gt;Instead the pipeline is deliberately asymmetric:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;PGN / Chess.com / Lichess
        │
        ▼
   Stockfish analysis
   (eval, multipv lines, mate scores)
        │
        ▼
   Move classifier
   (brilliant → blunder, win% loss)
        │
        ▼
   MoveFacts sheet  ← ground truth
        │
        ▼
   Coach Rex (LLM)  ← may only talk about these facts
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  What Stockfish actually produces
&lt;/h3&gt;

&lt;p&gt;For each position we run Stockfish (python-chess and a cached engine wrapper) and keep:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Best move (SAN and UCI)&lt;/li&gt;
&lt;li&gt;Score in centipawns or mate distance&lt;/li&gt;
&lt;li&gt;Principal variation (the "if both sides play well" line)&lt;/li&gt;
&lt;li&gt;MultiPV alternatives (2nd and 3rd best) so explanations can compare ideas and not just recite move one&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Results are cached by FEN and depth so replaying a game doesn't recompute the same positions forever.&lt;/p&gt;

&lt;h3&gt;
  
  
  Classification that matches how humans feel swings
&lt;/h3&gt;

&lt;p&gt;Raw 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.&lt;/p&gt;

&lt;p&gt;So FineChess classifies with &lt;strong&gt;win-probability loss&lt;/strong&gt; from the mover's perspective, then labels moves across the familiar spectrum: brilliant, great, best, excellent, good, book, inaccuracy, miss, mistake, blunder.&lt;/p&gt;

&lt;p&gt;Brilliant detection is its own mini-pipeline: sacrifice candidates, SEE filters, PV lookahead, and guards against calling something "brilliant" when you were already completely winning.&lt;/p&gt;

&lt;h3&gt;
  
  
  The MoveFacts sheet: the contract with the LLM
&lt;/h3&gt;

&lt;p&gt;Before Coach Rex speaks, the backend builds a strict JSON fact sheet, roughly:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Played move and label&lt;/li&gt;
&lt;li&gt;Eval or mate before and after&lt;/li&gt;
&lt;li&gt;Win % before and after&lt;/li&gt;
&lt;li&gt;Best move and best line (SAN)&lt;/li&gt;
&lt;li&gt;Played continuation line&lt;/li&gt;
&lt;li&gt;Material delta along best vs played lines&lt;/li&gt;
&lt;li&gt;Whether the best move is a check or capture&lt;/li&gt;
&lt;li&gt;Game phase (opening, middlegame or endgame)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That sheet is the coach's &lt;strong&gt;only allowed chess reality&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Rex's system prompt is blunt about it:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;ENGINE FACTS are ground truth. Never invent moves, evaluations, or lines that are not in them.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And the answer shape is coaching, not commentary:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Intent&lt;/strong&gt;: what the played move was trying to do (be fair)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Missed idea&lt;/strong&gt;: name the best move and walk the line in human language&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cost&lt;/strong&gt;: describe the damage from facts (material, advantage, mate) and never guess&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Habit&lt;/strong&gt;: one reusable thinking rule tied to &lt;em&gt;this&lt;/em&gt; position&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No "centipawns." No lecture. Roughly club-player English in about 120 words.&lt;/p&gt;

&lt;p&gt;That is the whole bet of FineChess:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Stockfish decides what is true. The LLM decides how to teach it.&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  How RAG grounds the broader coaching voice
&lt;/h2&gt;

&lt;p&gt;Move-by-move analysis is only half the product.&lt;/p&gt;

&lt;p&gt;FineChess also has a &lt;strong&gt;global coach&lt;/strong&gt; that remembers patterns across your games: recurring weaknesses, opening mastery gaps, fix plans, recent accuracy. When you ask something like:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"I keep hanging pieces after I castle queenside. What should I watch for?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;the coach shouldn't answer from generic LLM chess folklore.&lt;/p&gt;

&lt;p&gt;So we retrieve.&lt;/p&gt;

&lt;h3&gt;
  
  
  A deliberately lightweight knowledge base
&lt;/h3&gt;

&lt;p&gt;Under &lt;code&gt;backend/knowledge/&lt;/code&gt; we keep public-domain chess literature (starting with Capablanca's &lt;em&gt;Chess Fundamentals&lt;/em&gt; from Project Gutenberg). At startup the service:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Loads every &lt;code&gt;.txt&lt;/code&gt; book&lt;/li&gt;
&lt;li&gt;Chunks by &lt;strong&gt;concept boundaries&lt;/strong&gt; (chapters, parts, numbered titles) instead of dumb fixed windows&lt;/li&gt;
&lt;li&gt;Indexes chunks with &lt;strong&gt;TF-IDF&lt;/strong&gt; (1 to 2 grams)&lt;/li&gt;
&lt;li&gt;Retrieves the top passages for the player's question&lt;/li&gt;
&lt;li&gt;Injects them into the system prompt as &lt;code&gt;CHESS KNOWLEDGE REFERENCE&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The instruction to the model is intentionally narrow:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Use them to ground your explanation. Explain in your own coaching voice but let these principles guide your reasoning.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Why TF-IDF instead of a fancy vector database on day one?&lt;/p&gt;

&lt;p&gt;Because chess coaching retrieval is often &lt;strong&gt;lexical and conceptual&lt;/strong&gt; ("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 &lt;strong&gt;literature in the loop&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;So FineChess uses grounding at two layers:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Layer&lt;/th&gt;
&lt;th&gt;Source of truth&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Move coach (Rex)&lt;/td&gt;
&lt;td&gt;Stockfish &lt;code&gt;MoveFacts&lt;/code&gt;
&lt;/td&gt;
&lt;td&gt;Don't invent tactics&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Global coach&lt;/td&gt;
&lt;td&gt;Player memory and RAG literature&lt;/td&gt;
&lt;td&gt;Don't invent principles&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Both are anti-hallucination strategies. They just fight different failure modes.&lt;/p&gt;




&lt;h2&gt;
  
  
  The technical challenge: LLMs love inventing chess moves
&lt;/h2&gt;

&lt;p&gt;Here's the uncomfortable truth about putting an LLM next to a chessboard:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;It will confidently invent a move that isn't legal, wasn't played, and wasn't in the engine line, and it will sound &lt;em&gt;great&lt;/em&gt; doing it.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Early prototypes of FineChess did exactly that.&lt;/p&gt;

&lt;p&gt;Rex would say you "dropped a rook" when the PV only lost a pawn.&lt;br&gt;
Or cite &lt;code&gt;Qh5&lt;/code&gt; as the refutation when Stockfish's best line never touched the queen.&lt;br&gt;
Or end a sentence on &lt;code&gt;17...&lt;/code&gt; like a broken PGN printer.&lt;/p&gt;

&lt;p&gt;That is not a tone problem. That is a &lt;strong&gt;trust&lt;/strong&gt; problem. One fake move and the coach is dead.&lt;/p&gt;

&lt;h3&gt;
  
  
  The fix: verify, retry, then refuse to freestyle
&lt;/h3&gt;

&lt;p&gt;Coach Rex now runs a cheap but ruthless grounding check &lt;em&gt;after&lt;/em&gt; generation:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Parse every SAN-looking token in the reply&lt;/li&gt;
&lt;li&gt;Allow only moves that appear in &lt;code&gt;played_san&lt;/code&gt;, &lt;code&gt;best_san&lt;/code&gt;, &lt;code&gt;best_line_san&lt;/code&gt;, or &lt;code&gt;played_line_san&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Block dramatic material phrases ("drops a rook", "loses the exchange", "drops a piece") unless the material deltas in the fact sheet actually support them&lt;/li&gt;
&lt;li&gt;If the reply fails, regenerate once with the failure note appended&lt;/li&gt;
&lt;li&gt;If still bad, try the fallback LLM provider&lt;/li&gt;
&lt;li&gt;If still bad or timeout (about 22s), serve a &lt;strong&gt;templated answer built only from facts&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;There 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.&lt;/p&gt;

&lt;p&gt;In other words:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The model is allowed to be eloquent.&lt;br&gt;
It is not allowed to be creative about the board.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;That single constraint changed FineChess from "fun demo" into something I'd trust with my own blunders.&lt;/p&gt;

&lt;p&gt;A second, quieter challenge was &lt;strong&gt;latency&lt;/strong&gt;. 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.&lt;/p&gt;




&lt;h2&gt;
  
  
  What it feels like in the product
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Import a game from Chess.com, Lichess, or paste a PGN&lt;/li&gt;
&lt;li&gt;Stockfish analyzes in the background while you watch progress&lt;/li&gt;
&lt;li&gt;Browse the board with move quality, eval graph, and key moments&lt;/li&gt;
&lt;li&gt;Ask Coach Rex about a specific move or chat about patterns across your games&lt;/li&gt;
&lt;li&gt;Leave with a habit, not just a color-coded move list&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Under 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.&lt;/p&gt;




&lt;h2&gt;
  
  
  Try FineChess
&lt;/h2&gt;

&lt;p&gt;If you've ever stared at an eval bar and thought &lt;em&gt;"okay but what was I supposed to think?"&lt;/em&gt; that's the product.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Live app:&lt;/strong&gt; &lt;a href="https://finechess.vercel.app" rel="noopener noreferrer"&gt;https://finechess.vercel.app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Import a recent loss. Click the move that hurt. Ask Rex why.&lt;/p&gt;

&lt;p&gt;I'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.&lt;/p&gt;




&lt;h3&gt;
  
  
  Quick architecture takeaway
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Engine truth  →  Fact sheet  →  LLM narration  →  Grounding check
Literature    →  TF-IDF RAG  →  Coach principles
Player memory →  Pattern context → Personalized habits
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Chess improvement doesn't need more numbers.&lt;/p&gt;

&lt;p&gt;It needs numbers that can explain themselves.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>chess</category>
    </item>
  </channel>
</rss>
