Skip to main content

Welcome to a Grasp lesson

Create a free account to keep studying and create your own study path.

Lesson 72

Building a Chatbot Interface with Streamlit

Recommended resources

Welcome back! In our last lesson, we crafted sophisticated prompts to transform our AI from a simple Q&A bot into a genuine tutor capable of providing step-by-step explanations. However, this powerful "brain" is still confined to the command line. It's time to give it a face and a voice.

This lesson marks a significant step in your project: building the user-facing application. We will use Streamlit, a powerful Python library, to create a clean, interactive web interface for your AI Tutor. You'll learn how to display conversational history, handle user input, and manage the state of the chat—all without leaving the comfort of Python. Given your experience with frameworks like React and Django, you'll likely appreciate how quickly you can build a polished data application with Streamlit.

1. Envisioning the Final Product

Before we dive into the code, let's visualize our goal. We are building the front-end component of a complete Retrieval-Augmented Generation (RAG) system.

This architectural diagram shows how different components interact in a RAG system. Our focus today is on the "Streamlit UI" part, which serves as the user's entry point to the entire application.

The user interface will look something like this—a clean, conversational layout where the user can ask questions and receive the tutor's guided responses.

This image shows a typical UI for a RAG chatbot built with Streamlit. Note the main components: a chat history display area and an input box at the bottom for the user's messages.

2. The Streamlit Way: Core Concepts

Streamlit allows you to build web apps for machine learning and data science with remarkable speed. To use it effectively, you need to understand two core concepts: its execution model and session state.

The Dataquest article, "Build a Web Interface for Your Chatbot with Streamlit," provides an excellent explanation of these foundational ideas.

Project Tutorial: Build a Web Interface for Your Chatbot ... - Dataquest

This tutorial is a comprehensive guide to building a chatbot UI. We'll focus on the conceptual parts first.

Please read the following sections: "Part 3: Understanding Session State": This is the most crucial concept. Pay close attention to why session state is necessary and how it solves the problem of Streamlit rerunning the entire script on each interaction. "Part 4: The Chat Interface": Focus on the explanation of st.chat_input and the use of the walrus operator (:=). "Understanding Key Concepts": Briefly review the "Session State Deep Dive" and "The Streamlit Execution Model" subsections for a more formal summary.

To summarize, every time a user interacts with a widget (like typing a message or clicking a button), Streamlit reruns your entire Python script from top to bottom. To prevent your chat history from being wiped out on every turn, you must store it in st.session_state, a special object that persists across reruns.


3. The Building Blocks of a Chat Interface

Let's explore the specific Streamlit elements for building conversational apps. The official Streamlit documentation and the following video provide clear, hands-on demonstrations.

Build a basic LLM chat app - Streamlit Docs

The official documentation is the best place to start. It introduces the main chat elements and how to combine them.

Read from the Introduction up to and including "Build a bot that mirrors your input". This will walk you through: st.chat_message: How to create containers for user and assistant messages. st.chat_input: How to create the text input box at the bottom of the screen. Putting them together with st.session_state to create a simple "Echo Bot" that remembers the conversation.

Now, let's see these concepts in action. This video provides a very fast and practical walkthrough of building a chat interface.

Build a Streamlit Chatbot FAST 🤯

This video by "Coding Is Fun" demonstrates how to assemble a chat UI very quickly.

Please watch these two segments: Basic chat element: This shows the fundamental st.chat_message element and how to specify the role ('user' or 'assistant'). Building an echo bot: This is a live-coded example that puts all the pieces together: initializing session state, displaying history, getting user input, and appending new messages. This directly mirrors the code you will write.

These resources give you the complete pattern for a Streamlit chat application:

  1. Initialize: Check if a messages list exists in st.session_state. If not, create it.
  2. Display: Loop through the messages in st.session_state and display each one using st.chat_message.
  3. Accept Input: Use st.chat_input to capture the user's next message.
  4. Update and Rerun: If the user submitted a message, add it to st.session_state.messages, add the assistant's reply, and Streamlit will automatically rerun the script to display the updated history.

4. Streaming Responses for a Better UX

A key feature of modern chatbots is the "typewriter" effect, where the response is streamed token by token. This provides immediate feedback to the user that the bot is working. Streamlit makes this incredibly simple with the st.write_stream function.

Stream LLMs with LangChain + Streamlit | Tutorial

This tutorial from Alejandro AO, while using LangChain, has an excellent demonstration of Streamlit's modern streaming capabilities.

Watch the section from streaming with st.write_stream. The key takeaway is that if your function that calls the LLM is a generator (i.e., it uses yield to return chunks of the response), you can pass that generator directly to st.write_stream to render the output as it arrives.

When we integrate our RAG pipeline in the next lesson, we will ensure that the function generating the LLM response is a generator so we can use this elegant streaming feature.


5. Your Task: Build the Chatbot's UI Skeleton

It's time to build the front-end for your AI Tutor. For this task, you will create a Streamlit app that has a complete, functional chat interface but uses a simple placeholder for the AI's response. This allows you to focus purely on the UI logic before we wire it up to the RAG backend in the next lesson.

Create a new file named app.py.

Instructions:

  1. Set up the basic app structure:

    • Import streamlit.
    • Give your app a title, e.g., st.title("SQL AI Tutor").
  2. Initialize Chat History:

    • Use the standard pattern to initialize your chat history in st.session_state. The history should be a list of dictionaries, where each dictionary has a role and content.
    • You can start the conversation with a greeting from the assistant.
    
    
    
    # Example initialization
    if "messages" not in st.session_state:
        st.session_state.messages = [{"role": "assistant", "content": "Hello! I'm Codey, your SQL AI Tutor. How can I help you learn today?"}]
    
  3. Display Chat History:

    • Iterate through st.session_state.messages.
    • For each message, use a with st.chat_message(...) block to display its content.
  4. Handle User Input:

    • Use st.chat_input() to get the user's prompt. An if statement with the walrus operator (if prompt := ...) is a concise way to do this.
    • Inside the if block:
      • Append the user's message (role: 'user', content: prompt) to st.session_state.messages.
      • Display the user's message immediately using st.chat_message.
  5. Create a Placeholder Assistant Response:

    • Inside the same if block, create a placeholder response. For now, we are not calling your RAG pipeline. This keeps the task focused on the UI.
    • Append the assistant's placeholder message (role: 'assistant', content: response_text) to st.session_state.messages.
    • Display the assistant's message.
    
    
    
    # Example placeholder logic within the `if prompt...` block
    
    
    
    
    # For now, we'll just echo the prompt.
    # In the next lesson, this will be replaced with the call to your RAG chain.
    response_text = f"Echo: {prompt}" 
    
    with st.chat_message("assistant"):
        st.markdown(response_text)
    
    st.session_state.messages.append({"role": "assistant", "content": response_text})
    

    Note: The user message should be displayed before the assistant message to maintain the correct conversational order. Your final code should display history first, then process the new input and its response.

  6. Run Your App:

    • Open your terminal in the project directory.
    • Run the command: streamlit run app.py
    • Your web browser should open with your new chat interface. Test it by sending a few messages. The conversation should persist as you interact with it.

Conclusion

Congratulations! You've successfully built a functional, interactive web interface for your AI Tutor. You now have a solid understanding of Streamlit's core components for conversational AI and, most importantly, the critical role of session state.

Key Takeaways:

  • Streamlit's Core Chat Elements: st.chat_message and st.chat_input are the fundamental building blocks for any conversational app.
  • Session State is Essential: st.session_state is the key to maintaining conversational memory across user interactions in Streamlit's rerunning execution model.
  • The Chat App Pattern: The loop of initializing state, displaying history, capturing input, and appending new messages is the standard architecture for Streamlit chat applications.
  • Streaming for UX: st.write_stream offers a simple and powerful way to display LLM responses as they are generated, significantly improving the user experience.

Preview of the Next Lesson:

Our AI Tutor now has a polished front-end, but its brain isn't yet connected. In the next lesson, we will perform the final and most exciting step: integrating the RAG pipeline with the Streamlit front-end. We will replace the simple "echo" response with the real, context-aware, and pedagogically sound answers generated by your full RAG system, bringing your AI Tutor to life.