为花生过敏朋友打造的 SafePlate:浏览器端过敏感知膳食规划器
The Maya story + SafePlate's six features, home screenshot
开发者用 all-MiniLM-L6-v2 嵌入模型(Apache-2.0)配合 transformers.js 与 ONNX Runtime Web,在浏览器本地构建了过敏感知膳食规划器 SafePlate,模型约 23 MB,首次访问下载后可离线运行。
My friend Maya has peanut, tree-nut, and sesame allergies. Every group dinner starts the same way: her squinting at
ingredient lists, googling "does pesto have nuts" (it does — pine nuts), and quietly eating plain rice while everyone else
shares satay.
So I built her SafePlate — an allergy-aware meal planner that reads every ingredient of every recipe for her:
- 🥜 Her profile, not a generic one — name, allergies, and how strict to be ("Sensitive" vs "Severe: flag every trace").
- 🍽️ A verdict on every recipe — All clear, Worth a closer look, or Not safe for Maya — with the exact ingredient that triggered it and why.
- 🕵️ It catches the hidden ones — pesto → pine nuts, Worcestershire sauce → anchovies, marzipan → almonds, tahini → sesame, green curry paste → shrimp paste.
- 🔁 Every flag comes with a swap — peanut sauce → sunflower seed butter, tahini → sunflower seed butter + lemon.
- 🏷️ "Check anything" scanner — paste any ingredient list (a sauce label, a snack bar) and it flags what's risky for her.
- 🗓️ One-click week planner — a full week of safe plates, saved locally on her device.
## Demo
👉 Live demo: https://karleeov-dev-hack.kimi.page
It's fully shareable by URL, which makes for a fun try-it-yourself:
-
https://karleeov-dev-hack.kimi.page?friend=Maya&allergens=peanut,tree-nut,sesame— pre-loaded profile -
https://karleeov-dev-hack.kimi.page?scan=nutella%20spread,%20tahini%20drizzle,%20oat%20milk,%20eggplant,%20honey%20roasted %20peanuts,%20rice%20crackers— auto-runs the scanner on a tricky list. Three of those are dangerous for Maya; three only sound dangerous.
First visit downloads the model (~23 MB); after that it's cached and the whole app works offline.
## Code
https://github.com/karleeov/Maya
No build step, no framework — index.html, app.js, recipes.js, styles.css. The phrasebook, veto table, and swap
list in recipes.js are plain readable data, so adapting SafePlate for a different allergy set means editing a list, not a
model.
## How I Built It
The core is all-MiniLM-L6-v2, an open-weight sentence-embedding model (Apache-2.0), running entirely in the
browser
through transformers.js + ONNX Runtime Web. Ingredients and allergen profiles become 384-dimensional vectors;
cosine similarity is what knows marzipan lives suspiciously close to almonds.
But here's the honest part: embeddings alone were too noisy to trust with someone's health. I validated the scorer
offline against the exact quantized ONNX build the browser ships, and the false-positive ceiling was brutal — rice noodles scored 0.80 (because "egg noodles" exist),
→ eggtomato sauce → fish hit 0.76, butter → tree nuts 0.74. Pure semantic
search would have cried wolf about pancakes and stayed quiet about satay.
So SafePlate is a hybrid:
-
A curated, word-boundary-aware phrasebook per allergen carries precision — it knows
eggplant≠eggandbuttermilk≠butter. - The embedding layer rides shotgun — powering the "semantically close to X (matched term)" explanations, catching long-tail phrasings, and driving the caution tier.
- A small veto table encodes domain truth the model can't know: coconut milk isn't dairy, oat milk is fine, peanut butter contains no butter.
- Severity modes shift the thresholds, because "sensitive" and "anaphylactic" are not the same product. In Severe mode it still raises coconut as a tree-nut caution (the FDA lists it as one) — I'd rather explain a false alarm to Maya than apologize for a missed one.
The model downloads from the Hugging Face hub (with a mirror fallback), caches in the browser, and after that the app —
model included — runs with the Wi-Fi off.
t asking anyone's permission.
- Hackable. If her little cousin has a different allergy set, we edit a data list — not a billing plan.
The honest trade-off: a small open model is dumber than a frontier closed one. That's why the architecture is hybrid —
the open model does what it's good at (semantics, explanations, long-tail matching) and boring curated data does what it's
good at (precision). Open source didn't lower the ceiling; it changed where I put the walls.
来源:Google AI:DEV 作者专属(RSS) · dev.to


