AI-insightsbot / app.py
tmlinhdinh
clean up git messages
b8e2ff5
import chainlit as cl
from operator import itemgetter
from langchain_openai import ChatOpenAI, OpenAIEmbeddings
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.prompts import ChatPromptTemplate
from langchain.schema import StrOutputParser
from langchain_community.document_loaders import PyMuPDFLoader
from langchain_community.vectorstores import Qdrant
# Constants (you can adjust these as per your environment)
# DATA LOADER
DATA_LINK1 = "https://www.whitehouse.gov/wp-content/uploads/2022/10/Blueprint-for-an-AI-Bill-of-Rights.pdf"
DATA_LINK2 = "https://nvlpubs.nist.gov/nistpubs/ai/NIST.AI.600-1.pdf"
# CHUNKING CONFIGS
CHUNK_SIZE = 500
CHUNK_OVERLAP = 50
# RETRIEVER CONFIGS
COLLECTION_NAME = "AI Bill of Rights"
EMBEDDING_MODEL = "text-embedding-3-small"
# FINAL RAG CONFIGS
QA_MODEL = "gpt-4o"
RAG_PROMPT = """\
Given a provided context and question, you must answer the question based only on context.
If you cannot answer the question based on the context - you must say "I don't know".
Context: {context}
Question: {question}
"""
# Function to chunk documents
def chunk_documents(unchunked_documents, chunk_size, chunk_overlap):
text_splitter = RecursiveCharacterTextSplitter(
chunk_size=chunk_size,
chunk_overlap=chunk_overlap,
)
return text_splitter.split_documents(unchunked_documents)
# Function to build retriever
def build_retriever(chunked_documents, embeddings, collection_name):
vectorstore = Qdrant.from_documents(
documents=chunked_documents,
embedding=embeddings,
location=":memory:", # Storing in-memory for demonstration
collection_name=collection_name,
)
retriever = vectorstore.as_retriever()
return retriever
# Load documents and prepare retriever
rag_documents_1 = PyMuPDFLoader(file_path=DATA_LINK1).load()
rag_documents_2 = PyMuPDFLoader(file_path=DATA_LINK2).load()
chunked_rag_documents = chunk_documents(rag_documents_1, CHUNK_SIZE, CHUNK_OVERLAP) + \
chunk_documents(rag_documents_2, CHUNK_SIZE, CHUNK_OVERLAP)
@cl.on_chat_start
async def on_chat_start():
embeddings = OpenAIEmbeddings(model=EMBEDDING_MODEL)
retriever = build_retriever(chunked_rag_documents, embeddings, COLLECTION_NAME)
rag_prompt = ChatPromptTemplate.from_template(RAG_PROMPT)
qa_llm = ChatOpenAI(model=QA_MODEL)
rag_chain = (
{"context": itemgetter("question") | retriever, "question": itemgetter("question")}
| rag_prompt | qa_llm | StrOutputParser()
)
cl.user_session.set("chain", rag_chain)
# Chainlit app
@cl.on_message
async def main(message):
chain = cl.user_session.get("chain")
result = chain.invoke({"question" : message.content})
await cl.Message(
content=result, # Extract the response from the chain
author="AI"
).send()