Β
π Lesson: Building a Simple Web Chat Interface (with Streamlit)
π― Lesson Objective
By the end of this lesson, you’ll:
-
Build a chat UI to interact with your document-based AI agent
-
Upload documents (PDF, DOCX, TXT)
-
Ask questions and get AI-powered answers
-
Keep chat history on-screen (with memory support)
π§° Tools Used
| Tool | Purpose |
|---|---|
| Streamlit | UI framework for interactive Python apps |
| LangChain | LLM framework |
| Ollama | Local model runner |
| Chroma | Vector database for memory |
| PyMuPDF / Docx2txt | Document loaders |
π§© Project Structure
chatbot-app/
βββ app.py # Main Streamlit app
βββ documents/ # Uploaded files
βββ db_memory/ # Persistent vectorstore
βββ requirements.txt # Dependencies
π¦ Step 1: requirements.txt
streamlit
langchain
chromadb
sentence-transformers
llama-index
pypdf
python-docx
unstructured
ollama
Install them:
pip install -r requirements.txt
π» Step 2: app.py β Streamlit Chat App
import os
import streamlit as st
from langchain.document_loaders import PyPDFLoader, Docx2txtLoader, TextLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.vectorstores import Chroma
from langchain.embeddings import HuggingFaceEmbeddings
from langchain.chains import ConversationalRetrievalChain
from langchain.memory import ConversationBufferMemory
from langchain.llms import Ollama
# App title
st.set_page_config(page_title="π Chat with Your Documents")
st.title("π Chat with Your Documents")
# Upload files
uploaded_files = st.file_uploader("Upload your documents", type=["pdf", "docx", "txt"], accept_multiple_files=True)
# Load and process documents
def load_documents(files):
docs = []
for file in files:
path = os.path.join("documents", file.name)
with open(path, "wb") as f:
f.write(file.getbuffer())
if file.name.endswith(".pdf"):
loader = PyPDFLoader(path)
elif file.name.endswith(".docx"):
loader = Docx2txtLoader(path)
elif file.name.endswith(".txt"):
loader = TextLoader(path)
else:
continue
docs.extend(loader.load())
return docs
# Load model and build chain
@st.cache_resource
def build_chain(docs):
splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
chunks = splitter.split_documents(docs)
embeddings = HuggingFaceEmbeddings()
vectordb = Chroma.from_documents(chunks, embedding=embeddings, persist_directory="db_memory")
vectordb.persist()
memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)
llm = Ollama(model="mistral")
chain = ConversationalRetrievalChain.from_llm(
llm=llm,
retriever=vectordb.as_retriever(),
memory=memory
)
return chain
if uploaded_files:
documents = load_documents(uploaded_files)
qa_chain = build_chain(documents)
# Chat interface
st.subheader("π¬ Chat with your uploaded content")
if "chat_history" not in st.session_state:
st.session_state.chat_history = []
user_query = st.text_input("Ask a question:")
if user_query:
response = qa_chain.run({"question": user_query})
st.session_state.chat_history.append(("You", user_query))
st.session_state.chat_history.append(("Bot", response))
for role, msg in st.session_state.chat_history:
with st.chat_message(role):
st.markdown(msg)
else:
st.info("Upload PDF, DOCX, or TXT files to get started.")
β Step 3: Run the App
streamlit run app.py
It will open in your browser at:
http://localhost:8501
You can now:
-
Upload documents
-
Ask questions
-
See responses appear in chat
-
Enjoy persistent memory across questions
π οΈ Next Options (Add-ons)
Would you like me to add:
-
ποΈ Voice input and TTS output to the web interface?
-
π Save chat history to disk (for user sessions)?
-
π€ Option to summarize entire documents automatically?
-
π Host it online (e.g., Hugging Face Spaces, Render, or Railway)?
Let me know what you want next and Iβll build it for you.
51
