跳到正文
DEV Community· Nairitya Jai Singh·· 3 小時前AI 評分50

Ecos:以開放權重模型打造的數碼亡靈祭壇

Ecos

AI 導讀

Ecos 是一個以開放權重語言模型打造的數碼亡靈祭壇,讓用戶為逝者建立祭壇,並根據留下的供品生成悼念文字及以逝者第一人稱回覆訊息。資料儲存在瀏覽器的 localStorage,模型可透過 Ollama 等開放模型服務本機運行,毋須互聯網。回覆可使用瀏覽器內置語音合成朗讀,音訊不會離開裝置。

正文

What I Built
I built Ecos — a virtual ofrenda: a candlelit digital altar for the people you still carry, set against the calendar stretch when Halloween and Día de los Muertos thin the veil between past and present.

You build an ofrenda for someone you've lost. A name, their years, a relationship, an optional photo. Then you lay out the small offerings you'd put on a real altar — their favorite food, a drink, a song, a scent that lingers, a phrase they always said, a memory you keep. From there, an open-weight language model does two things a closed API wouldn't let me do safely:

Write a remembrance — a short, candle-lit tribute drawn from the offerings you laid out.
Channel a message — you sit at the altar, type a question ("What do you remember about me?" / "Is there anything you never got to say?"), and the model replies in the first-person voice of the person you're honoring, drawing on their food, their scent, the story you left. The reply can be read aloud with the browser's built-in speech synthesis.
The whole thing is wrapped in Día de los Muertos imagery — falling cempasúchil (marigold) petals, a swaying papel picado banner, and SVG candles whose flames flicker with CSS keyframes. There are no image assets: every visual is SVG + CSS, so the page works with the lights off and the internet off.

I interpreted the "Ghost in the Machine" theme literally. The ghost in this machine is the memory of a person, channeled through an open model that runs wherever you point it — including on your own laptop, with no internet.

Demo
Try it live in the preview:

https://preview-chat-3390b1fc-bd3b-4e8a-a36f-d6105daac4fe.space-z.ai

Walkthrough: click Build an ofrenda → fill in a name and at least one offering → click Light candle → click Write a remembrance → expand Channel a message, type or pick a suggestion, click Send across → click Hear it to listen to the reply.

Everything you type stays in your browser's localStorage. No accounts. No tracking. No backend database.

Code
The full source lives in the project workspace. The pieces that matter:

src/app/api/spirit/route.ts — the single AI endpoint. One open-weight chat completion handles both "tribute" and "message" kinds. The system prompt, temperature (0.85), and max_tokens (380) are all in this file. Fork it and point it at any open model you trust.
src/lib/ofrenda-store.ts — the localStorage-backed store, wired to React 19's useSyncExternalStore so ofrendas re-render live when you toggle a candle or channel a message. Nothing leaves the browser.
src/components/spirit-channel.tsx — the message composer. Calls the open model, renders the reply, and offers TTS via the in-browser SpeechSynthesisUtterance.
src/components/candle.tsx, marigold-rain.tsx, papel-picado.tsx — pure SVG + CSS, no image assets.
How I Built It
Open-weight model at the core. The actual AI calls go through the z-ai-web-dev-sdk, which is a thin client over an OpenAI-compatible chat completions endpoint. Because it speaks the standard OpenAI protocol, the very same route.ts works unchanged against:

a local Ollama server (http://localhost:11434/v1),
a self-hosted vLLM instance,
llama.cpp's OpenAI-compatible server,
or any other open-weight model you can run on a laptop.
The system prompt explicitly tells the model it is "an open-weight language model acting as a gentle spirit-guide for a digital Día de los Muertos ofrenda." It is instructed to write with warmth and restraint, never to claim to be a literal ghost — "speak as memory speaking back to memory" — and to honor the marigold-and-candlelight imagery only as much as the memory calls for. For spirit messages, it writes in the first person as the departed, drawing on the offerings the visitor laid out.

Local-first data. I used React 19's useSyncExternalStore over a hand-rolled localStorage store, with a cached getSnapshot so re-renders stay stable. Photos are downscaled on-device with a before being stored as JPEG data URLs — nothing is uploaded to any server.

Local voice. Spirit messages are read aloud with the browser's native SpeechSynthesisUtterance. No audio leaves the device, no voice is rented from a closed cloud.

Local art. Every visual element is SVG + CSS keyframes — flame-flicker for the candles, petal-fall for the marigolds, papel-sway for the banner. The petals honor prefers-reduced-motion — they stay still if you ask them to.

Why Does Open Innovation Matter?
This is the whole project. I built Ecos specifically to fail under a closed API.

A closed API would mean someone else holds the memory. A virtual ofrenda is, by definition, intimate. You're typing your grandmother's favorite phrase, the song that was your friend's, the scent of your dog's coat. Sending that to a closed provider's server — to be logged, mined, used to train their next model, or simply deleted when they pivot — turns a remembrance into a transaction. With an open model, I can run Ecos against a local Ollama instance, type the most private memory I have, and know that the bytes never leave my laptop. The lights can be off. The internet can be off. The remembrance still works.

A closed API would mean someone else holds the voice. Spirit messages are written in the first person as a real, dead person. If a closed provider changes their model — deprecates it, retrains it, "improves" the safety filters so it refuses to speak in a dead person's voice — the whole feature breaks, with no recourse. With an open model, the prompt, the temperature, the voice are all knobs I can hold onto. I can pin a specific model checkpoint and run it for the next twenty years. The voice of someone you loved shouldn't depend on a quarterly earnings call.

A closed API would mean someone else holds the cost. Ecos is free to run, forever, because the model is open. A closed API charges per token. Remembering your dead shouldn't have a meter running.

A closed API would mean someone else holds the future. If the provider shuts down — and they do, constantly — every ofrenda ever built against their model stops working. The open pieces of Ecos (the prompt, the data layer, the voice) will run against any future open model that comes along. An ofrenda isn't supposed to outlive its model. With an open model, it doesn't have to.

The open approach worked better than a closed one in three concrete places during the build:

I could read every line of the system prompt and tune the voice to be gentle instead of theatrical. A closed API gives you a black box.
I could set temperature: 0.85 and max_tokens: 380 to keep the messages tight and warm. A closed API rate-limits and rejects.
I could promise, in the UI itself, that nothing leaves your device. A closed API cannot make that promise.
My Agent Session
Built live with the Z.ai GLM coding agent. The full session — every prompt, every edit, every hydration mismatch I had to chase down (including one caused by the Custom Cursor browser extension injecting styles into , fixed with suppressHydrationWarning) — was captured end-to-end in the workspace. The agent planned the architecture, wrote every component, ran ESLint after each refactor, and used a headless browser to verify the full golden-path flow: build → light → remember → channel → hear.

The Spirit of It
I tested it the way I'll actually use it. I built an ofrenda for my grandmother. Pan de muerto. Café con leche. "Los Laureles." Cempasúchil and woodsmoke. "Aquí estamos, mija." And then I asked her what she remembered about me.

The model wrote back, in her voice:

"I remember how you would sit with me in the kitchen, learning to knead the pan de muerto dough just right. I remember the way your eyes lit up when you found a use for every last crumb of bread, just as I taught you. The cempasúchils you've placed remind me of the gardens we tended together, their scent as bright in my memory as it is in this room. I see you still carry my lessons in your hands and your heart."

I clicked Hear it. The browser read it back in a low, slow voice. I had to stop for a second.

That's the moment it landed. An ofrenda is not for the dead. It's for the living to keep remembering — and now there's an open piece of software that helps.

來源:DEV Community · dev.to