[KongchangAI]
· 4 min read· 2,234 words

Reply Desk: A Review Reply Assistant for Small Businesses That Keeps Data on-Device

Reply Desk: A Review Reply Assistant for Small Businesses That Keeps Data on-Device

Open-source Gemma 3 1B lets this review reply assistant run entirely in-browser, balancing privacy and low cost.

Reply Desk is a browser-based review reply assistant from the Hacktoberfest Open Source AI Challenge, built for small businesses too busy to reply to reviews. Running Gemma 3 1B in a Web Worker via Transformers.js with no account, API key, or server, it flags urgent reviews with keyword lists, has the model distinguish mixed from negative sentiment, and drafts on-brand signed replies that steer unhappy customers to the owner's private contact—keeping all customer data local. Key lessons: give a 1B model one task, use word lists for deterministic checks, and solve three CPU-path issues. Open weights underpin its privacy pledge and zero-marginal-cost pricing.

The Review Dilemma for Small Businesses and a Hacktoberfest Experiment

Corner bubble tea shops, barbershops, clinics, tutoring centers, and home bakeries increasingly depend on their ratings on Google and Zomato. Replying to every review helps business, but the person behind the counter simply doesn't have time to do it. Worse, the reviews that actually matter—"found a hair in my food," "the staff was rude"—often get buried under twenty "the milk tea is great!" comments.

In week two of the Hacktoberfest Open Source AI Challenge, in the "side hustle" track, developer Yash11778 submitted Reply Desk, a browser-based review reply assistant built specifically to solve this problem. Its core principle is refreshingly direct: the customer's own words never leave the counter.

Reply Desk project source page

Three Things Reply Desk Solves

Reply Desk's functionality boils down to three actions:

  1. Pin urgent reviews to the top. Complaints involving food safety, health, money, and employee conduct are flagged as "Today" and jump to the front the moment they're pasted in.
  2. Detect the sentiment of each review: positive, mixed, or negative.
  3. Draft a reply in the owner's voice, signed with the owner's own name. Unhappy customers are directed to the owner's private contact method (such as a WhatsApp number) rather than being argued with in public.

The owner just needs to read, tweak, copy, and post. If the sentiment is wrong, click the correct button, and the system redrafts.

All of this runs on an open-weight model, Gemma 3 1B, entirely within the browser tab. No account, no API key, no server, no data uploads.

Real Output: A Laptop Without a GPU

The most convincing part comes from real test output. On a laptop with no GPU at all (pure CPU, running in-browser), the results generated for a fictional cafe "Chai Point Corner" and its owner "Priya" were as follows:

Review: Found a hair in my poha. Disgusting. I want a refund. Flag: Today: Foreign object found in food · Sentiment: Negative Reply: I sincerely apologize for the unpleasant experience with your poha. I'm very sorry your experience was so disappointing. Please contact me directly at 98765 43210 so we can discuss further and resolve this properly. I value your feedback and want to make sure you're satisfied. — Priya

Review: Waited 25 minutes for two sandwiches, and the guy at the counter was rude when I asked. Flag: Today: Employee conduct · Sentiment: Negative Reply: Thank you for your feedback. I sincerely apologize for the delay and for your experience with our staff. I want to assure you that I will look into this immediately. Please contact me directly at 98765 43210 so we can discuss further. — Priya

Review: Nice ambience, and the owner auntie is friendly. But the sandwich was a bit soggy. Sentiment: Mixed Reply: I'm sorry to hear you had a disappointing experience. Thank you for your feedback. I will certainly take your comments about the sandwich into consideration and look into what went wrong. — Priya

These replies aren't literary masterpieces, and they don't need to be. They're polite, specific, signed, and never invent discounts or fake phone numbers—something that took the developer considerable effort. The third one also shows why owners need to review before posting: it skips thanking the "friendly owner auntie," which a human can add back in five seconds.

Gemma 3 1B is the smallest version in the third generation of Google's Gemma series of open-weight language models, released in 2025, with roughly 1 billion parameters. Compared to large models with tens or hundreds of billions of parameters, 1B-class models offer the advantage of being small, fast at inference, and runnable on consumer hardware or even in a browser—at the cost of noticeably weaker reasoning and instruction-following ability. They're more likely to ignore complex formatting requirements and more prone to wavering judgments on ambiguous inputs. The two uses in this article (deciding whether sentiment is mixed or negative, and drafting replies) deliberately keep task complexity low, precisely to accommodate this characteristic.

Transformers.js is a JavaScript library from Hugging Face that lets Transformer models, previously only runnable in Python, be loaded and run directly in the browser or Node.js. It relies on ONNX Runtime Web (onnxruntime-web) as its underlying execution engine, running PyTorch-exported ONNX models in the browser, with WebGPU or WASM as optional backends.

Web Worker is a background thread mechanism provided by browsers, where scripts run without blocking the main thread's UI rendering. Both model loading and inference are time-consuming, and placing them in a Worker prevents the page from freezing after pasting a review.

Technical Architecture: A Quick Diagram

The project's processing pipeline is designed quite clearly:

Paste review ──► Split by blank lines
             ──► Keyword check: urgent? (instant, no model)
             ──► Complaint words? No ──► Positive (no model)
                                        Yes ──► Gemma: mixed or negative?
             ──► Gemma: draft reply using the prompt for the given sentiment
             ──► Cleanup: strip small talk, placeholders, duplicate signatures

The model runs in a Web Worker via Transformers.js, using onnx-community/gemma-3-1b-it-ONNX. It uses 4-bit weights on WebGPU and 8-bit on CPU.

Lesson One: Give a 1B Model One Task, Not Three

The developer's initial prompt asked Gemma to simultaneously classify sentiment, flag urgency, and write a reply, all while following a fixed format. The result: the model completely ignored the format, producing things like **First line: POSITIVE**. For a real complaint, it also wrote:

Please contact Priya directly at [Priya's phone number or email]

Two changes fixed the problem: one prompt per task, separating classification from reply writing; and one prompt per sentiment, since "apologize if the review is bad" made it apologize to satisfied customers too. So the code first determines sentiment, and each sentiment has its own single-line instruction:

const TASK: Record<Mood, (b: Business) => string> = {
  positive: () => 'Thank them for their review.',
  mixed: () => "Thank them for the good parts they mentioned, and say plainly that you'll look into what they didn't like.",
  negative: (b) => `Apologize only once, make no excuses, and ask them to contact you at ${b.contact} so you can make it right.`,
};

The owner's real contact information is passed in, and the prompt explicitly states "do not invent phone numbers, emails, discounts, or promises." A small cleanup pass afterward strips bracketed content, openings like "Okay, here's a reply:", markdown formatting, and duplicate signatures.

Lesson Two: Use a Word List Wherever You Can Instead of a Model

Missing food-safety complaints is the only truly serious error, so urgency detection uses a pure keyword list—hair, cockroach, sick, food poisoning, stale, refund, rude, and so on. It's predictable, instant, and makes the urgent card appear at the top before the model has even finished loading.

The same goes for obviously happy reviews. The CPU (8-bit) version loves ambiguity, classifying "best masala chai around!!" as "mixed." Now, reviews without any complaint words (but, though, cold, slow, rude, not...) are directly marked positive without asking the model. Gemma only handles the hard cases: mixed or negative.

Lesson Three: "Runs in the Browser" Has Fine Print

Getting the no-GPU path working required three fixes, all discovered by actually running things rather than reading docs:

  1. The 4-bit version crashes on CPU: Could not find an implementation for GatherBlockQuantized. The onnxruntime-web WASM backend doesn't have this kernel, so the CPU path was switched to load the 8-bit version.
  2. The 8-bit version then 404s: The model repo's config says the weights are in external data files, which is true for the other versions, but int8 is a self-contained single file. Passing use_external_data_format: { 'model_int8.onnx': 0, … } fixed it.
  3. It only ran on one CPU core. WASM threads require SharedArrayBuffer, which in turn requires the page to be cross-origin isolated. Two headers in vite.config.ts (Cross-Origin-Opener-Policy: same-origin, Cross-Origin-Embedder-Policy: credentialless) got it using all cores. credentialless is key here, because it lets Hugging Face CDN downloads keep working without that server sending extra headers.

Why Open Source Matters Here

The developer argues that open source isn't idealism—it's the precondition for the business model to work:

  • Privacy is the product. Reviews contain customers' names, phone numbers, and complaints about named employees. "The customer's words never leave this computer" is a promise that can genuinely be kept, because there's no server to go to.
  • Zero cost per reply. Hosting a model charges per token, forever. Here the shop's own laptop does the work, so ₹199/month pricing isn't eaten up by API bills. A hosted model would also force him to meter usage, whereas "unlimited replies" is far easier to sell to shop owners.
  • No lock-in. There's no API key to leak, no vendor price hike or model deprecation. If a better small open model appears, swapping it out is a one-line change (the MODEL in worker.ts).
  • Works offline. Once the model is cached, shops with spotty connections can use it fine.

API billing and marginal cost is the key distinction for understanding the business model here. When calling a hosted large-model API, every piece of generated text incurs a charge, and costs grow linearly with user volume, making "unlimited replies" nearly impossible to price under a hosted scheme. But when an open-weight model is downloaded to run on the user's own device, the inference cost falls on the user's CPU/GPU and electricity bill, and the service provider has no per-call cost after the model is released. Marginal cost approaches zero, which is precisely the premise that makes a low-price plan like ₹199/month viable. "Zero lock-in" stems from the same logic: open weights can be freely downloaded, swapped, and cached locally, so a vendor discontinuing support or raising prices won't kill the product.

Target Users and Pricing Logic

This tool targets cafe owners who would never pay for "AI", but who would pay ₹199–299 a month for "reply to every review within two minutes, and you'll never miss another complaint." The same applies to small agencies managing ten local business listings.

Pricing works precisely because of open-source models—the core logic of the "Why Open Matters" section above.

What's Next

The project is MIT licensed, built with TypeScript and Vite, no framework, about 9 kB of app code plus the model runtime. The developer's listed next steps include:

  • Hindi, Marathi, and Hinglish replies, since many reviews are written that way, which would require a larger or fine-tuned model.
  • Per-business tone examples: paste three replies you've written, and have it mimic them.
  • Weekly summaries: "4 people mentioned slow service this week."

In a narrative where large models routinely require data centers to support them, Reply Desk offers a counterexample: put the right small model in the right place, use word lists for deterministic tasks, use the model for fuzzy judgment, and use browser isolation instead of server trust—this may well be the form of AI that small businesses can actually afford.

Background Notes

Several underlying concepts here are worth explaining. Quantization refers to compressing model weights from 16-bit floats down to 8-bit integers (int8) or 4-bit (4-bit), greatly reducing VRAM usage and memory bandwidth requirements, at the cost of a slight loss in precision. The WebGPU backend has dedicated low-bit kernel support for 4-bit quantization, while the WASM backend does not—which is exactly why the GatherBlockQuantized operator had no implementation in problem 1.

ONNX external data format refers to large models' weights not being stored in the main .onnx file, but split into separate .onnx_data files that are read on demand at load time. When only some models in a repo use this layout, the library's default inference can get it wrong, requiring you to manually specify which files are self-contained single files.

SharedArrayBuffer and cross-origin isolation are part of the browser security model. SharedArrayBuffer allows multiple threads to share the same block of memory and is a prerequisite for WASM multithreading; however, because it can be exploited for Spectre-style side-channel attacks, browsers require pages to satisfy "cross-origin isolation" conditions before allowing its use. To achieve this, the server must send both the Cross-Origin-Opener-Policy and Cross-Origin-Embedder-Policy response headers, and the latter's require-corp value blocks third-party resources that don't carry the corresponding header—credentialless is a more permissive value that allows those cross-origin downloads to continue.

One-line Summary

Open-source small model Gemma 3 1B lets a review reply assistant run entirely in the browser, balancing privacy and low cost.

Paragraph Summary

Reply Desk is a browser-based review reply assistant from the Hacktoberfest Open Source AI Challenge, designed for small businesses with no time to reply to reviews. Built on Gemma 3 1B and running in a Web Worker via Transformers.js, it needs no account, API key, or server, and customer words never leave the local machine. It uses keyword lists to instantly flag and pin urgent reviews involving food safety, health, money, and employee conduct; the model then distinguishes mixed from negative sentiment; finally it drafts replies in the owner's voice with a signature, directing unhappy customers only to the owner's private contact. Key development lessons include: give a 1B model a single task, use word lists rather than the model for deterministic judgments, and solve three issues on the CPU path—missing quantization kernels, external data file 404s, and cross-origin isolation for WASM multithreading. Open weights are the foundation that makes its privacy promise and zero-marginal-cost pricing viable.

#Reply Desk#Gemma 3 1B#review reply assistant#Transformers.js#on-device AI#open-source AI#small business tools#browser AI#WebGPU#ONNX Runtime Web
Share:

Related articles