rajkstats commited on
Commit
d50df56
1 Parent(s): e7b26d6

Adding all files

Browse files
.gitattributes ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ *.7z filter=lfs diff=lfs merge=lfs -text
2
+ *.arrow filter=lfs diff=lfs merge=lfs -text
3
+ *.bin filter=lfs diff=lfs merge=lfs -text
4
+ *.bz2 filter=lfs diff=lfs merge=lfs -text
5
+ *.ckpt filter=lfs diff=lfs merge=lfs -text
6
+ *.ftz filter=lfs diff=lfs merge=lfs -text
7
+ *.gz filter=lfs diff=lfs merge=lfs -text
8
+ *.h5 filter=lfs diff=lfs merge=lfs -text
9
+ *.joblib filter=lfs diff=lfs merge=lfs -text
10
+ *.lfs.* filter=lfs diff=lfs merge=lfs -text
11
+ *.mlmodel filter=lfs diff=lfs merge=lfs -text
12
+ *.model filter=lfs diff=lfs merge=lfs -text
13
+ *.msgpack filter=lfs diff=lfs merge=lfs -text
14
+ *.npy filter=lfs diff=lfs merge=lfs -text
15
+ *.npz filter=lfs diff=lfs merge=lfs -text
16
+ *.onnx filter=lfs diff=lfs merge=lfs -text
17
+ *.ot filter=lfs diff=lfs merge=lfs -text
18
+ *.parquet filter=lfs diff=lfs merge=lfs -text
19
+ *.pb filter=lfs diff=lfs merge=lfs -text
20
+ *.pickle filter=lfs diff=lfs merge=lfs -text
21
+ *.pkl filter=lfs diff=lfs merge=lfs -text
22
+ *.pt filter=lfs diff=lfs merge=lfs -text
23
+ *.pth filter=lfs diff=lfs merge=lfs -text
24
+ *.rar filter=lfs diff=lfs merge=lfs -text
25
+ *.safetensors filter=lfs diff=lfs merge=lfs -text
26
+ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
27
+ *.tar.* filter=lfs diff=lfs merge=lfs -text
28
+ *.tar filter=lfs diff=lfs merge=lfs -text
29
+ *.tflite filter=lfs diff=lfs merge=lfs -text
30
+ *.tgz filter=lfs diff=lfs merge=lfs -text
31
+ *.wasm filter=lfs diff=lfs merge=lfs -text
32
+ *.xz filter=lfs diff=lfs merge=lfs -text
33
+ *.zip filter=lfs diff=lfs merge=lfs -text
34
+ *.zst filter=lfs diff=lfs merge=lfs -text
35
+ *tfevents* filter=lfs diff=lfs merge=lfs -text
.gitignore ADDED
@@ -0,0 +1,160 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Byte-compiled / optimized / DLL files
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+
6
+ # C extensions
7
+ *.so
8
+
9
+ # Distribution / packaging
10
+ .Python
11
+ build/
12
+ develop-eggs/
13
+ dist/
14
+ downloads/
15
+ eggs/
16
+ .eggs/
17
+ lib/
18
+ lib64/
19
+ parts/
20
+ sdist/
21
+ var/
22
+ wheels/
23
+ share/python-wheels/
24
+ *.egg-info/
25
+ .installed.cfg
26
+ *.egg
27
+ MANIFEST
28
+
29
+ # PyInstaller
30
+ # Usually these files are written by a python script from a template
31
+ # before PyInstaller builds the exe, so as to inject date/other infos into it.
32
+ *.manifest
33
+ *.spec
34
+
35
+ # Installer logs
36
+ pip-log.txt
37
+ pip-delete-this-directory.txt
38
+
39
+ # Unit test / coverage reports
40
+ htmlcov/
41
+ .tox/
42
+ .nox/
43
+ .coverage
44
+ .coverage.*
45
+ .cache
46
+ nosetests.xml
47
+ coverage.xml
48
+ *.cover
49
+ *.py,cover
50
+ .hypothesis/
51
+ .pytest_cache/
52
+ cover/
53
+
54
+ # Translations
55
+ *.mo
56
+ *.pot
57
+
58
+ # Django stuff:
59
+ *.log
60
+ local_settings.py
61
+ db.sqlite3
62
+ db.sqlite3-journal
63
+
64
+ # Flask stuff:
65
+ instance/
66
+ .webassets-cache
67
+
68
+ # Scrapy stuff:
69
+ .scrapy
70
+
71
+ # Sphinx documentation
72
+ docs/_build/
73
+
74
+ # PyBuilder
75
+ .pybuilder/
76
+ target/
77
+
78
+ # Jupyter Notebook
79
+ .ipynb_checkpoints
80
+
81
+ # IPython
82
+ profile_default/
83
+ ipython_config.py
84
+
85
+ # pyenv
86
+ # For a library or package, you might want to ignore these files since the code is
87
+ # intended to run in multiple environments; otherwise, check them in:
88
+ # .python-version
89
+
90
+ # pipenv
91
+ # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
92
+ # However, in case of collaboration, if having platform-specific dependencies or dependencies
93
+ # having no cross-platform support, pipenv may install dependencies that don't work, or not
94
+ # install all needed dependencies.
95
+ #Pipfile.lock
96
+
97
+ # poetry
98
+ # Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
99
+ # This is especially recommended for binary packages to ensure reproducibility, and is more
100
+ # commonly ignored for libraries.
101
+ # https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
102
+ #poetry.lock
103
+
104
+ # pdm
105
+ # Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
106
+ #pdm.lock
107
+ # pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
108
+ # in version control.
109
+ # https://pdm.fming.dev/#use-with-ide
110
+ .pdm.toml
111
+
112
+ # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
113
+ __pypackages__/
114
+
115
+ # Celery stuff
116
+ celerybeat-schedule
117
+ celerybeat.pid
118
+
119
+ # SageMath parsed files
120
+ *.sage.py
121
+
122
+ # Environments
123
+ .env
124
+ .venv
125
+ env/
126
+ venv/
127
+ ENV/
128
+ env.bak/
129
+ venv.bak/
130
+
131
+ # Spyder project settings
132
+ .spyderproject
133
+ .spyproject
134
+
135
+ # Rope project settings
136
+ .ropeproject
137
+
138
+ # mkdocs documentation
139
+ /site
140
+
141
+ # mypy
142
+ .mypy_cache/
143
+ .dmypy.json
144
+ dmypy.json
145
+
146
+ # Pyre type checker
147
+ .pyre/
148
+
149
+ # pytype static type analyzer
150
+ .pytype/
151
+
152
+ # Cython debug symbols
153
+ cython_debug/
154
+
155
+ # PyCharm
156
+ # JetBrains specific template is maintained in a separate JetBrains.gitignore that can
157
+ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
158
+ # and can be added to the global gitignore or merged into this file. For a more nuclear
159
+ # option (not recommended) you can uncomment the following to ignore the entire idea folder.
160
+ #.idea/
Dockerfile ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ FROM python:3.11
2
+ RUN useradd -m -u 1000 user
3
+ USER user
4
+ ENV HOME=/home/user \
5
+ PATH=/home/user/.local/bin:$PATH
6
+ WORKDIR $HOME/app
7
+ COPY --chown=user . $HOME/app
8
+ COPY ./requirements.txt ~/app/requirements.txt
9
+ RUN pip install -r requirements.txt
10
+ COPY . .
11
+ CMD ["chainlit", "run", "app.py", "--port", "7860"]
app.py ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Importing Python libraries
2
+ import os
3
+ import asyncio
4
+ from dotenv import load_dotenv
5
+
6
+ import chainlit as cl
7
+
8
+ from langchain.chains import ConversationalRetrievalChain
9
+ from langchain.memory import ChatMessageHistory, ConversationBufferMemory
10
+ from langchain_community.document_loaders import PyMuPDFLoader
11
+ from langchain_community.vectorstores import Qdrant
12
+ from langchain_openai import ChatOpenAI
13
+ from langchain_openai.embeddings import OpenAIEmbeddings
14
+ from langchain.text_splitter import RecursiveCharacterTextSplitter
15
+ import tiktoken
16
+
17
+ # Load environment variables from a .env file
18
+ load_dotenv()
19
+
20
+ @cl.on_chat_start
21
+ async def start_chat():
22
+ # Notify the user that the system is setting up the vector store
23
+ await cl.Message(content="Setting up Qdrant vector store. Please wait...").send()
24
+
25
+ # Load documents using PyMuPDFLoader from the specified URL
26
+ docs = PyMuPDFLoader("https://d18rn0p25nwr6d.cloudfront.net/CIK-0001326801/c7318154-f6ae-4866-89fa-f0c589f2ee3d.pdf").load()
27
+
28
+ # Define a function to calculate the token length using tiktoken
29
+ def tiktoken_len(text):
30
+ tokens = tiktoken.encoding_for_model("gpt-3.5-turbo").encode(text)
31
+ return len(tokens)
32
+
33
+ # Configure a text splitter that handles large documents
34
+ text_splitter = RecursiveCharacterTextSplitter(
35
+ chunk_size = 1000,
36
+ chunk_overlap = 0, # Ensure there is no cutoff at the edges of chunks
37
+ length_function = tiktoken_len,
38
+ )
39
+
40
+ # Split the document into manageable chunks
41
+ split_chunks = text_splitter.split_documents(docs)
42
+
43
+ # Set up the embedding model for document encoding
44
+ embedding_model = OpenAIEmbeddings(model="text-embedding-3-small")
45
+
46
+ # Asynchronously create a Qdrant vector store with the document chunks
47
+ qdrant_vectorstore = await cl.make_async(Qdrant.from_documents)(
48
+ split_chunks,
49
+ embedding_model,
50
+ location=":memory:", # Use in-memory storage for vectors
51
+ collection_name="meta_10k" # Name of the collection in Qdrant
52
+ )
53
+
54
+ # Initialize a retriever from the Qdrant vector store
55
+ qdrant_retriever = qdrant_vectorstore.as_retriever()
56
+
57
+ # Notify the user that setup is complete
58
+ await cl.Message(content="Qdrant setup complete. You can now start asking questions!").send()
59
+
60
+ # Initialize a message history to track the conversation
61
+ message_history = ChatMessageHistory()
62
+
63
+ # Set up memory to hold the conversation context and return answers
64
+ memory = ConversationBufferMemory(
65
+ memory_key="chat_history",
66
+ output_key="answer",
67
+ chat_memory=message_history,
68
+ return_messages=True,
69
+ )
70
+
71
+ # Configure the LLM for generating responses
72
+ llm = ChatOpenAI(model_name="gpt-3.5-turbo", temperature=0, streaming=True)
73
+
74
+ # Create a retrieval chain combining the LLM and the retriever
75
+ chain = ConversationalRetrievalChain.from_llm(
76
+ llm,
77
+ retriever=qdrant_retriever,
78
+ chain_type="stuff", # Specify the type of chain (customizable based on application)
79
+ memory=memory,
80
+ return_source_documents=True
81
+ )
82
+
83
+ # Store the configured chain in the user session
84
+ cl.user_session.set("chain", chain)
85
+
86
+ @cl.on_message
87
+ async def main(message: cl.Message):
88
+ # Retrieve the conversational chain from the user session
89
+ chain = cl.user_session.get("chain")
90
+ # Define a callback handler for asynchronous operations
91
+ cb = cl.AsyncLangchainCallbackHandler()
92
+
93
+ # Process the incoming message using the conversational chain
94
+ res = await chain.acall(message.content, callbacks=[cb])
95
+ answer = res["answer"] # Extract the answer from the response
96
+
97
+ # Send the processed answer back to the user
98
+ await cl.Message(content=answer).send()
chainlit.md ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Welcome to FilingFinder! 📊📄
2
+
3
+ Ready to unlock the secrets held within Meta's financial filings? You've come to the right place. FilingFinder leverages cutting-edge language models to help you quickly extract and understand critical financial data directly from Meta's 10-K documents.
4
+
5
+ ## How It Works 🚀
6
+
7
+ FilingFinder is simple to use:
8
+ 1. Enter your query related to Meta's financials—be it about cash reserves, director listings, or other specific details.
9
+ 2. Our system analyzes the text from the latest 10-K filing to provide accurate and detailed answers.
10
+
11
+ ## Features 🌟
12
+
13
+ - **Instant Retrieval:** Get real-time answers from Meta's financial documents.
14
+ - **Accurate Data:** Powered by advanced NLP, ensuring precision in data extraction.
15
+ - **User-Friendly Interface:** Designed for ease of use, regardless of your tech background.
16
+
17
+ ## Need Assistance? 🛠️
18
+
19
+ If you encounter any issues or have questions, we're here to help:
20
+ - **Support Channel:** Reach out by creating an issue on github repo
21
+
22
+ ## Let's Get Started! 🌐
23
+
24
+ Begin your financial discovery now. FilingFinder is here to guide you through Meta's extensive financial data, helping you make informed decisions with ease.
notebook/meta_filing_langchain_rag_prototype.ipynb ADDED
@@ -0,0 +1,375 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "markdown",
5
+ "metadata": {},
6
+ "source": [
7
+ "### Midterm Challenge: Building and Deploying a RAG Application"
8
+ ]
9
+ },
10
+ {
11
+ "cell_type": "markdown",
12
+ "metadata": {},
13
+ "source": [
14
+ "#### Build 🏗️\n",
15
+ "\n",
16
+ "- Data: Meta 10-k Filings\n",
17
+ "- LLM: OpenAI GPT-3.5-turbo\n",
18
+ "- Embedding Model: text-3-embedding small\n",
19
+ "- Infrastructure: LangChain or LlamaIndex (you choose)\n",
20
+ "- Vector Store: Qdrant\n",
21
+ "- Deployment: Chainlit, Hugging Face\n",
22
+ "\n",
23
+ "#### Ship 🚢\n",
24
+ "\n",
25
+ "Evaluate your answers to the following questions\n",
26
+ "- \"What was the total value of 'Cash and cash equivalents' as of December 31, 2023?\"\n",
27
+ "- \"Who are Meta's 'Directors' (i.e., members of the Board of Directors)?\"\n",
28
+ "- Record <10 min loom video walkthrough\n",
29
+ "- Extra Credit: Baseline retrieval performance w/ RAGAS, change something about your RAG system to improve it, then show the improvement quantitatively!"
30
+ ]
31
+ },
32
+ {
33
+ "cell_type": "markdown",
34
+ "metadata": {},
35
+ "source": [
36
+ "### Installing Required Libraries"
37
+ ]
38
+ },
39
+ {
40
+ "cell_type": "code",
41
+ "execution_count": 170,
42
+ "metadata": {},
43
+ "outputs": [],
44
+ "source": [
45
+ "!pip install -qU langchain langchain-core langchain-community langchain-openai"
46
+ ]
47
+ },
48
+ {
49
+ "cell_type": "code",
50
+ "execution_count": 172,
51
+ "metadata": {},
52
+ "outputs": [],
53
+ "source": [
54
+ "!pip install -qU qdrant-client\n"
55
+ ]
56
+ },
57
+ {
58
+ "cell_type": "code",
59
+ "execution_count": 171,
60
+ "metadata": {},
61
+ "outputs": [],
62
+ "source": [
63
+ "!pip install -qU tiktoken pymupdf"
64
+ ]
65
+ },
66
+ {
67
+ "cell_type": "markdown",
68
+ "metadata": {},
69
+ "source": [
70
+ "#### Set Environment Variables"
71
+ ]
72
+ },
73
+ {
74
+ "cell_type": "code",
75
+ "execution_count": 4,
76
+ "metadata": {},
77
+ "outputs": [],
78
+ "source": [
79
+ "import os\n",
80
+ "import getpass\n",
81
+ "\n",
82
+ "os.environ[\"OPENAI_API_KEY\"] = getpass.getpass(\"OpenAI API Key:\")"
83
+ ]
84
+ },
85
+ {
86
+ "cell_type": "markdown",
87
+ "metadata": {},
88
+ "source": [
89
+ "#### Data Collection"
90
+ ]
91
+ },
92
+ {
93
+ "cell_type": "code",
94
+ "execution_count": 173,
95
+ "metadata": {},
96
+ "outputs": [],
97
+ "source": [
98
+ "from langchain.document_loaders import PyMuPDFLoader\n",
99
+ "\n",
100
+ "docs = PyMuPDFLoader(\"https://d18rn0p25nwr6d.cloudfront.net/CIK-0001326801/c7318154-f6ae-4866-89fa-f0c589f2ee3d.pdf\").load()"
101
+ ]
102
+ },
103
+ {
104
+ "cell_type": "markdown",
105
+ "metadata": {},
106
+ "source": [
107
+ "#### Chunking our Meta-10k Filing Document"
108
+ ]
109
+ },
110
+ {
111
+ "cell_type": "code",
112
+ "execution_count": 174,
113
+ "metadata": {},
114
+ "outputs": [],
115
+ "source": [
116
+ "from langchain.text_splitter import RecursiveCharacterTextSplitter\n",
117
+ "import tiktoken\n",
118
+ "\n",
119
+ "enc = tiktoken.encoding_for_model(\"gpt-3.5-turbo\")\n",
120
+ "\n",
121
+ "def tiktoken_len(text):\n",
122
+ " tokens = tiktoken.encoding_for_model(\"gpt-3.5-turbo\").encode(\n",
123
+ " text,\n",
124
+ " )\n",
125
+ " return len(tokens)\n",
126
+ "\n",
127
+ "text_splitter = RecursiveCharacterTextSplitter(\n",
128
+ " chunk_size = 200,\n",
129
+ " chunk_overlap = 0, # Overlap to ensure continuity and prevent cutoffs at chunk edges\n",
130
+ " length_function = tiktoken_len,\n",
131
+ ")\n",
132
+ "\n",
133
+ "split_chunks = text_splitter.split_documents(docs)"
134
+ ]
135
+ },
136
+ {
137
+ "cell_type": "code",
138
+ "execution_count": 175,
139
+ "metadata": {},
140
+ "outputs": [
141
+ {
142
+ "data": {
143
+ "text/plain": [
144
+ "663"
145
+ ]
146
+ },
147
+ "execution_count": 175,
148
+ "metadata": {},
149
+ "output_type": "execute_result"
150
+ }
151
+ ],
152
+ "source": [
153
+ "len(split_chunks)"
154
+ ]
155
+ },
156
+ {
157
+ "cell_type": "markdown",
158
+ "metadata": {},
159
+ "source": [
160
+ "Now we have 663 ~200 token long documents"
161
+ ]
162
+ },
163
+ {
164
+ "cell_type": "markdown",
165
+ "metadata": {},
166
+ "source": [
167
+ "#### Embeddings and Vector Storage"
168
+ ]
169
+ },
170
+ {
171
+ "cell_type": "code",
172
+ "execution_count": 176,
173
+ "metadata": {},
174
+ "outputs": [],
175
+ "source": [
176
+ "from langchain_community.vectorstores import Qdrant\n",
177
+ "\n",
178
+ "from langchain_openai.embeddings import OpenAIEmbeddings\n",
179
+ "\n",
180
+ "embedding_model = OpenAIEmbeddings(model=\"text-embedding-3-small\")\n",
181
+ "\n",
182
+ "qdrant_vectorstore = Qdrant.from_documents(\n",
183
+ " split_chunks,\n",
184
+ " embedding_model,\n",
185
+ " location=\":memory:\",\n",
186
+ " collection_name=\"meta_10k_filings\",\n",
187
+ ")"
188
+ ]
189
+ },
190
+ {
191
+ "cell_type": "markdown",
192
+ "metadata": {},
193
+ "source": [
194
+ "#### Setting up our retriever using Langchain retriever method"
195
+ ]
196
+ },
197
+ {
198
+ "cell_type": "code",
199
+ "execution_count": 177,
200
+ "metadata": {},
201
+ "outputs": [],
202
+ "source": [
203
+ "qdrant_retriever = qdrant_vectorstore.as_retriever()"
204
+ ]
205
+ },
206
+ {
207
+ "cell_type": "markdown",
208
+ "metadata": {},
209
+ "source": [
210
+ "### Setting up our Langchain based RAG"
211
+ ]
212
+ },
213
+ {
214
+ "cell_type": "markdown",
215
+ "metadata": {},
216
+ "source": [
217
+ "#### Setting up our Prompt template"
218
+ ]
219
+ },
220
+ {
221
+ "cell_type": "code",
222
+ "execution_count": 154,
223
+ "metadata": {},
224
+ "outputs": [],
225
+ "source": [
226
+ "from langchain_core.prompts import ChatPromptTemplate\n",
227
+ "\n",
228
+ "RAG_PROMPT = \"\"\"\n",
229
+ "CONTEXT:\n",
230
+ "{context}\n",
231
+ "\n",
232
+ "QUERY:\n",
233
+ "{question}\n",
234
+ "\n",
235
+ "RESPONSE:\n",
236
+ "- If the QUERY is directly related to the provided CONTEXT, generate a detailed, structured answer using the information from the CONTEXT.\n",
237
+ "- If the QUERY does not pertain to the provided CONTEXT, state that the question is unrelated and suggest checking the appropriate source or document for the correct information.\n",
238
+ "\"\"\"\n",
239
+ "\n",
240
+ "rag_prompt = ChatPromptTemplate.from_template(RAG_PROMPT)\n"
241
+ ]
242
+ },
243
+ {
244
+ "cell_type": "markdown",
245
+ "metadata": {},
246
+ "source": [
247
+ "#### RAG Chain"
248
+ ]
249
+ },
250
+ {
251
+ "cell_type": "code",
252
+ "execution_count": 155,
253
+ "metadata": {},
254
+ "outputs": [],
255
+ "source": [
256
+ "from operator import itemgetter\n",
257
+ "from langchain.schema.output_parser import StrOutputParser\n",
258
+ "from langchain.schema.runnable import RunnablePassthrough\n",
259
+ "\n",
260
+ "retrieval_augmented_qa_chain = (\n",
261
+ " # INVOKE CHAIN WITH: {\"question\" : \"<>\"}\n",
262
+ " # \"question\" : populated by getting the value of the \"question\" key\n",
263
+ " # \"context\" : populated by getting the value of the \"question\" key and chaining it into the base_retriever\n",
264
+ " {\"context\": itemgetter(\"question\") | qdrant_retriever, \"question\": itemgetter(\"question\")}\n",
265
+ " # \"context\" : is assigned to a RunnablePassthrough object (will not be called or considered in the next step)\n",
266
+ " # by getting the value of the \"context\" key from the previous step\n",
267
+ " | RunnablePassthrough.assign(context=itemgetter(\"context\"))\n",
268
+ " # \"response\" : the \"context\" and \"question\" values are used to format our prompt object and then piped\n",
269
+ " # into the LLM and stored in a key called \"response\"\n",
270
+ " # \"context\" : populated by getting the value of the \"context\" key from the previous step\n",
271
+ " | {\"response\": rag_prompt | openai_chat_model, \"context\": itemgetter(\"context\")}\n",
272
+ ")"
273
+ ]
274
+ },
275
+ {
276
+ "cell_type": "code",
277
+ "execution_count": 156,
278
+ "metadata": {},
279
+ "outputs": [],
280
+ "source": [
281
+ "question= \"What was the total value of 'Cash and cash equivalents' as of December 31, 2023?\"\n",
282
+ "response = retrieval_augmented_qa_chain.invoke({\"question\" :question})\n"
283
+ ]
284
+ },
285
+ {
286
+ "cell_type": "code",
287
+ "execution_count": 147,
288
+ "metadata": {},
289
+ "outputs": [
290
+ {
291
+ "name": "stdout",
292
+ "output_type": "stream",
293
+ "text": [
294
+ "The total value of 'Cash and cash equivalents' as of December 31, 2023, was $41.862 billion. This information can be found in the document on page 107 under the section 'Inputs (Level 3).' \n",
295
+ "\n",
296
+ "Please verify this information on page 107 of the document provided.\n"
297
+ ]
298
+ }
299
+ ],
300
+ "source": [
301
+ "print(response[\"response\"].content)"
302
+ ]
303
+ },
304
+ {
305
+ "cell_type": "code",
306
+ "execution_count": 135,
307
+ "metadata": {},
308
+ "outputs": [],
309
+ "source": [
310
+ "# for context in response[\"context\"]:\n",
311
+ "# print(\"Context:\")\n",
312
+ "# print(context)\n",
313
+ "# print(\"----\")"
314
+ ]
315
+ },
316
+ {
317
+ "cell_type": "code",
318
+ "execution_count": 159,
319
+ "metadata": {},
320
+ "outputs": [],
321
+ "source": [
322
+ "question= \"Who are Meta's 'Directors' (i.e., members of the Board of Directors)?\"\n",
323
+ "response = retrieval_augmented_qa_chain.invoke({\"question\" :question})"
324
+ ]
325
+ },
326
+ {
327
+ "cell_type": "code",
328
+ "execution_count": 160,
329
+ "metadata": {},
330
+ "outputs": [
331
+ {
332
+ "name": "stdout",
333
+ "output_type": "stream",
334
+ "text": [
335
+ "The members of Meta's Board of Directors are as follows:\n",
336
+ "1. Peggy Alford\n",
337
+ "2. Marc L. Andreessen\n",
338
+ "3. Andrew W. Houston\n",
339
+ "4. Nancy Killefer\n",
340
+ "5. Robert M. Kimmitt\n",
341
+ "6. Sheryl K. Sandberg\n",
342
+ "7. Tracey T. Travis\n",
343
+ "8. Tony Xu\n",
344
+ "\n",
345
+ "These names were listed on page 132 of the document provided in the CONTEXT.\n"
346
+ ]
347
+ }
348
+ ],
349
+ "source": [
350
+ "print(response[\"response\"].content)"
351
+ ]
352
+ }
353
+ ],
354
+ "metadata": {
355
+ "kernelspec": {
356
+ "display_name": "llmops-course",
357
+ "language": "python",
358
+ "name": "python3"
359
+ },
360
+ "language_info": {
361
+ "codemirror_mode": {
362
+ "name": "ipython",
363
+ "version": 3
364
+ },
365
+ "file_extension": ".py",
366
+ "mimetype": "text/x-python",
367
+ "name": "python",
368
+ "nbconvert_exporter": "python",
369
+ "pygments_lexer": "ipython3",
370
+ "version": "3.11.8"
371
+ }
372
+ },
373
+ "nbformat": 4,
374
+ "nbformat_minor": 2
375
+ }
requirements.txt ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ chainlit==0.7.700
2
+ openai==1.25.0
3
+ tiktoken
4
+ python-dotenv==1.0.0
5
+ qdrant-client
6
+ pymupdf
7
+ langchain==0.1.16
8
+ langchain-community==0.0.34
9
+ langchain-core==0.1.46
10
+ langchain-openai==0.1.4
11
+ langchain-text-splitters==0.0.1
12
+ langchainhub==0.1.15
13
+ langsmith==0.1.51