Ashvanth.S commited on
Commit
dbb2933
β€’
1 Parent(s): c5d127d

Add initial files

Browse files
.gitignore ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ .venv/
2
+
3
+ .env
4
+
5
+
6
+ __pycache__/
7
+
8
+ # Jupyter Notebook checkpoints
9
+ .ipynb_checkpoints/
README.md CHANGED
@@ -1,11 +1,124 @@
1
- ---
2
- title: Sarvam Assignment
3
- emoji: πŸ‘
4
- colorFrom: pink
5
- colorTo: yellow
6
- sdk: docker
7
- pinned: false
8
- short_description: Q&A using Rag and Agent
9
- ---
10
-
11
- Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # RAG and Agent-based Q&A System
2
+
3
+ ## Table of Contents
4
+ - [Introduction](#introduction)
5
+ - [Features](#features)
6
+ - [System Architecture](#system-architecture)
7
+ - [Prerequisites](#prerequisites)
8
+ - [Installation](#installation)
9
+ - [Usage](#usage)
10
+ - [API Endpoints](#api-endpoints)
11
+ - [Frontend Interface](#frontend-interface)
12
+
13
+ This project implements a sophisticated Question-Answering system that combines Retrieval-Augmented Generation (RAG) with an intelligent agent. The system is designed to answer queries related to NCERT textbooks chapters, specifically focusing on the Sound chapter, while also handling general queries using web search capabilities. Do not: **Don't forget to specify your open-ai key in the .env file**
14
+
15
+ The application serves two main functionalities:
16
+
17
+ - A RAG system that retrieves relevant information from a vector database containing NCERT textbook content.
18
+ - An agent-based system that can perform smart actions based on the user's query, including invoking the RAG system when appropriate and using additional tools like web search.
19
+
20
+ ## Introduction
21
+
22
+ This project implements a sophisticated Question-Answering system that combines Retrieval-Augmented Generation (RAG) with an intelligent agent. The system is designed to answer queries related to NCERT textbooks, specifically focusing on the Sound chapter, while also handling general queries using web search capabilities.
23
+
24
+ The application serves two main functionalities:
25
+ 1. A RAG system that retrieves relevant information from a vector database containing NCERT textbook content.
26
+ 2. An agent-based system that can perform smart actions based on the user's query, including invoking the RAG system when appropriate and using additional tools like web search.
27
+
28
+ ## Features
29
+
30
+ - **RAG System**:
31
+ - Utilizes a vector database to store and retrieve relevant information from NCERT textbooks.
32
+ - Provides accurate and concise answers to questions related to the Sound chapter.
33
+
34
+ - **Intelligent Agent**:
35
+ - Determines when to use the RAG system based on the query content.
36
+ - Incorporates additional tools, including web search for non-textbook related queries.
37
+ - Calculates word count of responses when requested.
38
+
39
+ - **FastAPI Backend**:
40
+ - Serves both RAG and Agent functionalities via separate endpoints.
41
+ - Ensures efficient and scalable handling of requests.
42
+
43
+ - **Gradio Frontend**:
44
+ - Provides an intuitive user interface for interacting with both the RAG and Agent systems.
45
+ - Allows easy testing and demonstration of the system's capabilities.
46
+
47
+
48
+ ## System Architecture
49
+
50
+ The system is built using the following key components:
51
+
52
+ 1. **Vector Store**: Stores embeddings of NCERT textbook content for efficient retrieval.
53
+ 2. **LangChain**: Facilitates the creation of the RAG chain and the agent.
54
+ 3. **OpenAI's ChatGPT**: Powers the language model for generating responses.
55
+ 4. **DuckDuckGo Search API**: Enables web search capabilities for the agent.
56
+ 5. **FastAPI**: Provides the backend API framework.
57
+ 6. **Gradio**: Creates the frontend user interface.
58
+
59
+ ## Installation
60
+
61
+ 1. Clone the repository and create a virtual env
62
+ ```bash
63
+ python -m venv venv
64
+ source venv/bin/activate
65
+ ```
66
+
67
+ 2.Install the required packages:
68
+ ```bash
69
+ pip install -r requirements.txt
70
+ ```
71
+
72
+ 3. Setup up .env with all the environment variables
73
+ ```bash
74
+ OPEN_API_KEY=your_openai_api_key
75
+ UVICORN_HOST = 127.0.0.1
76
+ UVICORN_PORT = 7860
77
+ SOURCE_DATA = "../pdf_data"
78
+ VECTOR_STORE = "../chroma_langchain_db"
79
+ ```
80
+
81
+ ## Usage
82
+
83
+ To start the application run:
84
+ ```python
85
+ python3 main_app.py
86
+ ```
87
+
88
+ This will start the FastAPI server and launch the Gradio interface. You can access the Gradio interface by navigating to `http://localhost:8000` in your web browser.
89
+
90
+ ## API Endpoints
91
+
92
+ The application exposes two main endpoints:
93
+
94
+ 1. `/rag` (POST): For querying the RAG system
95
+ - Request body: `{ "question": "Your question here" }`
96
+ - Response: `{ "answer": "Generated answer" }`
97
+
98
+ 2. `/agent` (POST): For interacting with the intelligent agent
99
+ - Request body: `{ "question": "Your question here" }`
100
+ - Response: `{ "answer": "Agent's response" }`
101
+
102
+
103
+ ## Frontend Interface
104
+
105
+ The Gradio interface provides two tabs:
106
+
107
+ 1. **RAG System**: For asking questions related to the NCERT Sound chapter.
108
+ 2. **Agent**: For general queries, including those that may require web search or other tools.
109
+
110
+ Users can type their questions in the input box and receive answers in real-time.
111
+
112
+ ### RAG System Interface
113
+
114
+ ![RAG System Interface](images/RAG_app.png)
115
+
116
+ ### Agent Interface
117
+
118
+ ![Agent Interface](images/Agent_app.png)
119
+
120
+ ### API Documentation
121
+
122
+ The FastAPI automatic interactive API documentation is available at `/docs` endpoint:
123
+
124
+ ![API Documentation](images/API_docs.png)
chroma_langchain_db/237d30d4-0d4f-4fa7-b4ff-2981bcd6b160/data_level0.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f18abd8c514282db82706e52b0a33ed659cd534e925a6f149deb7af9ce34bd8e
3
+ size 6284000
chroma_langchain_db/237d30d4-0d4f-4fa7-b4ff-2981bcd6b160/header.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:effaa959ce2b30070fdafc2fe82096fc46e4ee7561b75920dd3ce43d09679b21
3
+ size 100
chroma_langchain_db/237d30d4-0d4f-4fa7-b4ff-2981bcd6b160/length.bin ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f7e5e2d7ceaf351ff89d12523776511335dcc308f06544d4cbbc32efa59828a2
3
+ size 4000
chroma_langchain_db/237d30d4-0d4f-4fa7-b4ff-2981bcd6b160/link_lists.bin ADDED
File without changes
chroma_langchain_db/chroma.sqlite3 ADDED
Binary file (643 kB). View file
 
main_app.py ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from fastapi import FastAPI
3
+ from pydantic import BaseModel
4
+ from dotenv import load_dotenv
5
+ from utils.document_loader import load_pdf, create_unique_ids
6
+ from utils.embeddings import get_embeddings
7
+ from utils.vector_store import create_vector_store, get_retriever, load_vector_store
8
+ from utils.rag_chain import get_model, create_rag_chain, get_conversational_rag_chain
9
+ from utils.gradio_interface import create_gradio_interface
10
+ from utils.agent import init_agent, get_agent_response
11
+ import gradio as gr
12
+
13
+ load_dotenv()
14
+
15
+ app = FastAPI()
16
+
17
+ class QuestionRequest(BaseModel):
18
+ question: str
19
+
20
+ class AnswerResponse(BaseModel):
21
+ answer: str
22
+
23
+ def init_rag_system():
24
+ pdf_path = os.getenv("SOURCE_DATA")
25
+ vector_store_path = os.getenv("VECTOR_STORE")
26
+ # Load embeddings
27
+ embeddings = get_embeddings()
28
+ if os.path.exists(vector_store_path) and os.listdir(vector_store_path):
29
+ print("Loading existing vector store...")
30
+ vector_store = load_vector_store(embeddings)
31
+ else:
32
+ print("Creating new vector store...")
33
+ documents = load_pdf(pdf_path)
34
+ unique_ids = create_unique_ids(documents)
35
+ vector_store = create_vector_store(documents, unique_ids, embeddings)
36
+ retriever = get_retriever(vector_store)
37
+ model = get_model()
38
+ rag_chain = create_rag_chain(model, retriever)
39
+ return get_conversational_rag_chain(rag_chain)
40
+
41
+ # Initialize conversational RAG chain
42
+ conversational_rag_chain = init_rag_system()
43
+
44
+ # Initialize agent
45
+ agent = init_agent()
46
+
47
+ @app.post("/rag", response_model=AnswerResponse)
48
+ async def ask_rag_question(request: QuestionRequest):
49
+ print(f"RAG Question: {request.question}")
50
+ response = conversational_rag_chain.invoke(
51
+ {"input": request.question},
52
+ config={"configurable": {"session_id": "default_session"}}
53
+ )
54
+ return AnswerResponse(answer=response["answer"])
55
+
56
+ @app.post("/agent", response_model=AnswerResponse)
57
+ async def ask_agent_question(request: QuestionRequest):
58
+ print(f"Agent Question: {request.question}")
59
+ response = get_agent_response(agent, request.question)
60
+ return AnswerResponse(answer=response)
61
+
62
+ interface = create_gradio_interface(app, conversational_rag_chain, agent)
63
+ app = gr.mount_gradio_app(app, interface, path="/")
64
+
65
+ if __name__ == "__main__":
66
+ import uvicorn
67
+ uvicorn.run(
68
+ app,
69
+ host=os.getenv("UVICORN_HOST"),
70
+ port=int(os.getenv("UVICORN_PORT")),
71
+ # reload=True
72
+ )
requirements.txt ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
 
1
+ chromadb
2
+ langchain
3
+ langchain-community
4
+ langchain-openai
5
+ langchain-chroma
6
+ gradio
7
+ openai
8
+ pydantic
9
+ duckduckgo-search
utils/__init__.py ADDED
File without changes
utils/agent.py ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from dotenv import load_dotenv
3
+ from utils.embeddings import get_embeddings
4
+ from utils.vector_store import load_vector_store
5
+ from langchain_community.utilities import DuckDuckGoSearchAPIWrapper
6
+ from langchain_community.tools import DuckDuckGoSearchResults
7
+ from langchain.chains import create_retrieval_chain
8
+ from langchain.chains.combine_documents import create_stuff_documents_chain
9
+ from langchain.tools import tool
10
+ from langchain_openai import ChatOpenAI
11
+ from langchain.agents import create_openai_functions_agent, AgentExecutor
12
+ from langchain_community.chat_message_histories import ChatMessageHistory
13
+ from langchain_core.messages import AIMessage
14
+ from langchain.prompts import ChatPromptTemplate, MessagesPlaceholder
15
+ from langchain_core.runnables import RunnableWithMessageHistory
16
+
17
+ load_dotenv()
18
+
19
+ wrapper = DuckDuckGoSearchAPIWrapper(max_results=2)
20
+ search_web = DuckDuckGoSearchResults(api_wrapper=wrapper, source="news")
21
+
22
+ @tool
23
+ def rag_tool(query:str)->str:
24
+ """
25
+ The function queries the vector db and retrieves the answer
26
+ """
27
+ embeddings = get_embeddings()
28
+ vector_store = load_vector_store(embeddings)
29
+ retriver = vector_store.as_retriever(search_type='similarity',search_kwargs={"k": 2})
30
+
31
+ system_prompt = (
32
+ "You are an assistant for question-answering tasks. "
33
+ "Use the following pieces of retrieved context to answer "
34
+ "the question. If you don't know the answer, say that you "
35
+ "don't know. Use three sentences maximum and keep the "
36
+ "answer concise."
37
+ "\n\n"
38
+ "{context}"
39
+ )
40
+
41
+ prompt = ChatPromptTemplate.from_messages(
42
+ [
43
+ ("system", system_prompt),
44
+ ("human", "{input}"),
45
+ ]
46
+ )
47
+
48
+ question_answer_chain = create_stuff_documents_chain(get_model_use(), prompt)
49
+ rag_chain = create_retrieval_chain(retriver, question_answer_chain)
50
+ response = rag_chain.invoke({"input":query})
51
+ return (response["answer"])
52
+
53
+
54
+ @tool
55
+ def calculate_word_count(words: str) -> int:
56
+ """
57
+ The function helps in calculating the number of words present in the responses
58
+ """
59
+ response = words.split()
60
+ return len(response)
61
+
62
+ tools = [rag_tool,search_web, calculate_word_count]
63
+
64
+ prompt = ChatPromptTemplate.from_messages([
65
+ ("system", """
66
+ You are an assistant helping the user with queries related to the NCERT Sound chapter and real-time events or factual information. Follow these instructions:
67
+
68
+ 1. **NCERT Sound Chapter Queries**:
69
+ - Use your rag tool provide to answer any query regarding NCERT Sound chapter to answer questions such as:
70
+ - What is an echo?
71
+ - How is sound propagated?
72
+ - What are the applications of ultrasound?
73
+ - STRICT RULE: Do not use external tools after using rag_tool
74
+
75
+ 2. **Non-Sound Chapter Queries**:
76
+ - For any questions unrelated to the Sound chapter, such as real-time events, news, or factual information not covered in the Sound chapter, use the search tool to provide the latest and most accurate information.
77
+
78
+ 3. **Counting Words in a Response**:
79
+ - If the query involves counting the number of words in a response, use the `calculate_word_count` tool to determine the word count.
80
+
81
+ 4. **Clarification**:
82
+ - If the query is unclear or ambiguous, clarify the user's intent before selecting the appropriate tool or providing a response.
83
+
84
+ Be concise, accurate, and use the appropriate tool or knowledge based on the query type. Do not confuse the tools or mix the instructions for different query types.
85
+ """),
86
+ MessagesPlaceholder(variable_name="chat_history"),
87
+ ("user", "Form input details: {input}"),
88
+ MessagesPlaceholder(variable_name="agent_scratchpad"),
89
+ ])
90
+
91
+ def get_model_use():
92
+ return ChatOpenAI(api_key=os.getenv("OPEN_API_KEY"),temperature=0)
93
+
94
+ def init_agent():
95
+ llm = get_model_use()
96
+ agent = create_openai_functions_agent(llm, tools, prompt)
97
+ agent_executor = AgentExecutor(agent=agent, tools=tools, verbose=True)
98
+ message_history = ChatMessageHistory()
99
+ agent_with_chat_history = RunnableWithMessageHistory(
100
+ agent_executor,
101
+ lambda session_id: message_history,
102
+ input_messages_key="input",
103
+ history_messages_key="chat_history",
104
+ )
105
+ return agent_with_chat_history
106
+
107
+ def get_agent_response(agent, user_input, session_id="agentic_trial"):
108
+ response = agent.invoke(
109
+ {
110
+ "input": user_input
111
+ },
112
+ config={"configurable": {"session_id": session_id}}
113
+ )
114
+ return response['output']
utils/document_loader.py ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from langchain_community.document_loaders import PDFPlumberLoader
3
+
4
+ def load_pdf(directory):
5
+
6
+ for file in os.listdir(directory):
7
+ file_path = os.path.join(directory,file)
8
+ loader = PDFPlumberLoader(file_path)
9
+ document = loader.load()
10
+
11
+ return document
12
+
13
+ def create_unique_ids(documents):
14
+ return [f"{doc.metadata['source']}_page_{doc.metadata['page']}" for doc in documents]
utils/embeddings.py ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from langchain_openai import OpenAIEmbeddings
3
+ from dotenv import load_dotenv
4
+
5
+ load_dotenv()
6
+
7
+ def get_embeddings():
8
+ return OpenAIEmbeddings(model='text-embedding-3-small', api_key=os.getenv("OPEN_API_KEY"))
utils/gradio_interface.py ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import gradio as gr
2
+ from fastapi import FastAPI
3
+ from fastapi.responses import JSONResponse
4
+
5
+ def create_gradio_interface(app: FastAPI, conversational_rag_chain, agent):
6
+ def qa_function(message, history, system):
7
+ if system == "RAG":
8
+ response = conversational_rag_chain.invoke(
9
+ {"input": message},
10
+ config={"configurable": {"session_id": "abc123"}}
11
+ )
12
+ return response["answer"]
13
+ elif system == "Agent":
14
+ response = agent.invoke(
15
+ {"input": message},
16
+ config={"configurable": {"session_id": "agent_session"}}
17
+ )
18
+ return response['output']
19
+
20
+ gr_app = gr.Blocks()
21
+
22
+ with gr_app:
23
+ gr.Markdown("# NCERT Q&A System")
24
+ gr.Markdown("Ask questions based on the NCERT Sound chapter or use the Agent for broader queries.")
25
+
26
+ chatbot = gr.Chatbot()
27
+ msg = gr.Textbox()
28
+ clear = gr.Button("Clear")
29
+
30
+ system_choice = gr.Radio(["RAG", "Agent"], label="Choose System", value="RAG")
31
+
32
+ def user(user_message, history, system):
33
+ return "", history + [[user_message, None]]
34
+
35
+ def bot(history, system):
36
+ user_message = history[-1][0]
37
+ bot_message = qa_function(user_message, history, system)
38
+ history[-1][1] = bot_message
39
+ return history
40
+
41
+ msg.submit(user, [msg, chatbot, system_choice], [msg, chatbot], queue=False).then(
42
+ bot, [chatbot, system_choice], chatbot
43
+ )
44
+ clear.click(lambda: None, None, chatbot, queue=False)
45
+
46
+ return gr_app
utils/rag_chain.py ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from langchain_openai import ChatOpenAI
3
+ from langchain.chains import create_retrieval_chain, create_history_aware_retriever
4
+ from langchain.chains.combine_documents import create_stuff_documents_chain
5
+ from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
6
+ from langchain_core.runnables.history import RunnableWithMessageHistory
7
+ from langchain_community.chat_message_histories import ChatMessageHistory
8
+
9
+ def get_model():
10
+ return ChatOpenAI(api_key=os.getenv("OPEN_API_KEY"))
11
+
12
+ def create_contextualize_q_prompt():
13
+ contextualize_q_system_prompt = (
14
+ "Given a chat history and the latest user question "
15
+ "which might reference context in the chat history, "
16
+ "formulate a standalone question which can be understood "
17
+ "without the chat history. Do NOT answer the question, "
18
+ "just reformulate it if needed and otherwise return it as is."
19
+ )
20
+ return ChatPromptTemplate.from_messages([
21
+ ("system", contextualize_q_system_prompt),
22
+ MessagesPlaceholder("chat_history"),
23
+ ("human", "{input}"),
24
+ ])
25
+
26
+ def create_qa_prompt():
27
+ qa_system_prompt = """You are an assistant for question-answering tasks. Use the following pieces of retrieved context to answer the question. \
28
+ The retrieved content belongs to subject textbooks present. You will receive different chunks, each of which belongs to a single page of a textbook. \
29
+ Using the chunk given, think logically and answer the questions from the user. \
30
+ If you are not able to identify the relevant information regarding to the user's question in the retrieved chunks, then just return 'No data found'.\
31
+ Use three sentences maximum and keep the answer concise. \
32
+
33
+ {context}"""
34
+ return ChatPromptTemplate.from_messages([
35
+ ("system", qa_system_prompt),
36
+ MessagesPlaceholder("chat_history"),
37
+ ("human", "{input}"),
38
+ ])
39
+
40
+ def create_rag_chain(model, retriever):
41
+ contextualize_q_prompt = create_contextualize_q_prompt()
42
+ qa_prompt = create_qa_prompt()
43
+
44
+ history_aware_retriever = create_history_aware_retriever(model, retriever, contextualize_q_prompt)
45
+ question_answer_chain = create_stuff_documents_chain(model, qa_prompt)
46
+ return create_retrieval_chain(history_aware_retriever, question_answer_chain)
47
+
48
+ def get_conversational_rag_chain(rag_chain):
49
+ store = {}
50
+
51
+ def get_session_history(session_id: str):
52
+ if session_id not in store:
53
+ store[session_id] = ChatMessageHistory()
54
+ return store[session_id]
55
+
56
+ return RunnableWithMessageHistory(
57
+ rag_chain,
58
+ get_session_history,
59
+ input_messages_key="input",
60
+ history_messages_key="chat_history",
61
+ output_messages_key="answer",
62
+ )
utils/vector_store.py ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ from dotenv import load_dotenv
3
+ from langchain_chroma import Chroma
4
+
5
+ load_dotenv()
6
+
7
+ persist_directory = os.getenv("VECTOR_STORE")
8
+
9
+ def create_vector_store(documents, unique_ids, embeddings):
10
+ """
11
+ Creates a new vector store with the given documents, unique IDs, and embeddings.
12
+ """
13
+ vector_store = Chroma(
14
+ collection_name="NCERT-Chapters",
15
+ embedding_function=embeddings,
16
+ persist_directory=persist_directory
17
+ )
18
+ vector_store.add_documents(documents=documents, ids=unique_ids)
19
+ vector_store.persist()
20
+ return vector_store
21
+
22
+ def load_vector_store(embeddings):
23
+ """
24
+ Loads an existing vector store using the embeddings provided.
25
+ """
26
+ return Chroma(
27
+ collection_name="NCERT-Chapters",
28
+ persist_directory=persist_directory,
29
+ embedding_function=embeddings
30
+ )
31
+
32
+ def get_retriever(vector_store, k=5):
33
+ """
34
+ Returns a retriever object to search through the vector store.
35
+ """
36
+ return vector_store.as_retriever(search_kwargs={"k": k})