Forays Into AI

The only way to discover the limits of the possible is to go beyond them into the impossible. - Arthur C. Clarke

Building a simple chat application using Streamlit and Langchain

AI Chatbot

Sometimes you want to set up a user interface for your chat application. This post discusses setting up such an interface using Streamlit - an open-source app framework that "turns data into shareable web apps in minutes".

Setting Up Your Environment

The full code for this post is on Github.

Install dependencies

You will need to install streamlit, langchain, and other required dependencies. Follow the instructions from the repo.

Project structure

For the simple chat script, the project consists of three main components:

  • runner.py: Contains the SimpleRunner class, responsible for managing chat sessions and processing messages.
  • utils.py: Includes utility functions like show_chat_history(), which displays previous chat interactions.
  • The main script (multi_turn_chat.py): Ties everything together, creating the web interface and handling user input.

Main script

The main script sets up the UI, and is very simple. Essentially, it looks like:

def main():
    runner = SimpleRunner(session_key='chat-with-assistant')
    st.title("Let's chat - Please ask me anything")

    show_chat_history(runner.get_history())

    if question := st.chat_input():
        with st.expander(question, True):
            st.chat_message("human").write(question)
            with st.spinner("Thinking..."):
                response = runner.run(question)
                st.chat_message("ai").write(response.content)
  • Initializing the Runner: We create a SimpleRunner instance, responsible for managing the chat session.
  • Setting Up Streamlit Interface: st.title() sets the title of our web page, and show_chat_history() displays past interactions.
  • Handling Chat Input: st.chat_input() captures the user's question. If a question is asked, we display it and the AI's response in an expander with a loading spinner.

Running the Application

To run your Streamlit application, execute the following command in your terminal:

streamlit run multi_turn_chat.py

This command launches a local web server, and you should see your chat application running in your default web browser.

Extending the Chat Application with Semantic Search

The basic chat application we've discussed above serves as a great starting point. However, in many scenarios, you might want your chat application to understand and leverage existing documents or knowledge bases to provide more accurate and helpful responses. The script 'chat_with_documents.py' enhances the simple application with semantic search capabilities using an in-memory document index.

Enhancements Overview

  1. Document Uploading: Allow users to upload documents (PDFs and text files) that the chat application can reference.
  2. Document Indexing: Implement an in-memory document index to store and search uploaded document content.
  3. Semantic Search: Use RunnerWithSemanticSearch instead of SimpleRunner for querying the document index to provide context-aware responses.

Handle Document Uploads and Indexing

First, add the ability for users to upload documents directly through the Streamlit interface. The uploaded documents are then embedded into the FAISS vector store via the InMemoryDocumentIndex:

def file_uploads(document_index):
    uploaded_files = st.file_uploader("Upload documents", type=["pdf", "txt"], accept_multiple_files=True)
    if uploaded_files:
        for uploaded_file in uploaded_files:
            # Process and add each uploaded file to the document index
            document_index.add_to_index(uploaded_file)

Initializing the Document Index

We initialise the InMemoryDocumentIndex object which is a wrapper around FAISS once, to avoid writing over the stored vectors:

def initialize_document_index():
    if 'document_index' not in st.session_state:
        data_loader = DataLoader()
        st.session_state.document_index = InMemoryDocumentIndex(data_loader)
    return st.session_state.document_index

Enhanced main function

The main function now uses RunnerWithSemanticSearch, which leverages the document index for generating responses:

def main():
    runner = RunnerWithSemanticSearch(session_key='chat-with-with-documents')
    # Set up the Streamlit web interface
    st.title("Query an AI using semantic search")

    # Display all messages in the history
    show_chat_history(runner.get_history())
    document_index = initialize_document_index()

    # Handle input from the chat input box
    if question := st.chat_input():
        with st.expander(question, True):
            st.chat_message("human").write(question)
            with st.spinner("Thinking..."):
                response = runner.run(question, document_index)
                st.chat_message("ai").write(response.content)

Putting It All Together

Finally, integrate the document upload functionality with the main chat interface, allowing users to choose whether to upload documents:

if __name__ == "__main__":
    upload_files = st.checkbox("Upload files?", False)
    if upload_files:
        document_index = initialize_document_index()
        file_uploads(document_index)
    else:
        main()

Run using:

streamlit run chat_with_your_documents.py

And that's it

By extending our chat application with semantic search capabilities, we've significantly increased its usefulness and applicability. Whether it's for a customer support system that can pull information from manuals and FAQs, or for an educational chatbot that references course materials, the ability to understand and leverage a vast array of documents opens up new possibilities for interaction and assistance.

Docs

For further exploration, please refer to the following documentation:

TaggedSemantic SearchChat

Can You Be a Successful Programmer in 2027 Without AI Skills?

As AI transforms the tech landscape, will programmers need to adapt and learn AI to stay relevant and successful in 2027 and beyond? I would say the answer is a clear yes, but there is more to it.

Building a Simple Multi-Agent Physics Teacher Application with AutoGen

Learn how to build a simple multi-agent application using the AutoGen framework to create a physics teacher application where a student agent interacts with a teacher agent to learn about Newton's laws of motion.

Creating a Real-time Chat Application with Streamlit and Neo4j

Learn how to build a chat application with Streamlit and Neo4j in our latest tutorial. We'll guide you through setting up Docker, using an open source LLM, and managing chat histories with Neo4j. Perfect for both beginners, this post provides all the tools needed to create an AI-enhanced chat application. Dive into the code and start building today!

We use necessary cookies to make our site work. We'd also like to set analytics cookies that help us make improvements by measuring how you use the site. These will be set only if you accept. For more detailed information about the cookies we use, see our Privacy Policy page.