← Back to portfolio
Case Study · 12 / 17
Applied ML · Full-Stack · 2025

A chatbot, and the
plumbing that keeps it up.

AmazeBot wraps Hugging Face's Blenderbot in a Django REST backend and a React + Tailwind chat UI. The model is the easy part — the case study is really about throttling, caching, and retry logic, the unglamorous work that keeps a hosted-model app from falling over.

Role
Solo — full-stack build
Model
Hugging Face Blenderbot
Stack
Django REST · React · Tailwind
Status
Open-source project
Fig. 12 · message → model → reply
12
Calling a model is one line. Calling it reliably is the whole backend.
§ 01 — The problem

The demo works. The tenth user is where it breaks.

Standing up a chatbot against a hosted model is a five-minute job — until real traffic hits it. Then the external API's rate limits, cold responses, and occasional failures turn a slick demo into a spinner. The interesting engineering isn't the conversation; it's the layer that makes the conversation dependable.

AmazeBot is built around that layer: a Django REST backend that throttles, caches, and retries around Blenderbot so the React UI stays responsive.

A model integration is a reliability problem wearing an AI costume.

§ 02 — Constraints

What the backend had to guarantee.

§ 03 — Architecture

A thin UI over a careful API.

The React client posts a message to a single Django REST endpoint. The backend checks throttle and cache, calls Blenderbot with retries, and returns the reply over CORS to the frontend.

01 — UI
React chat
Tailwind chat surface posts messages via Axios to the API.
02 — Gate
Throttle + cache
DRF throttling caps request rate; caching short-circuits repeats.
03 — Call
Blenderbot
Hugging Face inference wrapped in retry logic and error handling.
04 — Return
JSON reply
Response sent back over CORS to the client, ready for the next turn.

Keeping the model call behind the REST boundary means the API key never reaches the browser and every safeguard — rate limit, cache, retry — lives in one place the frontend doesn't have to know about.

§ 04 — What broke first

The external API sets the real latency.

Early on, response time and reliability were entirely at the mercy of the hosted model — some calls were quick, some slow, some failed outright. The fix wasn't a faster model, it was caching and retries: repeated prompts stopped hitting the network at all, and transient errors got a second attempt instead of a red bubble.

That reframed the project. AmazeBot is less "a chatbot" and more "a well-behaved client for someone else's model" — which is the skill that actually transfers to production AI work.

10/s
Request-rate ceiling protecting the upstream API
1
REST endpoint the whole chat runs through
0
API keys exposed to the browser
§ 05 — Design

A conversation, nothing more.

The interface is a single-column chat with Tailwind styling and honest loading states, so the retry-and-cache machinery underneath stays invisible. The user sees a smooth conversation; they never see the throttle decision or the cache hit that made it feel instant.

§ 06 — What I'd do differently

Three things, next time.