Build a WeChat Support Bot with an LLM API (2026)
A minimal WeChat customer-service bot: message hooking, LLM reply generation, rate limiting and cost control — using one OpenAI-compatible key.
"Add AI support" doesn't mean running a flagship model. Ninety percent of support traffic is status checks, price questions and repeated explanations — gpt-4o-mini-class models handle it, at 1/30th the cost. Here's a deployable architecture focused on model tiering and cost math.
Architecture
WeChat message → gateway → router ─┬→ budget model (gpt-4o-mini / gemini-flash-lite)
└→ premium model (claude-sonnet-5, hard cases only)
↓
session store (Redis, last 10 turns)Three design decisions:
- Gateway owns the WeChat protocol (official WeCom/customer-service APIs), decoupled from models
- Router picks the model per message — the core cost lever
- Session store caps context growth
Model tiering
Three routing strategies, simplest first:
Keyword split: "price / refund / shipping / how to" hits the budget model with a knowledge base; "error / bug / exception" or explicit human requests escalate.
Confidence escalation: budget model answers, then a cheap yes/no call judges "was this answer good?" — uncertain answers get re-answered by the premium model.
Time-based mixing: premium models during business hours, budget models nights and weekends.
Prices on zaimod (November 2026, USD per 1M tokens):
| Role | Model | Input | Output |
|---|---|---|---|
| Routine answers | gpt-4o-mini | $0.16 | $0.62 |
| Backup | gemini-3.1-flash-lite-preview | $0.25 | $1.50 |
| Escalation | claude-sonnet-5 | $4.00 | $20.00 |
| Chinese-first | doubao-seed-2-0-mini-260428 | $0.50 | $3.00 |
Core code (Python)
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["ZAIMOD_API_KEY"],
base_url="https://api.zaimod.com/v1",
)
CHEAP = "gpt-4o-mini"
PRO = "claude-sonnet-5"
COMPLEX_HINTS = ("error", "bug", "exception", "broken", "why does")
def pick_model(text: str) -> str:
if any(k in text.lower() for k in COMPLEX_HINTS):
return PRO
return CHEAP
def reply(history: list[dict]) -> str:
model = pick_model(history[-1]["content"])
resp = client.chat.completions.create(
model=model,
messages=[{"role": "system", "content": SYSTEM_PROMPT}, *history[-10:]],
max_tokens=600,
temperature=0.3,
)
return resp.choices[0].message.contentDetails that matter:
max_tokens=600— support replies shouldn't rambletemperature=0.3— determinism over creativity- Truncate to the last 10 turns; longer conversations should route to a human anyway
Knowledge beats model upgrades
The bottleneck in support quality is knowledge supply, not model IQ. Structure your product info, price list and policies into documents, retrieve by keyword, and inject into the system prompt. Skip the vector database at first — exact match plus tokenised search covers most catalogs; add embeddings when it stops.
The cost math
2,000 messages/day, 1,500 input tokens each (with KB injection), 400 output:
- 85% on gpt-4o-mini: 2M × $0.16 + 0.55M × $0.62 ≈ $0.66/day
- 15% escalated to claude-sonnet-5: 0.45M × $4 + 0.12M × $20 ≈ $4.2/day
- Total ≈ $4.9/day, roughly $150/month
Running everything on claude-sonnet-5 would cost $1,100+/month for the same traffic. Tiering saves 86%.
Launch checklist
- [ ] Top questions covered by the knowledge base, not model improvisation
- [ ] Escalation to premium model or human works and is logged
- [ ] Model name and token usage recorded per message for reconciliation
- [ ] max_tokens and context turns capped
- [ ] Sensitive-word filtering runs before the model
Grey-launch for a week, reconcile the bill, watch the human-handoff rate, then scale.
One zaimod key runs every model above →