LESSON 72 ยท REAL-WORLD PROJECTS

AI Chatbot

Build a practical AI chatbot from the ground up using Python, an LLM, conversation state, streaming, safety checks, and production-ready design patterns.

25 min readโ€ขIntermediateโ€ขPythonโ€ขProject

How an AI Chatbot Works

UserSends a message
Chat UICaptures input
BackendValidates + builds request
LLMGenerates a response
MemoryKeeps useful context
ResponseStreams back to user
iImportant: A chatbot is more than an LLM call. A useful application needs a UI, backend, prompt strategy, conversation state, error handling, safety controls, and monitoring around the model.
1

What Are We Building?

Our project is a simple support-style chatbot. A user sends a message, the application sends the relevant conversation context to an LLM, and the assistant returns a helpful answer.

User experience

Fast responses, readable messages, clear errors, and a conversation history.

Application behavior

Validate input, control context, call the model, and return a structured response.

2

Project Architecture

Keep the chatbot architecture simple at first. Add RAG, tools, or agents only when the product actually needs them.

BrowserChat UI
APIBackend
PromptInstructions
MemoryRecent turns
ModelLLM provider
3

Choose the Chatbot Scope

Define what the bot should and should not do before writing code. A narrow scope makes prompting, evaluation, and safety much easier.

  • Answer common product questions.
  • Explain policies in plain language.
  • Ask for clarification when context is missing.
  • Admit when it does not know an answer.
  • Do not invent account or order information.
  • Escalate requests that require a human.
4

Prepare Your Python Environment

The examples use Python. In a real project, keep secrets such as API keys outside source code.

</> Python
import os

API_KEY = os.environ.get("OPENAI_API_KEY")

if not API_KEY:
    raise RuntimeError("OPENAI_API_KEY is not configured")

print("Environment is ready")

For production, use your platform's secret manager rather than committing credentials to Git.

5

Design the System Prompt

The system prompt defines the assistant's role, boundaries, tone, and response behavior. Keep stable instructions separate from user messages.

Example policy: You are a helpful support assistant. Answer using only information available to you. If the request requires account access or you are uncertain, say so and recommend the correct next step.
6

Represent Conversation Messages

Most chat APIs represent a conversation as ordered messages with roles. Keep the structure explicit so it can be validated and trimmed.

</> Python
messages = [
    {"role": "system", "content": "You are a helpful support assistant."},
    {"role": "user", "content": "How do I reset my password?"},
    {"role": "assistant", "content": "Open Settings and choose Security."},
    {"role": "user", "content": "What if I cannot access my email?"},
]

print(len(messages))
7

Make the Model Call

The exact SDK differs by provider, but the application pattern is the same: send instructions and conversation context, then handle the model response.

</> Python
def build_request(messages: list[dict]) -> dict:
    return {
        "model": "your-model",
        "messages": messages,
        "temperature": 0.2,
    }

request = build_request(messages)
print(request["model"])

Treat the provider SDK call as an implementation detail behind a small application service.

8

Control Conversation Memory

Sending the entire conversation forever increases tokens, latency, and cost. Start with a recent-message window and add summarization when conversations become long.

Short-term memory

Keep the latest turns that are directly relevant to the current conversation.

Summarized memory

Compress older turns into durable facts or a short conversation summary.

9

Trim Context with Python

A basic sliding window is often enough for an initial chatbot.

</> Python
def keep_recent_messages(messages: list[dict], max_messages: int = 8):
    system = messages[:1]
    recent = messages[-max_messages:]
    return system + recent

trimmed = keep_recent_messages(messages, max_messages=4)
print(len(trimmed))
10

Add a Chat History Store

For a real application, conversation state normally lives outside the request process. Store messages by a conversation ID and user or tenant ID.

Conversation IDGroups messages into one chat.
User IDControls ownership and access.
TimestampSupports ordering and retention.
RoleDistinguishes user and assistant messages.
ContentStores the message body securely.
MetadataTracks model, tokens, and useful diagnostics.
11

Streaming Improves Perceived Speed

Instead of waiting for the complete response, stream generated tokens or chunks to the UI. This can make the chatbot feel much faster even when total generation time is unchanged.

RequestUser sends a message.
First tokenUI starts rendering.
StreamMore output arrives incrementally.
12

Handle Errors Gracefully

Model providers can return timeouts, rate limits, authentication failures, or temporary service errors. Never expose raw stack traces or provider secrets to users.

  • Set a request timeout.
  • Retry only transient failures.
  • Use exponential backoff.
  • Limit retry attempts.
  • Return a friendly fallback message.
  • Log a correlation ID for debugging.
13

Protect Against Prompt Injection

User input is untrusted data. Do not let a user message silently override system policies or reveal hidden instructions.

Rule: Treat instructions from the user, retrieved documents, and tool results as separate trust levels. Validate what the application is allowed to do before executing any action.
14

Protect Sensitive Data

A chatbot may process names, emails, account details, internal documents, or other sensitive information. Minimize what reaches the model and enforce authorization before retrieving private data.

Minimize

Send only the fields required for the task.

Authorize

Check access before fetching private records.

Redact

Remove secrets and unnecessary sensitive values.

Retain carefully

Define retention and deletion rules for chat history.

15

When Should You Add RAG?

Add retrieval when the chatbot must answer from a knowledge base that changes over time or is not part of the model's reliable knowledge.

Basic chatbot

General conversation, writing help, simple instructions.

Chatbot + RAG

Company policies, product docs, manuals, FAQs, internal knowledge.

Chatbot + tools

Actions such as checking an order or creating a support ticket.

16

When Should You Add Tools?

Tools are useful when the chatbot must obtain live information or perform an action. The model should propose the tool call; your application validates and executes it.

MessageUser request
DecisionModel chooses tool
ValidateApplication checks args
ExecuteBackend runs tool
AnswerModel explains result
17

Add Guardrails

Guardrails should cover both inputs and outputs. Keep the rules close to the application boundary instead of relying only on the prompt.

  • Validate message length and format.
  • Block or review risky requests.
  • Protect system instructions and secrets.
  • Restrict tool permissions.
  • Validate structured outputs.
  • Provide a human escalation path.
18

Monitor the Chatbot

Track enough telemetry to understand failures without storing more user content than necessary.

LatencyTTFT and total response time.
TokensInput and output usage.
ErrorsProvider and application failures.
QualityFeedback and evaluation scores.
SafetyBlocked or escalated requests.
CostCost per conversation or task.
19

Evaluate the Chatbot

Create a small golden test set before launch. Include normal questions, edge cases, known failures, safety cases, and questions that require the bot to admit uncertainty.

20 common questions

Measure correctness and relevance.

10 edge cases

Test ambiguity and incomplete inputs.

10 safety cases

Test injection and data-leakage scenarios.

Production samples

Review real failures using privacy-safe telemetry.

20

Complete Project Flow

Put the pieces together into a simple request lifecycle.

1. InputValidate message
2. ContextLoad recent history
3. PromptBuild messages
4. ModelGenerate/stream
5. ChecksApply guardrails
6. StoreSave + observe
21

Mini Project: Support Chatbot

Build a support chatbot that answers product questions and knows when to escalate.

Step 1

Create a chat interface and conversation ID.

Step 2

Create a backend endpoint that validates messages.

Step 3

Build a system prompt with clear support boundaries.

Step 4

Send recent conversation context to your model.

Step 5

Add streaming and friendly error handling.

Step 6

Add evaluation, logging, safety checks, and cost monitoring.

22

Production Checklist

Architecture

UI, API, model service, memory, and telemetry are separated.

Security

Secrets, authorization, data minimization, and injection defenses are in place.

Reliability

Timeouts, retries, fallbacks, and rate limits are configured.

Performance

Streaming, context limits, and appropriate models are used.

Quality

Golden tests and regression evaluation run before releases.

Operations

Latency, errors, tokens, cost, and feedback are monitored.

30-Second Recap

01An AI chatbot is an application around an LLM, not just a model call.
02Conversation memory must be controlled to manage context, latency, and cost.
03Use RAG for changing knowledge and tools for live data or actions.
04Security and guardrails belong in the application layer.
05Streaming improves perceived responsiveness.
06Evaluation and monitoring turn a demo into a reliable product.

Key Takeaways

  • Start with a narrow chatbot scope and a clear system prompt.
  • Keep recent conversation state under control instead of sending unlimited history.
  • Never expose API keys or trust user input with privileged actions.
  • Add RAG and tools only when they solve a real product requirement.
  • Design for latency, cost, reliability, safety, and observability from the beginning.
  • Use a versioned evaluation set to catch regressions as the chatbot evolves.

Quick Quiz

1. Is an AI chatbot just an LLM?

No. The production application includes the UI, backend, context management, safety, error handling, and operational controls around the model.

2. Why limit conversation history?

To control token usage, latency, cost, and context quality.

3. When should you use RAG?

When answers should come from a knowledge source that the model should not be expected to know reliably on its own.

4. Who executes a tool call?

The application or backend executes the tool after validating the model's requested arguments.