AI Design: Build a Python
Chatbot
Basic 8 • 2–3 periods • Rule‑based ➜
simple NLP
Lesson Overview & Objectives
• Topic: Designing and coding a Python chatbot
• Duration: 2–3 × 40–60 minutes
• By the end, students will be able to:
– Explain where chatbots are used and their limits
– Design intents (topics) with example phrases
– Implement and test a working Python chatbot
– Evaluate and improve responses using feedback
Success Criteria & Materials
• Success Criteria:
– Bot correctly answers at least 8/10 test questions
– Code is organized (functions + dictionaries)
– Includes a fallback/help and at least one improvement
• Materials: Laptops with Python 3.x, projector, worksheet, test questions
Ethics & Safety
• Be honest that it’s a bot; avoid pretending to be a human
• Don’t collect personal/sensitive data
• No medical/financial/legal advice
• Always provide a way to reach a human
What is a Chatbot?
• A program that chats with users via text or voice
• Common uses: customer support, school info, banking, e‑commerce
• Two styles: rule‑based (keywords) and AI/NLP (learned patterns)
Rule‑based vs AI/NLP
• Rule‑based:
– If/elif logic and keyword checks
– Predictable, easy to control, no training data
• AI/NLP:
– Learns patterns from data (statistical/ML methods)
– More flexible but needs data and careful evaluation
NLP: Natural Language Processing (Basics)
• Goal: Help computers understand and use human language
• Key ideas for this class:
– Tokens: split text into words (e.g., "Hello there!") → [hello, there]
– Intents: the purpose of a message (greeting, fees, hours)
– Entities: key data in a message (time, date, course)
– Similarity: compare messages using overlap or vectors
Simple Similarity for Beginners
• We can score a message against each intent by word overlap
• Example: tokens(user) ∩ keywords(intent)
• Score = overlap / number_of_keywords (simple ratio)
• Pick the intent with the highest score; if low, use fallback
Design Your Bot (Group Task)
• Choose 6–8 intents (greeting, hours, fees, thanks, goodbye, help, etc.)
• For each intent: write 3–5 example phrases and 2–3 responses
• Decide on a helpful fallback and a 'quit' command
Project Architecture (Flow)
• User Input → Preprocess (lowercase, tokenize) → Intent Match →
Response
• If no strong match, show fallback/help
• Keep intents and responses in a dictionary for easy editing
Code A: Rule‑based Chatbot (Part 1)
# chatbot_basic.py — Basic 8 (Rule-based)
import random
INTENTS = {
"greeting": {
"keywords": {"hi", "hello", "hey", "good morning", "good afternoon"},
"responses": [
"Hello! How can I help you today?",
"Hi there 😊 What do you want to know?",
"Hey! Ask me about school info."
]
},
"thanks": {
"keywords": {"thanks", "thank you", "appreciate"},
"responses": ["You're welcome!", "Anytime!", "Glad to help."]
},
"goodbye": {
"keywords": {"bye", "goodbye", "see you"},
"responses": ["Goodbye! 👋", "See you later!", "Have a nice day!"]
}
"school_hours": {
"keywords": {"time", "open", "close", "hours"},
"responses": [
"School opens 7:30am and closes 3:30pm (Mon–Thu), 12:30pm (Fri).",
"We open at 7:30am; closing is 3:30pm except Friday (12:30pm)."
]
},
"fees_info": {
"keywords": {"fees", "fee", "payment", "pay"},
"responses": [
"Fee details are available at the admin office. Would you like the
contact?",
Code A: Rule‑based Chatbot (Part 2)
FALLBACKS = [
"Hmm, I’m not sure about that. Try asking about school hours or fees.",
"I didn’t understand. Can you rephrase?",
"Good question! I can answer about hours, fees, or general school info."
]
def choose_response(intent_name):
return [Link](INTENTS[intent_name]["responses"])
def detect_intent(user_text):
text = user_text.lower().strip()
# simple keyword presence
for intent, data in [Link]():
for kw in data["keywords"]:
if kw in text:
return intent
return None
def chat():
print("SchoolBot v1 🤖 (type 'quit' to exit)")
while True:
user = input("You: ")
if [Link]().strip() in {"quit", "exit"}:
print("Bot: Bye! 👋")
Code A Breakdown (Line‑by‑Line)
• INTENTS: central dictionary of intents → keywords + responses
• FALLBACKS: list of safe replies when we don’t understand
• detect_intent(text): lower/strip, keyword search → intent name or None
• choose_response(name): random response to avoid repetition
• chat(): read input, check quit, detect intent, print reply or fallback
Code B: Token‑Overlap Chatbot (Part 1)
# chatbot_smart.py — Token Overlap Scoring (simple NLP)
import random, re
INTENTS = {
"greeting": {
"keywords": {"hi", "hello", "hey", "morning", "afternoon"},
"responses": ["Hello! How can I assist?", "Hi! What do you need?"]
},
"thanks": {
"keywords": {"thanks", "thank", "appreciate", "grateful"},
"responses": ["You're welcome!", "No problem!"]
},
"goodbye": {
"keywords": {"bye", "goodbye", "later", "see", "you"},
"responses": ["Goodbye!", "See you next time!"]
},
"school_hours": {
"keywords": {"time", "open", "close", "hour", "when"},
"responses": ["We open 7:30am; close 3:30pm (Mon–Thu), 12:30pm (Fri)."]
},
"fees_info": {
"keywords": {"fee", "fees", "payment", "pay", "tuition"},
"responses": ["Check Admin 8am–2pm or call the school line."]
},
"help": {
Code B: Token‑Overlap Chatbot (Part 2)
def best_intent(user_text, threshold=0.2):
tokens = tokenize(user_text)
best_name, best_score = None, 0.0
for name, data in [Link]():
kws = data["keywords"]
overlap = len(tokens & kws)
score = overlap / max(1, len(kws)) # simple overlap ratio
if score > best_score:
best_name, best_score = name, score
return best_name if best_score >= threshold else None
def chat():
print("SchoolBot v2 🤖 (type 'quit' to exit)")
while True:
user = input("You: ")
if [Link]().lower() in {"quit", "exit"}:
print("Bot: Bye! 👋")
break
intent = best_intent(user)
if intent:
print("Bot:", [Link](INTENTS[intent]["responses"]))
else:
print("Bot:", FALLBACK)
if __name__ == "__main__":
Code B Breakdown (Step‑by‑Step)
• tokenize(text): split into lowercase words; returns a set (no duplicates)
• For each intent: compute overlap = |tokens ∩ keywords|
• Score = overlap / number_of_keywords (simple similarity)
• Pick highest score; if < threshold → fallback
• Benefit: more forgiving matching than simple substring checks
Test, Evaluate, Improve
• Swap laptops and test with 10 questions from another group
• Record failures: what was asked vs. what bot answered
• Improve keywords, responses, add new intents, or adjust threshold
• Add 'help' and 'quit' commands; log unknowns for later fixes
Stretch Extensions
• Add synonyms per intent (e.g., 'tuition' ~ 'fees')
• Show confidence score next to answers
• Build a simple Tkinter GUI chat window
• Save unanswered questions to a text file for improvement
Assessment Rubric (Quick)
• Design (25%): clear intents, helpful responses, ethics/help
• Functionality (35%): runs reliably; 8/10 accuracy
• Code Quality (20%): names, functions, comments
• Iteration (20%): improvements from testing & feedback
Exit Ticket & Reflection
• When should a chatbot hand over to a human?
• What one improvement did your team make today?
• What new question did your bot fail to answer—and why?
Glossary
• Intent — purpose of a message (e.g., greeting)
• Token — a word in lowercase after splitting text
• Fallback — a safe reply when we don’t understand
• Similarity — how close two texts are (here: overlap of words)