Jewelry WhatsApp Assistant: Keeping Prices Out of the Model

Keep the model away from price numbers with three isolation layers: classification, a single data source, and output scanning.
A "price isolation" design for an Indian jewelry store's WhatsApp assistant: the model never produces prices. Rules plus a small model classify intent, price intents escalate to sales, and non-price FAQs return approved text. Displayed gold rates come only from a single manual record with a 6-hour freshness limit. Output regex blocks numbers next to currency or weight units as a second defense.
Title
Jewelry WhatsApp Assistant: Keeping Prices Out of the Model
Meta Description
How does a jewelry store's WhatsApp AI assistant avoid quoting wrong prices? This article introduces a price isolation design: intent classification first, price questions escalated directly to humans, a single data source with timestamps, and output-side number scanning as a fallback, with complete Python code examples and testing methods.
Article Content
For a WhatsApp assistant serving an Indian jewelry store, the most dangerous failure isn't an offensive reply—it's confidently quoting a wrong number: yesterday's gold rate, the making charge from an outdated price list, or a figure the model simply made up. This article introduces a "price isolation" design: keep the model entirely away from price-related answers, eliminating wrong quotes at the source.

Core Idea: Classify First, Escalate Price Intents Directly to Humans
The first rule of this design is very straightforward: the model never produces numbers. The system first classifies the intent of the user message (rules plus a small model). Once a price-type intent is detected, it never enters the generation stage and is escalated directly to the sales team.
PRICE_INTENTS = {"rate_today", "making_charges", "quote", "exchange_value", "discount"}
def handle(msg):
intent = classify(msg.text)
if intent in PRICE_INTENTS:
return escalate(msg, team="sales", reason=intent)
if intent in APPROVED_FAQ:
return reply(msg, APPROVED_FAQ[intent])
return escalate(msg, team="front_desk", reason="unknown")
For non-price questions, if they match an FAQ reviewed by the store owner (business hours, address, parking, appointments, general policies), the fixed text is returned directly. This content doesn't change daily, so it's safe to let the model "read from the script." All other unknown intents are likewise escalated to the human front desk.
Intent Classification is a fundamental step in dialogue systems: mapping user input to predefined categories (such as "check gold rate," "ask business hours," "complaint") and then routing to different processing paths by category. Common implementations include keyword/regex-based rule matching, embedding-based semantic similarity, and fine-tuned small text classification models. Here a hybrid approach of "rules plus a small model" is used because for price-type intents, recall matters more than precision—it's better to misclassify a non-price question as a price question and escalate it than to miss a single quote request. Rules cover high-frequency expressions (such as "today rate" and "making charge"), while the small model catches variants the rules miss, including Hinglish mixed expressions. The classification result directly determines whether the subsequent generation stage is entered, so the classifier itself also needs continuous regression testing with real messages.
Need to Show the Gold Rate? A Single Data Source with Timestamps
Some store owners want the assistant to share the day's displayed gold rate. In that case, the read must come from a single manually updated record, and if it's past its freshness window, it must be refused.
MAX_AGE = timedelta(hours=6)
def displayed_rate(now):
rec = rates.latest()
if rec is None or now - rec["updated_at"] > MAX_AGE:
return None
return rec
The reply template explicitly states that this is the in-store display rate at a certain point in time, and that the final price is subject to in-store confirmation. The model fills in nothing here—it only replaces placeholders in the template with the value and update time from the database.
Freshness Check (TTL / Freshness Check) is a common technique in data pipelines to prevent "stale data being treated as real-time data." The approach is to attach an update timestamp to each record, compute now - updated_at when reading, and treat it as invalid once it exceeds a preset threshold. Six hours is chosen here because Indian jewelry stores typically adjust their displayed gold rate manually several times a day, and a record not updated for more than half a day is likely to have drifted from the market. Compared with scheduled cleanup at the database layer, read-time validation is simpler and won't let old data through due to a failed cleanup job. For the model, it only comes into contact with validated structured values and timestamps, and does not participate in judging "whether this price is still accurate"—that judgment stays in deterministic code.
Output-Side Fallback: Scan for Numbers Adjacent to Currency/Weight Units
Even for non-price replies, a text scan should be performed before sending: if the generated content contains a currency symbol or weight unit immediately adjacent to a number (such as ₹, Rs, INR, rupees, g, gm, grams, tola), block the send. This catches cases where the model "helpfully" appends an estimate to an unrelated answer.
MONEY = re.compile(r"(₹|rs\.?|inr|rupees?)\s*\d|\d+\s*(g|gm|grams?|tola)\b", re.I)
def safe_to_send(text):
return not MONEY.search(text)
This output check is the second line of defense beyond input classification. With both stacked, the probability of price figures leaking from the model side is pushed very low.
Output Guardrail is a check layer executed after model generation and before the message is sent, forming defense in depth with input-side intent classification. Regex is the lightest-weight option among them: it doesn't judge semantics, only matches patterns, so it's fast and predictable, suitable for catching high-confidence risks like "a currency symbol or weight unit immediately adjacent to a number." Its limitations should be noted: regex cannot recognize numbers spelled out in words (such as "twenty-two thousand"), Unicode variants, or line-broken splits, nor can it distinguish legitimate numbers (such as "we open at 10") from quotes. Therefore it should serve as a last net, not the only line of defense; when it triggers, blocking and escalating to a human rather than auto-rewriting avoids introducing new errors.
Escalation Logs Are More Useful Than Accuracy Metrics
Every escalation should be logged with its reason. After a few weeks of running, the logs will tell the store owner what customers ask about most and how fast staff respond. For frontline operations, this information is more valuable than any model accuracy number—it directly points to which FAQs to add, whom to train, and which process to adjust.
Testing: Build a Price-Blocking Test Set from Real Messages
The test set should come from real (anonymized) messages, including Hinglish and voice-transcription text, asserting that every price-related message triggers an escalation. Every time the classifier or prompt is changed, rerun this test suite. This prevents regressions better than a vague "reply quality evaluation."
Why This Design Is Worth Adopting
Its value isn't in how complex the code is, but in using engineering to lock down "what the model shouldn't do." Price is the most sensitive, most volatile, and most easily hallucination-contaminated type of information in jewelry retail; removing it entirely from the generation path buys a predictable safety boundary. For any vertical-industry assistant that involves real-time quotes, this pattern can be transferred directly.
Disclosure: The author runs NxFlowAI, an AI automation agency in Mumbai; the first workflow audit requires 72 hours.
One-line Summary
Keep the model entirely away from price numbers, using three layers of isolation—classification, a single data source, and output scanning—to eliminate wrong quotes.
Paragraph Summary
The article introduces a "price isolation" design for a WhatsApp assistant serving Indian jewelry stores, with the core principle that the model never produces price numbers. The system first classifies intent using rules plus a small model; when a price-type intent is detected (checking gold rate, making charges, quotes, exchange valuation, discounts), it escalates directly to the sales team. Non-price questions that match an owner-reviewed fixed FAQ return fixed text, while all other unknown intents go to the human front desk. If the owner wants to display the day's gold rate, only a single manually maintained record may be read, and it is refused once older than 6 hours; the reply template clearly marks the time point and defers to in-store confirmation. On the output side, a regex scans for text where currency symbols or weight units are adjacent to numbers, blocking the send as a second line of defense. The author emphasizes that escalation logs guide operations better than accuracy metrics, and that the test set should come from real anonymized messages and be rerun every time.
Related articles

Build an AI Super Employee System at Zero Cost: A Full Breakdown of Automated Agent Workflows
A deep breakdown of the AI super employee system demoed on Bilibili: agent orchestration, digital human voiceovers, map and enterprise lead generation, 24/7 customer service, and legal modules. We analyze the business logic and compliance risks behind zero-cost signup to help entrepreneurs judge the real ROI of this AI digital employee system.

The Essential Difference Between Chatbots and AI Agents: Crossing from Conversation to Execution
What's the difference between a chatbot and an AI agent? Based on the MCP series on the Learn Tech channel, this article uses examples like booking flights and summarizing notes to explain: a chatbot only gives answers, while an agent actually completes tasks through a think-act-observe loop. It breaks down the four core components—model, tools, memory, and goal—as well as MCP's role as a bridge, and discusses agents' applicable boundaries and permission risks.

Free GitHub Repo: 342 Hours of AI Courses, from Math to MCP Servers
A free GitHub repo offers 342 hours of AI courses: 523 lessons across 20 phases, from math fundamentals to agent building and MCP servers. Nearly 100,000 learners have started.