Lorna Wanjiru
Back home

Zanira AI Customer Assistant

A dual-provider LangGraph ReAct agent (GPT-4o-mini by default, switchable to Claude via config) with 17 tools for inventory, orders, and payments, sharing a Postgres database directly with the Django backend, and serving customers over WhatsApp, web, and Instagram from one inbox.

~94%
Autonomous resolution
17
Tools
31
Live conversations
Visit Zanira Clothing

Problem

Zanira's customers reach out across WhatsApp, the website, and Instagram expecting instant, accurate answers on stock, sizing holds, order status, and payment (M-Pesa, cash-on-delivery). Answering manually across three channels doesn't scale, and generic chatbots aren't safe to trust with live inventory or payment details.

Solution

Built a LangGraph ReAct agent (create_react_agent) with 17 tools spanning product search/stock/colors, order status, customer/loyalty lookup, active offers, and WhatsApp-specific flows like size-hold creation/extension, COD finalization, and M-Pesa payment details. The agent connects directly to Zanira's Postgres database via psycopg2 connection pooling and raw SQL for low-latency reads, while all writes and business logic stay centralized in the Django backend: one source of truth, no data drift. Conversation memory runs on Redis, with an atomic Lua script for history append (safe under concurrent read/write) and a TTL-tracked "silence" key that triggers WhatsApp follow-up nudges after 4h/8h/12h of no reply. A rule-based "simple responder" short-circuits common queries before they ever reach the LLM, keeping cost and latency down. The whole thing runs as a FastAPI + Uvicorn service, Dockerized and deployed on Railway, alongside the Django REST backend, a Next.js 14 storefront, and a separate Next.js admin dashboard.

Outcome

Currently handling 31 customer conversations live across WhatsApp, website, and Instagram (29 active, 2 escalated to a human). That's a ~94% autonomous resolution rate across 28 unique customers, all routed through one unified inbox.

Engineering highlights

  • Diagnosed and fixed a stale-context reliability bug: the model trusted its own earlier stock claims instead of re-querying inventory. A single upfront instruction wasn't enough, so it was fixed by repeating the re-check instruction alongside the live message.
  • Added an allowlist guard on tool-generated image URLs before they reach WhatsApp, preventing a hallucinated or injected URL from being sent to a customer.
  • Cost-aware routing: a rule-based responder handles common queries before any paid model call.
  • Obtained WhatsApp Cloud API and Meta (Instagram messaging) developer access, worked from the provider docs, and tested webhooks and message flows against test numbers before going live.
  • A parallel non-AI "Smart Accountant" module in the Django backend (fabric/labour/overhead costing, margin-targeted pricing suggestions, sales-velocity restock alerts, P&L/cash-flow reporting) shipped alongside the AI work, showing this isn't just LLM plumbing.

Stack

LangGraph
LangChain
FastAPI
PostgreSQL
Redis
Docker
Railway
GPT-4o-mini / Claude (swappable)