Skip to content
Lu Phone Maw

AI Customer Support

A Gmail support assistant that classifies incoming email, answers routine questions from a curated knowledge base, and hands anything sensitive or uncertain to a person — with Python rules holding the final say.

Focus
AI Systems, Backend Engineering
Core stack
Python/FastAPI, Pydantic AI, Anthropic models, Supabase Postgres, Gmail API
Dashboard
React, TypeScript, Tailwind CSS, shadcn/ui
Deployment
Docker Compose (local)
Gmail thread: a customer asks which paddle board suits a 90 kg rider, and the support bot recommends the 11-foot all-round board, explains why the 10'6" board is too small, and mentions the touring board.

Customer emails

Gmail thread: a customer says their board loses air overnight, and the support bot replies with five valve-check steps and asks for the order number, board size and delivery date if the problem continues.

Troubleshooting

A board losing air gets the valve-check steps from the guidance — and if that doesn’t fix it, the reply asks for the order number, board size and delivery date so a colleague can take over.

Gmail thread in which a customer writes 'I want my money back, this is ridiculous.' and the support bot replies that a colleague will respond within one business day.

Handing off to a person

A refund demand isn’t answered by the AI: the customer gets a short acknowledgement and the thread is flagged in Gmail for the team.

How it decides

Decision pipeline for one email

Diagram

PollerNew Gmail threadbackground worker
Stage 1 · modelClassifytyped Classification output
Stage 2 · modelDraft replytools: list_sections, get_section
PythonBusiness rulesfinal reply / escalate decision

Escalates when

  • — the email has attachments or the classifier flags a human need
  • — the model chose to escalate
  • — the reply says there wasn't enough information
  • — the proposed resolution isn't an allowed customer step
  • — the reply promises an action the bot can't perform

Outcome

Reply in threadlabelled processed
Hand off to a personlabelled escalated · holding reply sent

Any gate can send the thread to a person. The model drafts; Python decides.

Support dashboard

Support dashboard Tickets tab: two tickets, one escalated returns-and-warranty request and one answered paddle-boards question, with the escalated conversation shown on the right.

Tickets

Every conversation is recorded with its topic and outcome, so the team can see at a glance what was answered and what was escalated.

Support dashboard Events tab with a Check inbox now button and a table of processed email events showing status, attempts, error and created time.

Processing history

Each incoming email is an event with its status, attempts and any error; failed events are retried up to three times, and the inbox can be checked on demand.

Dark support dashboard on its Knowledge base tab: a sidebar of sections (brand and tone, escalation rules, paddle boards, returns and warranty, shelving) and an editor open on the 'Always escalate' rules.

Knowledge base

The guidance the assistant reads — product details, policies, brand voice and the escalation rules themselves — is plain text the team can edit.