Systems Library / AI Model Setup / How to Create Your First AI Chatbot with OpenAI
AI Model Setup foundations

How to Create Your First AI Chatbot with OpenAI

Build a functional AI chatbot using OpenAI API in under 30 minutes.

Jay Banlasan

Jay Banlasan

The AI Systems Guy

Building your first AI chatbot with OpenAI is one of the most direct ways to see what the build ai chatbot openai tutorial output looks like in a real product. The core pattern is simple: maintain a list of messages, append each new user input, send the full list to the API, get a reply, append that to the list, repeat. Understanding this loop is the foundation for every chatbot, assistant, and agent system I build for clients.

Most businesses do not need a fancy chatbot framework to start. A 50-line Python script with conversation memory will handle 80% of the use cases I see. This tutorial gives you that script, then layers on the pieces that make it production-ready.

What You Need Before Starting

Step 1: Understand the Message Structure

OpenAI's chat API works with a list of message objects. Each message has a role and content:

Every call sends the entire conversation history. The model has no memory by itself. You are the one tracking and passing the history.

# This is what a conversation looks like as data
conversation = [
    {"role": "system", "content": "You are a helpful customer service agent for Acme Software."},
    {"role": "user", "content": "How do I reset my password?"},
    {"role": "assistant", "content": "You can reset your password by clicking 'Forgot Password' on the login page."},
    {"role": "user", "content": "I don't see that option. I'm on the mobile app."},
    # Next API call includes all of the above so context is preserved
]

Step 2: Build the Basic Terminal Chatbot

import os
from openai import OpenAI
from dotenv import load_dotenv

load_dotenv()

client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))

SYSTEM_PROMPT = """You are a helpful support agent for Acme Software.
Be concise. Answer questions directly. If you don't know something, say so honestly."""

def chat(user_message: str, history: list) -> tuple[str, list]:
    """
    Send a message and get a reply. Returns (reply_text, updated_history).
    
    Args:
        user_message: What the user typed
        history: Current conversation history
    
    Returns:
        Tuple of (assistant_reply, updated_history)
    """
    # Add user message to history
    history.append({"role": "user", "content": user_message})
    
    # Send full history to API
    response = client.chat.completions.create(
        model="gpt-4o-mini",  # Use mini for chatbots to keep costs low
        messages=[{"role": "system", "content": SYSTEM_PROMPT}] + history,
        temperature=0.7,
        max_tokens=500
    )
    
    # Extract reply
    reply = response.choices[0].message.content
    
    # Add assistant reply to history
    history.append({"role": "assistant", "content": reply})
    
    return reply, history


def main():
    """Run the chatbot in the terminal."""
    print("Chatbot ready. Type 'quit' to exit.\n")
    
    history = []
    
    while True:
        user_input = input("You: ").strip()
        
        if not user_input:
            continue
        
        if user_input.lower() in ["quit", "exit", "bye"]:
            print("Goodbye!")
            break
        
        reply, history = chat(user_input, history)
        print(f"\nBot: {reply}\n")
        
        # Optional: Show conversation length for debugging
        # print(f"[{len(history)} messages in context]")


if __name__ == "__main__":
    main()

Run it:

python chatbot.py

You now have a working chatbot with conversation memory.

Step 3: Add a Web Interface with Flask

pip install flask
# app.py
import os
from flask import Flask, request, jsonify, render_template_string
from openai import OpenAI
from dotenv import load_dotenv

load_dotenv()
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))

app = Flask(__name__)

SYSTEM_PROMPT = "You are a helpful customer support agent. Be concise and friendly."

# Store sessions in memory (use Redis or a database in production)
sessions = {}

HTML_TEMPLATE = """
<!DOCTYPE html>
<html>
<head>
    <title>AI Chatbot</title>
    <style>
        body { font-family: Arial, sans-serif; max-width: 600px; margin: 50px auto; padding: 20px; }
        #chat-box { height: 400px; border: 1px solid #ccc; padding: 15px; overflow-y: auto; margin-bottom: 15px; }
        .user-msg { text-align: right; margin: 8px 0; }
        .bot-msg { text-align: left; margin: 8px 0; color: #333; }
        .user-msg span { background: #007bff; color: white; padding: 8px 12px; border-radius: 12px; display: inline-block; }
        .bot-msg span { background: #f0f0f0; padding: 8px 12px; border-radius: 12px; display: inline-block; }
        #input-area { display: flex; gap: 10px; }
        #user-input { flex: 1; padding: 10px; border: 1px solid #ccc; border-radius: 6px; }
        button { padding: 10px 20px; background: #007bff; color: white; border: none; border-radius: 6px; cursor: pointer; }
    </style>
</head>
<body>
    <h2>Support Chat</h2>
    <div id="chat-box"></div>
    <div id="input-area">
        <input type="text" id="user-input" placeholder="Type your message..." onkeypress="if(event.key==='Enter') sendMessage()">
        <button onclick="sendMessage()">Send</button>
    </div>
    
    <script>
        const sessionId = Math.random().toString(36).substr(2, 9);
        
        async function sendMessage() {
            const input = document.getElementById('user-input');
            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, session_id: sessionId})
            });
            
            const data = await response.json();
            addMessage(data.reply, 'bot');
        }
        
        function addMessage(text, sender) {
            const chatBox = document.getElementById('chat-box');
            const div = document.createElement('div');
            div.className = sender === 'user' ? 'user-msg' : 'bot-msg';
            div.innerHTML = `<span>${text}</span>`;
            chatBox.appendChild(div);
            chatBox.scrollTop = chatBox.scrollHeight;
        }
    </script>
</body>
</html>
"""


@app.route("/")
def index():
    return render_template_string(HTML_TEMPLATE)


@app.route("/chat", methods=["POST"])
def chat():
    data = request.json
    user_message = data.get("message", "")
    session_id = data.get("session_id", "default")
    
    if session_id not in sessions:
        sessions[session_id] = []
    
    history = sessions[session_id]
    history.append({"role": "user", "content": user_message})
    
    response = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[{"role": "system", "content": SYSTEM_PROMPT}] + history,
        temperature=0.7,
        max_tokens=500
    )
    
    reply = response.choices[0].message.content
    history.append({"role": "assistant", "content": reply})
    
    # Trim history if it gets too long (keep last 20 messages)
    if len(history) > 20:
        sessions[session_id] = history[-20:]
    
    return jsonify({"reply": reply})


if __name__ == "__main__":
    app.run(debug=True, port=5000)

Run it:

python app.py

Open http://localhost:5000 in your browser.

Step 4: Add Conversation Reset and Basic Logging

@app.route("/reset", methods=["POST"])
def reset():
    session_id = request.json.get("session_id", "default")
    sessions.pop(session_id, None)
    return jsonify({"status": "reset"})


# Add to the /chat route for logging
import json
from datetime import datetime

def log_conversation(session_id: str, user_msg: str, bot_reply: str):
    log_entry = {
        "timestamp": datetime.now().isoformat(),
        "session_id": session_id,
        "user": user_msg,
        "bot": bot_reply
    }
    with open("chat_log.jsonl", "a") as f:
        f.write(json.dumps(log_entry) + "\n")

What to Build Next

Related Reading

Want this system built for your business?

Get a free assessment. We will map every system your business needs and show you the ROI.

Get Your Free Assessment

Related Systems