RAG Assignment Notebook Export
# RAG-Powered Chatbot Assignment
Full Submission Notebook
## Install Dependencies
!pip install langchain langchain-community langchain-openai faiss-cpu pypdf sentence-transformers
## Imports and Logging
import os, glob, logging
from langchain_community.document_loaders import PyPDFLoader, TextLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain_openai import OpenAIEmbeddings, ChatOpenAI
from [Link] import FAISS
from [Link] import ConversationalRetrievalChain
from [Link] import ConversationBufferMemory
from [Link] import Tool
[Link](level=[Link])
logger = [Link]("RAG-Chatbot")
## Load PDF/Text Files
DATA_DIR = "./data"
paths = [Link](DATA_DIR + "/*.pdf") + [Link](DATA_DIR + "/*.txt")
[Link](f"Found {len(paths)} files.")
all_docs = []
for p in paths:
try:
loader = PyPDFLoader(p) if [Link](".pdf") else TextLoader(p)
docs = [Link]()
for d in docs:
[Link]["source"] = [Link](p)
all_docs.extend(docs)
except Exception as e:
print("Failed:", p, e)
print("Total documents loaded:", len(all_docs))
## Split Text into Chunks
text_splitter = RecursiveCharacterTextSplitter(chunk_size=800, chunk_overlap=100)
chunks = text_splitter.split_documents(all_docs)
print("Total chunks:", len(chunks))
for i, chunk in enumerate(chunks):
[Link]["chunk_id"] = i
## Create Embeddings + FAISS Vector Store
embeddings = OpenAIEmbeddings()
vectorstore = FAISS.from_documents(chunks, embeddings)
retriever = vectorstore.as_retriever(search_kwargs={"k": 4})
[Link]("FAISS store created.")
## PDF Search Tool
def pdf_search_tool(query):
docs = retriever.get_relevant_documents(query)
out = ""
for d in docs:
out += f"\nSource: {[Link]['source']} | Chunk: {[Link]['chunk_id']}\n"
out += d.page_content[:300] + "\n"
return out
pdf_tool = Tool(name="pdf_search", func=pdf_search_tool,
description="Search inside PDFs and return relevant chunks.")
## Mock Database Lookup Tool
mock_db = {
"leave policy": "Employees can take 24 paid leaves annually.",
"exam eligibility": "Minimum 75% attendance required.",
"semester duration": "Each semester is 6 months."
}
def mock_lookup(key):
return mock_db.get([Link](), "No result found.")
mock_tool = Tool(name="mock_lookup", func=mock_lookup,
description="Search answers from a mock dictionary.")
## Build RAG Chain with Memory
llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
memory = ConversationBufferMemory(memory_key="chat_history", return_messages=True)
qa_chain = ConversationalRetrievalChain.from_llm(
llm=llm,
retriever=retriever,
memory=memory,
return_source_documents=True
)
## System Prompt Used
SYSTEM_PROMPT = """
You are a RAG-enabled chatbot. Cite source filenames and chunk IDs.
If answer not found, say 'Information not available in documents.'
"""
print(SYSTEM_PROMPT)
## Test Cases for Accuracy
TEST_CASES = {
"What is the attendance requirement?": "attendance",
"Explain the leave policy.": "leave",
"What is semester duration?": "semester"
}
score = 0
for q, kw in TEST_CASES.items():
print("\nQUESTION:", q)
res = qa_chain({"question": q})
ans = res["answer"].lower()
print("ANSWER:", ans)
if kw in ans:
score += 1
print(f"Accuracy: {score}/{len(TEST_CASES)}")
## Chat Interface
while True:
q = input("Ask (exit to stop): ")
if [Link]() == "exit":
break
res = qa_chain({"question": q})
print("\nAnswer:", res["answer"])
print("\nSources:")
for d in res["source_documents"]:
print(f"- {[Link]['source']} (chunk {[Link]['chunk_id']})")
## Flow Diagram (Mermaid)
```mermaid
flowchart TD
A[Load PDFs] --> B[Split into Chunks]
B --> C[Embeddings]
C --> D[FAISS Vector DB]
D --> E[Retriever]
E --> F[RAG Chain + Memory]
F --> G[LLM Response]
G --> H[Answer with citation]
```
## 100-Word Model Explanation
The model used is ChatOpenAI (gpt-4o-mini), a powerful LLM integrated with LangChain.
It is well-suited for Retrieval-Augmented Generation because it can combine retrieved context
with reasoning to generate accurate, citation-backed responses. The system uses
OpenAIEmbeddings to convert text into vector embeddings, stored inside a FAISS vector
database for fast similarity search. When a user asks a question, FAISS retrieves
the most relevant chunks, and the LLM generates an answer grounded in those sources.
This ensures reliability, transparency, and academic-grade information retrieval.