ReplyShelf:開源模型找出你已寫好的回覆
ReplyShelf: an open model finds the reply you already wrote
ReplyShelf 以開放權重模型搜尋已審核並儲存的問答卡,找出與新問題語意最接近的舊問題,並顯示原有回覆供用戶檢視及複製。模型使用 Xenova/all-MiniLM-L6-v2;在 8 條合成改寫問題的測試中,語意搜尋和 Jaccard 詞語重疊法均有 6 次找出預期卡片。應用程式在瀏覽器本地運行,無需 API key 或模型帳戶。
This is a submission for the Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady.
What I Built
A good support reply is work you have already done: you found the right words, checked the policy, and made the next step clear. When the same question arrives in different words, finding that reply can become another task.
ReplyShelf gives those answers a second life. Save a reviewed question-and-answer card. Ask a new question. A small open-weight model finds the closest meaning, and the app shows your exact saved reply alongside the question it originally answered. Review it, copy it, and make it personal.
The point is a quieter inbox, with a human still making the decision. The model has one job: help find the card.
This is a new project built during this challenge’s window. The demo’s eight policies and all evaluation questions are fictional. I have not tested it with real customer records or claimed measured hours saved.
Demo
Open ReplyShelf — a working browser app, with no API key or model account required.
Try this short path:
- Click “My accountant needs proof of payment.” The stored question says “invoice or receipt,” so the words differ. The semantic match finds the invoice card.
- Read the original question and exact saved reply. Click Copy this reply only after reviewing it.
- Try the weather question. The app withholds a ready-to-copy answer because the shelf has no close match.
- Open My shelf and add a reviewed reply of your own. Export a JSON backup when you want one.
- Open Behind the shelf and run the local comparison. Every result, including misses, is inspectable.
First use downloads about 46 MB of model/runtime assets from the app’s own site. It needs a modern browser with WebAssembly and an initial internet connection. Offline operation is not guaranteed.
Code
Source on GitHub · MIT application license.
The README explains local setup, model provenance, data handling, and limitations. The fixed asset manifest records SHA-256 hashes. The application can be served as static files; there is no application database or inference backend.
How I Built It
The core is Xenova/all-MiniLM-L6-v2, an Apache-2.0 open-weight sentence embedding model, running through Transformers.js 3.8.1 and ONNX Runtime’s WebAssembly backend in a Web Worker.
Mean pooling and normalization produce 384-dimensional vectors. Cosine similarity ranks saved questions against the incoming question. A saved answer stays exact; the model does not rewrite a refund policy, invent a deadline, or send a message.
The UI shows the source question because a plausible-looking reply can still address the wrong intent. Below similarity 0.42, it withholds a ready-to-copy reply. If the two closest scores are less than 0.06 apart, it flags ambiguity and shows alternatives. These are hand-set heuristics, not calibrated probabilities or safety guarantees.
The comparison did not produce a victory lap
I tested eight fixed synthetic paraphrases against the same eight-card shelf and compared the model with simple Jaccard word overlap. Both methods retrieved the expected top card 6 out of 8 times.
The interesting part was where they disagreed:
| Question | Semantic result | Word-overlap result |
|---|---|---|
| “My accountant needs proof that I paid.” | Invoice: correct | Refund: incorrect |
| “I switched to a different mailbox. Can I update my profile?” | Email change: correct | Export: incorrect |
| “Our new colleague needs access to the shared space.” | Ownership transfer: incorrect, flagged ambiguous | Invite: correct |
| “Someone else will be in charge of this workspace.” | Invite: incorrect, flagged ambiguous | Transfer: correct |
All three unrelated questions were withheld. In this tiny demonstration, both semantic misses were flagged ambiguous. That is useful evidence about these examples, not proof that the thresholds catch every error. The full set is in core.js, and the app runs it locally so the claim can be checked.
A Windows Chromium run completed the comparison in 120 ms after model initialization. Timing varies by device and cached shelf vectors. It excludes the initial download and is not a service-level promise.
Privacy changed the implementation
The first version loaded the AI runtime from a CDN. During the final review, I packaged the fixed runtime, WASM files, tokenizer, and model with the site and removed external fonts. Remote model loading is disabled. A deployed-header check then found that the host ignored the extra header file. I changed worker startup to a Blob bootstrap that inherits the document’s meta content policy, with a fixed same-origin module import. The policy restricts connections to the app’s origin. The source documents the additional response headers this host does not provide; I do not claim they are deployed.
Only card IDs and saved questions go to the worker; answer bodies stay in the UI. Incoming query vectors are not retained in the reusable vector cache. Shelf vectors live in worker memory, and the cards live in this browser’s local storage. Text is rendered as text, including imported content. Imports have size and field limits and ask before replacing a shelf.
I checked the actual search with the policy enabled, tested a 390-pixel layout, and ran ten unit tests covering ranking, ambiguity, import validation, duplicate IDs, and malformed data. This is a focused review, not a claim of a complete security audit. Browser storage is not app-encrypted; do not use the demo for secrets or sensitive customer records. Hosting providers can still keep normal access logs.
A shelf should feel like a shelf
The interface uses cream paper, terracotta, forest green, and restrained serif type. Two AI-generated still-life illustrations carry the idea into the product: a card returning from a wooden shelf to an envelope, and a card tray with a magnifying glass. They are project artwork, not screenshots of a feature. The interface screenshot above is the working app.
AI coding assistance and image generation were used to build this project, and an AI agent drafted this post. Human direction included the request for the visual redesign and approval to publish. The model’s retrieval role, actual comparison results, source, and limitations are disclosed here so the work can be evaluated directly.
Why Does Open Innovation Matter?
Open weights make this small feature practical to run on a user’s device. Open runtime code makes it possible to inspect the loading path, package the files together, and remove the inference service dependency. Open application code lets someone change the shelf schema, review the threshold rules, or replace the model without asking permission from an API vendor.
The model is part of the application people can inspect and run. That is especially useful for a tool whose central promise is keeping a small piece of work close to its owner.
The Lazy Payoff
The repeat task becomes ask → review → copy. The setup work is collecting answers worth keeping. The app saves the rummaging and the rewrite when a suitable answer exists, while leaving the final decision to the person replying.
The next useful experiment is a larger, consented support-question set with a separate threshold-calibration split. This demo has no real-user time study. For now, the payoff is deliberately small and testable: give an answer you already trust another useful day.
來源:DEV Community · dev.to

