家譜網站變成 404 後,我打造了一個在本機運行的家譜工具
My family tree became a 404, so I built one that lives on my computer
Tell the Tree 使用透過 Ollama 本機運行的 Gemma 4 E2B,讓用戶以日常句子建立家譜,並在確認前預覽修改;資料不會離開電腦。程式會處理關係歧義及家譜檢查,必要時詢問用戶。Gemma 4 E2B 配合程式在 15 句測試中答對 15 句,另在 6 句日常意大利語測試中作出 5 次正確決定。
This is a submission for the Hacktoberfest Open-Source AI Challenge Week 4: Ghost in the Machine
What I Built
I used to keep my family tree on a genealogy website: names, dates, photos. Then the site shut down, and everything I had put there turned into a 404.
That's my ghost in the machine: a family that still exists somewhere, in a database I can't reach anymore.
Tell the Tree is the tree I wish I'd had. You fill it in by telling it about your family, in plain sentences, in English or Italian:
Allegra è figlia di Claire e di Lord Byron.
(Allegra is the daughter of Claire and Lord Byron.)
A small open-weight model, Gemma 4 E2B, runs on my computer through Ollama and reads the sentence. My code checks it and shows the change in the tree as a dashed "new" preview. Nothing is saved until I confirm, and nothing ever leaves my computer.
It's for anyone who has family stories in their head and doesn't want to hand them to a website that might close one day.
The demo family has a ghost story of its own: the Godwins, the Shelleys and Lord Byron at Villa Diodati in 1816. That was the rainy summer when, stuck indoors, they held a ghost-story contest and Mary began writing Frankenstein. It's also a hard family to put in a tree. Mary's father, her half-brother and her son were all called William. Her husband and her son were both Percy. There are stepsisters and half-sisters everywhere.
Demo
Tell the Tree runs locally, so there's no live link. Here it is in action:
I type "Elizabeth è la sorella di Percy" (Elizabeth is Percy's sister). The tree has two Percys, so it asks which one I mean, shows Elizabeth as "new", and saves her only when I click "Add to tree". This was the first sentence after starting the app, so Ollama was still loading the model: the 22.7 seconds on screen are real, but I shortened that wait in the GIF.
Besides telling the tree in sentences, you can:
- answer its questions when something is ambiguous ("Which Percy do you mean?")
- add, edit or delete people by hand (the same checks apply)
- fix a relationship
- add a photo for each person, stored inside the tree file
- search, and switch between a horizontal and a vertical tree
- export and import GEDCOM, the standard format genealogy programs use to exchange trees
- print the tree or a PDF register
- switch between two themes: a plain register, and Villa Diodati 1816, with a moon and bats
Code
carla800
/
tell-the-tree
A local family tree you build by telling it, in plain sentences. Gemma 4 E2B + Ollama.
Tell the Tree
A family tree you build by telling it, in plain sentences. It runs entirely on your own computer.
You write sentences like "Mary's father was William Godwin" or "Allegra è figlia di Claire e di Lord Byron" (English or Italian). A small local model, Gemma 4 E2B running through Ollama, reads the sentence. The code checks it against the tree and shows you a preview of the change. Nothing is saved until you confirm, and your data never leaves your computer.
Built for DEV's "Ghost in the Machine" challenge, October 2026.
Why I built it
I used to keep my family tree on a genealogy website. The site shut down, and everything I had entered turned into a 404. I wanted a tree that lives on my own computer, in a file I own, that I can export to a standard format (GEDCOM), and that I can…
How I Built It
Gemma copies, the code decides
Family relationships are full of traps. In Italian, nipote can mean grandchild, or nephew or niece. A model asked to "work out the relationship" can get this wrong in a quiet, believable way, and a wrong link in a family tree is worse than a missing one.
So I split the work:
- Gemma copies. It reads the sentence and copies out the names and the kinship word exactly as written: "half-brother", "fratellastro", "nipote".
- The code decides. An Italian/English dictionary decides what that word means.
- When a word is ambiguous, the code looks at the tree. If the tree isn't enough, it asks me.
Then the code runs its checks:
- no cycles: nobody can become their own ancestor
- no impossible dates
- no conflicting parents
- no guessing between people with the same name: it asks "Which Percy do you mean?"
Every fact keeps the sentence it came from. Finally the change appears in the tree as a dashed preview, and only my confirmation saves it.
The stack
-
Model: Gemma 4 E2B (
gemma4:e2b-it-qat), running locally with Ollama - Backend: Python, FastAPI, SQLite (one file per tree, photos included)
- Frontend: React, TypeScript, React Flow and dagre to draw the tree
- Tests: 153. I also checked that the GEDCOM export and import work together: when I export the demo family and import it again, I get back the same tree.
E2B or E4B?
I tried both on my 15 test sentences:
| Model | Gemma alone | With my code |
|---|---|---|
| Gemma 4 E2B | 14/15 | 15/15 |
| Gemma 4 E4B | 12/15 (13/15 after one fix) |
E4B was also 2.5 times slower. Fifteen sentences is a small test, so I don't read too much into it, but it was enough to stay with E2B.
The honest part: 6 secret sentences
I wrote those 15 sentences myself while I was building, so they're clean, and a score on them doesn't prove much.
So before writing the engine, I wrote 6 more sentences in everyday spoken Italian, about an invented family, and put them aside. When the code was finished, I froze it with a git tag (holdout-run) and ran the 6 sentences exactly once.
| Result | |
|---|---|
| Gemma alone | 1/6 |
| With my code | 5/6 |
Here is what Gemma did with spoken Italian:
- It copied "Nonna Lucia" (Grandma Lucia) with the title, as if "Nonna" were part of her name.
- It turned words that aren't names into people: "papà" (dad), "figlio di nonno Carlo" (Grandpa Carlo's son).
- It missed relationships that were implied but never said.
- It invented a marriage.
Sentence h06 went the other way. Gemma got it right and my code got it wrong: it merged two different Williams into one person. That was exactly the trap I had written into that sentence.
The 5/6 also needs a warning. It only measures whether the code made the right decision: save, ask, or refuse. In 3 of those 5 cases, it would have saved wrong names, like "Nonna Lucia". The only thing standing between those mistakes and the tree is the preview, where I see the dashed "new" people and can say no.
These are the real ghosts in my machine: a "papà" who isn't anyone, a wedding that never happened, two Williams who became one. The preview is how they stay out of the family.
I didn't fix anything before publishing. If I fixed the code until those 6 sentences passed, they would become test sentences like the others, and the number would stop meaning anything. So it stays 1/6 and 5/6.
What's next:
- fix the two-Williams bug
- remove kinship titles from names ("Nonna", "Zio")
- when a "name" isn't really a name ("papà"), ask instead of creating a person
- run E4B on the secret sentences
Why Does Open Innovation Matter?
For this project, it's the whole point.
It can't disappear on me. My last tree lived inside someone else's service and died with it. Tell the Tree keeps each family in a single file on my computer, exports to GEDCOM, and uses a model whose weights are on my own disk. If I stopped working on this app tomorrow, the tree would still be mine.
Family data is private data. Names, birth dates and photos of people who are still alive, and who never agreed to be on anyone's server. Here, none of it leaves the computer.
The model can't change under me. I tested one specific model, and because it runs locally, that's the model the app keeps using. With a closed API, the model behind the endpoint can be updated or retired, and my test results would quietly stop being true. A secret test that runs once only means something if the model stays the same.
Trying another model was easy. Comparing E2B with E4B meant pulling another model with Ollama and running the same tests.
It costs nothing to run.
The Spirit of It
Día de los Muertos is about remembering the people who came before us. A family tree is a quiet version of the same thing: a place where people who are gone still have a name, a date, a face.
The part of Tell the Tree I care about most is a small one: every fact keeps the sentence it came from. Not just a date in a box, but the words someone used when they told it.
My old website lost everything at once. This time, the people, the photos and the words all stay in a file on my own computer.
Prize Categories
Best Use of Gemma. Gemma 4 E2B runs locally through Ollama and reads every sentence. The app is designed around what a small local model is good at (copying words out of a sentence) and what I'd rather not trust it with (deciding what a relationship means), and I measured both, including where it fails.
Credits
- Villa Diodati photo: Robertgrassi, public domain, via Wikimedia Commons
- Fonts: Atkinson Hyperlegible and IM Fell English, SIL Open Font License
- Gemma by Google DeepMind, run with Ollama; FastAPI, React Flow and dagre
The full story, mistakes included, is in my DEVLOG.
Thanks for reading. And if your family history also lives on a website you don't control, maybe export it today.
來源:DEV Community · dev.to

