跳到正文
DEV Community· Temiloluwa Valentine·· 3 小時前AI 評分55

Temiloluwa Valentine 打造 Oríkì 離線 AI 家庭記憶檔案工具

Africa's archives were burned. I built a laptop altar for the one that's left.

AI 導讀

Temiloluwa Valentine 打造 Oríkì(程式庫仍名為 Ofrenda),一款在個人手提電腦上運行的離線 AI 家庭記憶檔案工具,以本地 Gemma 將日常家族故事整理成家譜。工具會按家譜缺口提出問題,不會虛構人物或關係;亦可用本地 MediaPipe 從照片分離人物,讓半透明影像呈現在網絡攝影機畫面中。家庭檔案保存在本機,網絡攝影機畫面不會上傳。

正文

This is a submission for the Hacktoberfest Open-Source AI Challenge Week 4: Ghost in the Machine

What I Built

In January 2013, as militants fled Timbuktu, they set fire to 4,202 manuscripts at the Ahmed Baba Institute. Some were centuries old, on mathematics and science. The loss was real, but it could have been far worse. For months before, librarians and families had been moving the collections out in metal trunks, under crates of vegetables, by car, cart and canoe. Roughly 300,000 manuscripts reached safety in Bamako.

Records were also destroyed on purpose in my part of the world. Before many British colonies became independent, officials ran a programme later called Operation Legacy. Some files were burned or sunk at sea. About 8,800 more files were secretly sent to Britain and kept at Hanslope Park, a Foreign Office site. We only know because Kenyan survivors of the Mau Mau uprising took Britain to court in 2011. Those files came from 37 colonies, Nigeria among them.

So much of Africa's written memory was burned, hidden or carried away. What is left is in our heads: the name of a great-uncle, the town a family came from, the story told at a naming ceremony. Those archives are smaller, and they are fading too.

For me, this is not only history. I never really knew my grandparents. The only one I know is my grandmother on my mother's side. My father's mother passed away when I was about six, and honestly, I cannot remember her face. I never knew either of my grandfathers. What I have are stories. I have heard so many of them, told by the people who did know them. Those stories are all that stands between my grandparents and being forgotten, and they live only in the heads of the people telling them.

That is why I built Oríkì (the repo is still called Ofrenda, its first name). It is a small altar that runs on your own laptop. You tell it about your family in ordinary words, like "Tunde had a wife called Ama from Accra." A local Gemma model reads the story and places the people on a family tree. You can add a photograph and write the short memory you are afraid of forgetting.

Then it looks for the thin places, where the tree goes quiet. It does not guess. It lights a candle and gives you a question to ask someone older. If a person has a photo, you can sit with them: they come back as a soft, translucent ghost with a marigold edge, beside you on your webcam.

I read "Ghost in the Machine" the way Día de los Muertos does. A ghost is someone we meant to keep.

Demo

There is no hosted copy, on purpose. Your family file should not sit on a server I would have to ask you to trust. You clone the repo and run one command.

The family in the repo is fictional (the Adeyemis, from Ogbomoso, Ibadan, Lagos and Accra). I made them so you can try everything without putting real relatives into a public repository.

Code

Ofrenda

Oríkì: an offline AI archive for your African family's memory.

Remember me.

Ofrenda is a small altar you run on your own laptop. You tell it about your family in ordinary words. A local Gemma model reads the story and sets the people on a tree: who was whose parent, who moved away, where they were from. You can correct it, add a photograph, and write the short memory you are afraid of forgetting.

Then it looks for the missing branches. Someone has a name and a city and nothing else. The altar does not invent a spouse for them. It lights a candle and gives you a question to ask an older relative.

If there is a photograph, you can sit with them. MediaPipe, on the same machine, lifts the person out of the picture. They come back as a soft ghost beside you on the webcam: translucent…

Run it with ./start.sh, then open http://127.0.0.1:8000. The tests pass (27 of them) and none of them call Ollama.

How I Built It

The server is Python with FastAPI, bound to 127.0.0.1. The page is plain HTML, CSS and JavaScript. The family tree is one JSON file on disk, and photos sit beside it.

Gemma reads the story. The story goes to Gemma through Ollama on the same machine. The default is gemma2:2b, and OLLAMA_MODEL swaps in any other Gemma, such as gemma3:4b. The prompt asks for JSON only and tells the model not to invent people, years, places or memories.

Small models wander, so I do not trust the reply raw. The code strips markdown fences, repairs trailing commas, drops impossible years and drops relationships to people who were never named. If the JSON is unusable, it retries up to three times and shows the model its own error. Then it merges the result into the tree, so telling a story twice does not create two Funkes. "Tunde" lands on Tunde Adeyemi when that is the only Tunde. "Mama" is not guessed when two Mamas exist.

The candles are rules first, model second. I did not want a model to be the thing that notices a gap. The code finds the gaps by looking at the tree: someone with siblings but no spouse, children or memories, a parent whose own parents were never written down, a person who has died with no spouse recorded, and so on. Each gap becomes a question with a real name in it, for example: "Tunde Adeyemi has no spouse or children recorded. Ask [a relative] about him: who he built a life with in Accra, and whether there were children."

When Gemma is running, it may rewrite the wording so a younger relative could say it out loud. That rewrite is checked. A question about a person who does not exist is thrown away, and Gemma cannot add a gap the rules did not find. If Ollama is off, the candles still light with the plain questions. I would rather ask a stiff question than invent an uncle.

The ghost is computer vision, also local. MediaPipe's selfie segmenter, a small model I ship in the repo, lifts the person out of the portrait. The result is feathered, made translucent, and given a marigold halo. If the mask fails, a colour-key fallback tries, and after that a soft oval. The webcam is drawn in the browser with getUserMedia, and the frame is never uploaded. With no camera, the ghost stands in a painted night.

There is also a small built-in stand-in storyteller (OFRENDA_MOCK_LLM=1) that only understands a few sentence shapes. It exists for tests and for laptops without Ollama yet. It is not the product. Gemma is.

Why Does Open Innovation Matter?

A family tree is not a prompt I want to send to a company. A photo of someone who has died is not something I want in a request log or a training set.

Because Gemma is open-weight, the reading of the story happens on the laptop. Once the model is downloaded it costs nothing to run, and it works when the network is in a mood. That matters at home, where data is expensive and the light goes out. I can swap one Gemma for another without rebuilding the page, which matters because not every laptop is the same size.

Because MediaPipe is open, the cut-out is a file in the repo and not a vision API that bills by the face. I can read the mask, reject a bad one and fall back, which a closed API that only returns a finished sticker would not let me do.

This is the same lesson as Timbuktu and the migrated archives. A record kept where someone else can lock it, move it or burn it is not safe. A family's memory should live in the house.

The Spirit of It

The moment that landed for me was small. Tunde, in the fictional family, begins as a name and a move to Ghana, with no one beside him. The altar lights a candle on him and does not invent a wife. Then I typed one sentence, "Tunde had a wife called Ama from Accra," and Ama appeared beside him on the tree. The altar had asked, I had answered, and nothing in between was made up.

But the real reason I built this is closer to home. When I typed in the fictional Adeyemis and watched a candle light up beside someone with no story yet, I thought of my own grandmother, the one I was too young to remember. I do not have her face. I have stories about her, and a few questions I never thought to ask. Oríkì is the thing I wish my family had: a place where those stories are kept, and where every gap becomes a question to ask while there is still someone to answer it.

The fading ancestor is an idea from Pixar's Coco, credited in the README. No Pixar art is used.

If you try it, start with one person your family is about to misremember. One story is enough to hold them.

Prize Categories

Best Use of Gemma. Gemma, running locally through Ollama, turns plain-spoken family stories into a tree and rewrites the elder-questions. I kept the facts in code on purpose, so the model is used where language matters and not as a database.

來源:DEV Community · dev.to