Ecos:記憶即使不完整,仍值得保存
Ecos: A Memory Can Be Incomplete and Still Be Worth Keeping
Ecos 是一款以 Transformers.js 3.8.1 和開源多語言 MiniLM 建構的瀏覽器文字記憶檔案庫,可按語意搜尋,同時保留原文段落及有爭議或未明的日期。搜尋在瀏覽器內執行,故事文字不會傳送至推理服務;Ecos 不會替記憶者裁定不同説法何者正確。作者以 12 條英語及葡萄牙語查詢測試模型,10 條的預期記憶排在首位;這是小型自製實驗,並非通用準確度評測。
This is a submission for the Hacktoberfest Open-Source AI Challenge Week 4: Ghost in the Machine.
What I Built
A family archive has a difficult failure mode: it can become more certain than the people it is supposed to remember.
Someone says a trip happened in 1987. Someone else remembers 1989. A tidy generated biography could quietly choose one. The result would read beautifully, and part of the family’s voice would be gone.
I built Ecos, a small, browser-based archive for written memories. It finds passages by meaning, keeps them attached to the original words, and gives uncertain dates somewhere to stay.
For Ghost in the Machine, I chose the remembrance side of the theme. The “ghost” is a voice still present in a phrase, a recipe or a contradictory account. Ecos retrieves that voice. It does not impersonate the person or write a more polished life for them.
The public collection is entirely fictional: eight short Duarte-family memories, including a repaired coat, a birthday power cut, a recipe measured by touch and an undated letter. These are not my family records or interviews with real people.
Demo
Open Ecos · English / Português
You can read the fictional collection immediately. To try the open model:
- Choose Enable private search. First use downloads about 135 MB of model files. Story text stays in your browser.
- Try a celebration by candlelight. The query asks for “A celebration without electric lights”; the returned source begins with an electricity failure during a birthday supper.
- Open Read original. The highlighted words are an exact slice of the source, with the original line and character range.
- Choose Keep this passage, then open the Remembrance shelf and download a plain-text keepsake.
- Compare the two first river crossing accounts. Clara says 1987; Rui says 1989. Both remain visible. The letter with no date stays undated.
You can also add your own written memory, download a portable JSON archive, reopen it later, or explicitly save an unencrypted copy in this browser. The interface never silently saves your stories to an account.
Code
GitHub repository · MIT application code and original illustration
The repository includes the locked dependencies, fictional collection, source-integrity tests, actual retrieval experiment and a build/deployment workflow. The project and repository were started on October 26, inside the Week 4 window.
How I Built It
The important separation is between finding a passage and deciding what it proves.
For finding, I used Transformers.js 3.8.1 and the open multilingual MiniLM model, pinned to revision 2c4055b12046f11709e9df2c122e59ffbdc2f900. Its q8 ONNX weights run in a browser worker through ONNX Runtime WASM, using one CPU thread.
Each story is split into short passages while retaining offsets into its unmodified source. Mean-pooled, normalized embeddings compare the query with the story body only. Titles, dates and expected test labels are excluded from inference. Results below a cosine similarity of 0.30 are omitted; this cutoff is a heuristic, not a confidence score. Results are explicitly called possible echoes.
The model is essential to this search. If it cannot load, you can still read and export, but the app does not quietly substitute keyword matches and call them model results.
For preservation, ordinary code does the work. It keeps original text, computes citation ranges, sorts contributor-supplied dates and identifies differing years only when contributors supplied the same event label. It cannot decide whether Clara or Rui is right. That limitation is intentional.
I measured the misses, too
I ran the pinned q8 model against 12 authored English/Portuguese queries over the eight fictional stories, alongside a simple stopword-filtered exact-token overlap baseline.
| Method | Expected memory at rank 1 | Expected memory in top 3 distinct memories |
|---|---|---|
| Actual open-model embeddings | 10/12 | 10/12 |
| Exact-token overlap baseline | 1/12 | 2/12 |
The complete results include the failures.
Two related queries returned no close result. One was a broad request about keeping an object to remember someone who died. A more specific description of the grandmother’s apron worked in the browser, so I made the sample prompt more specific. The original evaluation still includes the miss.
I also tried three unrelated queries. Two returned nothing; a fictional question about a chess tournament on Mars incorrectly retrieved the coat memory. That is a useful warning about treating similarity as truth.
This is a tiny authored experiment, not a held-out benchmark or a general accuracy claim. The CPU experiment and actual browser WASM checks are recorded separately. Eight deterministic tests cover source fidelity, uncertain dates, archive validation, untrusted citation metadata and retrieval guards; those tests do not measure model quality.
Why Does Open Innovation Matter?
Here, the practical benefit is control over a very personal input.
The open model lets the browser compare meanings without sending family stories to an inference service. I can pin the weights, inspect the retrieval behavior and ship the same search without a private model key or per-query bill. That choice also makes its limitations reproducible.
It does not make the app magically private. The host receives normal app requests. Hugging Face and its download CDN receive normal request metadata when the model is fetched. A locally saved archive is unencrypted, and downloaded archives contain the stories, names, supplied dates, selected passages and a bounded recent-search receipt. Shared devices and shared downloads still require care.
Offline operation is conditional: the user must cache the app, finish the model download and keep both browser caches. Browser storage can be evicted. A downloaded JSON archive is the portable backup; a text keepsake remains readable even if Ecos disappears.
The Spirit of It
The decisive example is the disagreement about the boat trip. Ecos could have produced one confident sentence. Instead, it shows two accounts with two names and two years.
That leaves the archive a little less neat. It also leaves more of the people in it.
The current scope is deliberately small: written text, up to 40 memories, English and Portuguese search. There is no audio transcription, photo recognition, cloud sync, generated biography or claim of historical verification. I have not tested it with real families or measured a benefit to them.
For this theme, the most useful thing I could build was a place where an incomplete memory does not need to become a complete fiction.
Prize Categories
Best Use of GitHub Copilot — GitHub Actions automation. The challenge page explicitly includes automating a project with GitHub Actions in this category. Ecos uses Actions to install the locked dependencies, run the source-integrity tests, build the app and deploy GitHub Pages. This is the automation being submitted; I do not claim Copilot generated the code.
Built solo by Bruno Fernandes, an Accounting graduate with intermediate programming experience. Codex assisted implementation, documentation and testing. Open components and licenses are credited in the third-party notices.
來源:DEV Community · dev.to


