TUTORIAL
Advanced
90 min
AI Customer Support Chatbot
Build a FAQ bot using Claude/GPT APIs that actually understands your products and policies.
What You'll Build
- • A chatbot that answers questions about your business
- • Knowledge base from your own documents/FAQs
- • Web interface for customers to chat
- • Fallback to human support when needed
Cost: ~$0.002-0.02 per message with Claude Haiku or GPT-3.5. Budget ~$20-50/month for moderate usage.
1Project Setup
mkdir ai-support-bot && cd ai-support-bot
python -m venv venv
source venv/bin/activate
pip install anthropic flask python-dotenv
Create .env:
ANTHROPIC_API_KEY=your_api_key_here
# Or for OpenAI: OPENAI_API_KEY=your_key
2Create Knowledge Base
Create a knowledge_base.txt with your FAQs:
# knowledge_base.txt
COMPANY: Acme Corp
PRODUCTS: Widget Pro, Widget Basic, Enterprise Suite
PRICING:
- Widget Basic: $29/month
- Widget Pro: $79/month (includes priority support)
- Enterprise: Custom pricing, contact sales
REFUND POLICY:
We offer a 30-day money-back guarantee on all products.
To request a refund, email support@acme.com with your order number.
SUPPORT HOURS:
Monday-Friday: 9am-6pm EST
Weekend: Email only, response within 24 hours
COMMON ISSUES:
Q: How do I reset my password?
A: Click "Forgot Password" on the login page, enter your email,
and follow the link sent to your inbox.
Q: How do I cancel my subscription?
A: Go to Settings > Billing > Cancel Subscription.
You'll retain access until the end of your billing period.
3Build the Chatbot Core
# chatbot.py
import anthropic
import os
from dotenv import load_dotenv
load_dotenv()
# Load knowledge base
with open('knowledge_base.txt', 'r') as f:
KNOWLEDGE_BASE = f.read()
client = anthropic.Anthropic(api_key=os.getenv('ANTHROPIC_API_KEY'))
SYSTEM_PROMPT = f"""You are a helpful customer support assistant for Acme Corp.
Your job is to answer customer questions using ONLY the information provided below.
KNOWLEDGE BASE:
{KNOWLEDGE_BASE}
RULES:
1. Only answer questions you can answer from the knowledge base
2. If you don't know the answer, say "I don't have that information. Please contact support@acme.com"
3. Be friendly and professional
4. Keep responses concise (2-3 sentences when possible)
5. If the customer seems frustrated, acknowledge their feelings
If the customer asks to speak to a human, respond with: [TRANSFER_TO_HUMAN]
"""
def get_response(user_message, conversation_history=[]):
messages = conversation_history + [{"role": "user", "content": user_message}]
response = client.messages.create(
model="claude-3-haiku-20240307", # Fast and cheap
max_tokens=500,
system=SYSTEM_PROMPT,
messages=messages
)
assistant_message = response.content[0].text
# Check for human transfer request
needs_human = "[TRANSFER_TO_HUMAN]" in assistant_message
return {
"response": assistant_message.replace("[TRANSFER_TO_HUMAN]", ""),
"needs_human": needs_human
}
if __name__ == "__main__":
print("Chatbot ready! Type 'quit' to exit.")
history = []
while True:
user_input = input("You: ")
if user_input.lower() == 'quit':
break
result = get_response(user_input, history)
print(f"Bot: {result['response']}")
if result['needs_human']:
print("[System: Transferring to human agent...]")
history.append({"role": "user", "content": user_input})
history.append({"role": "assistant", "content": result['response']})
4Create Web Interface
# app.py
from flask import Flask, render_template, request, jsonify, session
from chatbot import get_response
import uuid
app = Flask(__name__)
app.secret_key = 'your-secret-key-here'
@app.route('/')
def home():
if 'session_id' not in session:
session['session_id'] = str(uuid.uuid4())
session['history'] = []
return render_template('chat.html')
@app.route('/chat', methods=['POST'])
def chat():
user_message = request.json.get('message')
history = session.get('history', [])
result = get_response(user_message, history)
# Update history
history.append({"role": "user", "content": user_message})
history.append({"role": "assistant", "content": result['response']})
session['history'] = history[-20:] # Keep last 20 messages
return jsonify(result)
if __name__ == '__main__':
app.run(debug=True)
5Chat UI Template
Create templates/chat.html:
<!DOCTYPE html>
<html>
<head>
<title>Support Chat</title>
<style>
body { font-family: sans-serif; max-width: 600px; margin: 50px auto; }
#chat { height: 400px; overflow-y: scroll; border: 1px solid #ddd; padding: 10px; }
.message { margin: 10px 0; padding: 10px; border-radius: 8px; }
.user { background: #e3f2fd; text-align: right; }
.bot { background: #f5f5f5; }
#input-area { display: flex; gap: 10px; margin-top: 10px; }
#message-input { flex: 1; padding: 10px; }
button { padding: 10px 20px; background: #1976d2; color: white; border: none; cursor: pointer; }
</style>
</head>
<body>
<h2>Support Chat</h2>
<div id="chat"></div>
<div id="input-area">
<input type="text" id="message-input" placeholder="Ask a question...">
<button onclick="sendMessage()">Send</button>
</div>
<script>
const chat = document.getElementById('chat');
const input = document.getElementById('message-input');
input.addEventListener('keypress', (e) => {
if (e.key === 'Enter') sendMessage();
});
async function sendMessage() {
const message = input.value.trim();
if (!message) return;
addMessage(message, 'user');
input.value = '';
const response = await fetch('/chat', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ message })
});
const data = await response.json();
addMessage(data.response, 'bot');
if (data.needs_human) {
addMessage('Connecting you to a human agent...', 'bot');
}
}
function addMessage(text, type) {
const div = document.createElement('div');
div.className = 'message ' + type;
div.textContent = text;
chat.appendChild(div);
chat.scrollTop = chat.scrollHeight;
}
addMessage('Hi! How can I help you today?', 'bot');
</script>
</body>
</html>
6Deploy & Test
Run locally:
python app.py
# Visit http://localhost:5000
For production: Deploy to Railway, Render, or your own server with gunicorn.
pip install gunicorn
gunicorn app:app --bind 0.0.0.0:8000
Next Steps to Improve
- • Add vector search for better knowledge retrieval (use Pinecone or pgvector)
- • Log conversations for training and improvement
- • Add sentiment analysis to detect frustrated customers
- • Integrate with your ticketing system for seamless human handoff