跳到正文
DEV Community· dongwei-polyred·· 2 小時前AI 評分49

FollowUp Local:以本機 Gemma 分析客戶停止回覆的原因

FollowUp Local: a Gemma model on your laptop that tells you why the customer went quiet

AI 導讀

FollowUp Local 讓用戶透過 Ollama 在本機執行 Gemma,分析聊天銷售中客戶停止回覆的階段與顧慮,並提供對話引文、跟進訊息及建議發送時間。在 8 vCPU、無 GPU 的電腦上,gemma3:4b 每次約需 15–24 秒,gemma3:1b 約需 6–9 秒。對話資料不會離開裝置,無須 API key、帳戶或按訊息付費。

正文

This is a submission for the Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle

What I Built

Most small sales don't die with a "no". They die with "let me check with her and get back to you", and then nothing.

FollowUp Local is a small tool for people who sell through chat: someone making candles and taking orders over Instagram DMs, a bike mechanic booking repairs on WhatsApp, a private tutor talking to parents on WeChat. You paste the conversation, and a Gemma model running on your own machine tells you:

  • where the customer is stuck: one of eight stages, such as waiting_on_someone_else, price_hesitation, comparing_options, gone_quiet
  • the real concern behind their words, which is often not what they literally said
  • one line of evidence, quoted from the customer
  • the next message to send, and when to send it

Here is what it said about a (fictional) wedding-favour order that stalled:

Stage: waiting_on_someone_else
Stuck on: She needs her fiancée to approve the sample.
Real concern: She's seeking reassurance about the label quality and wants to see it before committing to a larger order.
Evidence: "Let me check with her and get back to you"

Earlier in that chat the customer had mentioned seeing labels "that peeled off in photos". The model connected that to the stall, and that is the part I actually care about. "Follow up in 2 days" is easy. Spotting that the hesitation is really about the sticker is the useful bit.

Who would pay for it? Solo sellers and tiny shops whose income depends on a few dozen open conversations at a time. A tutor who turns one extra "I'll ask my husband" into a booking gets paid back for a year of a small subscription. I think there are two realistic ways to sell it:

  1. A one-time paid download, a packaged desktop app with the model bundled, for people who will never open a terminal.
  2. A niche version for one trade, such as tutoring centres or wedding vendors, with stage names, signals and example replies tuned to how that trade's customers actually hesitate.

Because inference runs on the customer's own hardware, each extra user costs me nothing to serve. That is what makes a cheap price workable at all (more on that below).

Demo

A real, unedited 32-second run on a CPU-only Linux box with no GPU. Paste a chat, click once, and gemma3:4b answers in about 19 seconds:

FollowUp Local demo

The CLI does the same thing for people who prefer a terminal:

CLI output

It also handles Chinese chats. For the bundled tutoring sample, where a parent says the price is "有点贵" (a bit expensive) and that she'll ask the child's father, it labels the stage price_hesitation, picks up that a previous course "didn't work", and drafts a reply in Chinese that leads with the free diagnostic trial lesson.

Code

GitHub logo dongwei-polyred / followup-local

Paste a customer chat, a local Gemma model (Ollama) tells you where they're stuck and writes the next follow-up. Nothing leaves your machine.

FollowUp Local

Paste a customer chat. A Gemma model running on your own computer (via Ollama) tells you:

  • where the customer is stuck (waiting_on_someone_else, price_hesitation, gone_quiet, ...)
  • the real concern behind what they said
  • one line of evidence quoted from the chat
  • the next message to send, and when to send it

Nothing leaves your machine. No API key, no account, no per-message cost.

Built for the DEV Hacktoberfest 2026 Open-Source AI Challenge, Week 2 ("Side Hustle"), between Oct 12 and Oct 18, 2026.

demo

Who it is for

People who sell through chat and lose deals to silence: a candle maker on Instagram DMs, a bike mechanic on WhatsApp, a private tutor on WeChat Their customer chats are private, and they don't want to paste them into a cloud chatbot.

Quick start

Requirements: Python 3.9+ (standard library only) and Ollama.

ollama pull gemma3:4b          #

…

One Python file using only the standard library, plus three fictional sample chats and their real outputs. MIT licensed.

ollama pull gemma3:4b
python3 followup.py samples/candle_shop_sample.txt   # CLI
python3 followup.py --serve                          # web UI on :8765

How I Built It

Model: Gemma 3 through Ollama. I tried two sizes on the same CPU-only machine (8 vCPUs, no GPU):

model time per chat what I saw
gemma3:1b ~6–9 s Often labelled everything asking_questions, and its messages were generic ("Would you like me to send a picture?")
gemma3:4b ~15–24 s Picked sensible stages, reused the seller's own facts ($8 sample, refunded on order), and answered Chinese chats in Chinese

4B is the default. 1B is still available through FOLLOWUP_MODEL=gemma3:1b for older laptops.

Four things made a small local model usable for this. None of them is clever on its own:

  1. Structured output instead of hoping for JSON. Ollama's format field takes a JSON schema. I give it the six fields and an enum of the eight stages, so the model can't invent a stage or return half a sentence.
  2. One worked example. A three-line example chat ("My partner handles the budget, I'll ask him") with the ideal answer did more for quality than any extra instructions I tried.
  3. Keyword signals as hints, not rules. A tiny pass looks for phrases in the customer's lines only: "check with", "my wife", "问问", "said $", "think about it". It passes them to Gemma as HINT: waiting_on_someone_else, gone_quiet. With the hint, the 1B model went from always answering asking_questions to usually picking the right stage. The 4B model sometimes disagrees with the hint, and that's intended: in the bike-repair chat the hints say three different things, and the model correctly settles on price_hesitation.
  4. Checking the model's quote. The model is asked to copy one customer line as evidence. If the quote it returns isn't actually in the chat, I replace it with the last real customer line. Small models paraphrase, and a made-up quote is worse than none.

The prompt also tells the model to mention only prices and services the seller has already stated, to end with one easy yes/no question, and to avoid fake urgency or new discounts.

What still goes wrong. I'd rather be upfront about this, because it's the reason there's no "send" button. In my test runs the 4B model sometimes:

  • claimed an action that hadn't happened ("I've just sent a photo of the sticker")
  • added a comparison the seller never made ("things the other shop doesn't offer")
  • got a relationship wrong in Chinese, writing "your dad" where it meant "the child's father"

So FollowUp Local writes a draft for a person to read. It doesn't send anything for you. For something going out under a small business owner's name, I think that's the right design anyway.

Why Does Open Innovation Matter?

For this particular tool, open weights are what make it possible in the first place:

  • The data is the most private thing a small seller has. A chat log holds customers' names, budgets, family situations, and sometimes addresses. "Paste your customers' WhatsApps into our cloud" is a hard sell, and it may not even be the seller's to share. With Gemma running locally, the chat never leaves the laptop. The UI says so, and you can check it by unplugging the network.
  • The economics work at a small-business price. The value of each analysis is real but small, and a seller may run dozens a day. With a hosted API every analysis costs me money, so I'd have to charge per message or as a subscription. Locally, the marginal cost is zero, so a one-time price is possible.
  • Model size is a dial I control. Because the weights are open, I can choose 1B for an old laptop or 4B for better answers. And the "niche version" idea from above is really a fine-tuning project: a Gemma tuned on one trade's (consented) conversations. That's something you can do with open weights and can't do with a closed endpoint.
  • No lock-in for the seller. If I stop maintaining this, the tool and the model still run on their machine.

A closed frontier model would probably write slightly nicer follow-ups. But for this user, the privacy and cost arguments matter more than the last bit of polish.

Prize Categories

  • Best Use of Gemma: Gemma 3 (4B, with 1B as a lighter option) runs locally through Ollama and is the core of the product. It does the stage classification, the concern analysis and the bilingual message drafting, using schema-constrained JSON output.

來源:DEV Community · dev.to