{"slug": "gemma-added-a-generation-that-never-lived-my-code-turned-it-into-a-ghost", "title": "Gemma added a generation that never lived. My code turned it into a ghost.", "summary": "A developer built Shezhire, an open-source pipeline that turns a recorded Kazakh family story into a genealogy (шежіре) using Gemma 4 via Ollama, with a verification layer that requires every proposed family link to be grounded in a specific sentence and timestamp from the transcript. On 60 test families, Gemma 4 12B produced correct links 85.5% of the time, and the verification code caught all 118 incorrect links, so every link that reached the output page was correct. The project, roughly 800 lines of Python using faster-whisper and open Gemma 4 weights, was motivated by the model confidently inventing a generation between a father and his children.", "body_md": "*This is a submission for the [Hacktoberfest Open-Source AI Challenge Week 4: Ghost in the Machine](https://dev.to/challenges/hacktoberfest-week4-2026-10-26)*\n\n**TL;DR** Shezhire turns a recorded family story into a Kazakh family tree (*шежіре*) with Gemma 4 running on open weights. The model reads, but it does not get the last word: every link has to point at the sentence and the second of the recording where it was said, and plain code checks that the words are really there. On 60 test families, Gemma 4 12B got 85.5% of its links right. Every one of the 118 wrong links was caught, so 100% of what reached the page was right.\n\nIn Kazakhstan there is a question every kid hears sooner or later, usually from an old man at a wedding table: *\"Жеті атаңды білесің бе?\"* Do you know your seven fathers?\n\nYou are supposed to answer by heart. Your father, his father, his father, seven names back. Most of us can't. We get to three, maybe four, and then somebody's grandmother leans over and finishes it for us, with a village, a year and a story about why the family moved.\n\nThat grandmother is the whole archive. There is no database behind her. When she is gone, the tree is gone.\n\nSo I wanted the simplest possible thing: put a phone on the table, let her talk, get the tree out of the recording.\n\nThe first real run showed me the ghost. The story said:\n\n*Моего прадеда звали Сәкен… Его жену, мою прабабушку, звали Мария. У них было двое детей: Данияр и Ерлан.*\n\nMy great-grandfather was Сәкен… They had two children, Данияр and Ерлан.\n\nGemma 4 12B read it and answered, confidently, with a quote: **\"Сәкен is the grandfather of Данияр.\"** Of his own son. One line of JSON, and a whole generation that never lived appears between a father and his children. On a family tree that is the worst kind of mistake. It looks right. Somebody will print it.\n\n**Shezhire** keeps the model but takes away its last word:\n\nHere the model decided that the narrator's younger brother has the same father as she does. Probably true. But nobody said it, and the code will not write down what nobody said.\n\n**Live page:** [Әлия's family tree, built by Gemma 4 12B](https://oleg-vdv.github.io/shezhire/demo/aliya-gemma4_12b.html). Click a name or a line. Ink lines show the quote and the time it was said; dashed lines show what the model claimed and why it was dropped.\n\nThe same story read by the small model, [Gemma 4 E2B](https://oleg-vdv.github.io/shezhire/demo/aliya-gemma4_e2b-it-qat.html), for comparison.\n\nThe story is invented but written the way older relatives talk: Russian with Kazakh kinship words (*атам, әжем, әкем*), people called by role (\"my grandfather\") instead of name, a neighbour everyone calls *апа* who is not family.\n\n**A family tree from recorded stories, built by a local open-weight model and checked line by line against the recording.**\n\n*Шежіре* is the Kazakh word for a genealogy. Kazakh families keep track of seven generations of ancestors (*жеті ата*), mostly through stories told by the oldest relatives. When those relatives are gone, the stories go with them.\n\nShezhire takes a recording of a grandmother telling the family story, lets an open-weight model (Gemma 4 through Ollama) read the transcript, and builds the tree. The model is not trusted. Every link it proposes goes through code that has to find, in the recording itself:\n\n```\naudio ─faster-whisper─▶ timestamped segments ─Gemma 4 via Ollama─▶ claims (JSON)\nclaims ─verify.py─▶ verified links + ghosts ─tree.py─▶ generations, contradictions ─▶ one HTML page\n```\n\nEverything here is open: Gemma 4 weights, Ollama, faster-whisper, and about 800 lines of Python.\n\nFor every link the model proposes, `shezhire/verify.py` asks four questions, in this order:\n\nPlus two rules I added after reading the small model's mistakes:\n\nAnd two things that make it work on how people actually talk:\n\nI don't have a GPU at home, so the eval ran on a free Kaggle T4 with Ollama inside the notebook. The runner is in the repo (`kaggle/build.py`).\n\n`eval/make_synthetic.py` generates families with a known true tree and the traps real recordings have: a named neighbour who is \"like family\", a child whose name nobody remembers, \"he married in 1942\" with the husband in the previous sentence, Kazakh words inside Russian speech. I made 30 families, tuned the check on them, then generated **30 new families with a different seed** that the rules had never seen.\n\nFinal setup, Gemma 4 12B:\n\n|  | 30 families I tuned on | 30 new families | \n|---|---|---|\n| Links the model proposed | 407 | 407 | \n| Correct before the check | 85.5% | 85.5% | \n| Wrong links caught as ghosts | **59 of 59** | **59 of 59** | \n| Correct after the check | **100%** (303 of 303) | **100%** (290 of 290) | \n| True links the check threw away | 46 of 350 | 59 of 351 | \n| Time per story on a T4 | 45 s | 44 s | \n\n\"True links thrown away\" is the price. Almost all of them fail rule 3: one of the two people is only named further back in the story. I chose that trade on purpose: a missing branch is a gap the family can fill, an invented one is a lie on the page.\n\n`\"think\": false`) and it went down to 45 seconds a story.` shezhire transcribe`) is in the repo; the numbers above are on typed transcripts.\nA closed model would probably write nicer JSON. But a family tree does not need nicer JSON. It needs every line to point at the recording.\n\nDía de los Muertos builds an *ofrenda* so the dead are remembered correctly: their names, their food, their photos. A *шежіре* makes the same promise in a different form.\n\nThe scariest ghost for that promise is not a spirit. It is a person who never lived, written into the family by a machine in a calm, confident voice. So in Shezhire the ghosts stay on the page, on purpose, in red pencil, each with a note: *the recording does not say this*. The tree is honest about what the machine wanted to add.", "url": "https://wpnews.pro/news/gemma-added-a-generation-that-never-lived-my-code-turned-it-into-a-ghost", "canonical_source": "https://dev.to/olegvdv/gemma-added-a-generation-that-never-lived-my-code-turned-it-into-a-ghost-jab", "published_at": "2026-10-31 04:10:32+00:00", "updated_at": "2026-10-31 04:19:58.244371+00:00", "lang": "en", "topics": ["artificial-intelligence", "large-language-models", "ai-tools", "ai-agents"], "entities": ["Gemma 4", "Ollama", "faster-whisper", "Shezhire", "Kaggle", "Kazakhstan"], "also_reported_by": [], "alternates": {"html": "https://wpnews.pro/news/gemma-added-a-generation-that-never-lived-my-code-turned-it-into-a-ghost", "markdown": "https://wpnews.pro/news/gemma-added-a-generation-that-never-lived-my-code-turned-it-into-a-ghost.md", "text": "https://wpnews.pro/news/gemma-added-a-generation-that-never-lived-my-code-turned-it-into-a-ghost.txt", "jsonld": "https://wpnews.pro/news/gemma-added-a-generation-that-never-lived-my-code-turned-it-into-a-ghost.jsonld"}}