philmui commited on
Commit
5449492
1 Parent(s): 46430f8
.chainlit/config.toml ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [project]
2
+ # Whether to enable telemetry (default: true). No personal data is collected.
3
+ enable_telemetry = true
4
+
5
+
6
+ # List of environment variables to be provided by each user to use the app.
7
+ user_env = []
8
+
9
+ # Duration (in seconds) during which the session is saved when the connection is lost
10
+ session_timeout = 3600
11
+
12
+ # Enable third parties caching (e.g LangChain cache)
13
+ cache = false
14
+
15
+ # Authorized origins
16
+ allow_origins = ["*"]
17
+
18
+ # Follow symlink for asset mount (see https://github.com/Chainlit/chainlit/issues/317)
19
+ # follow_symlink = false
20
+
21
+ [features]
22
+ # Show the prompt playground
23
+ prompt_playground = true
24
+
25
+ # Process and display HTML in messages. This can be a security risk (see https://stackoverflow.com/questions/19603097/why-is-it-dangerous-to-render-user-generated-html-or-javascript)
26
+ unsafe_allow_html = false
27
+
28
+ # Process and display mathematical expressions. This can clash with "$" characters in messages.
29
+ latex = false
30
+
31
+ # Automatically tag threads with the current chat profile (if a chat profile is used)
32
+ auto_tag_thread = true
33
+
34
+ # Authorize users to upload files with messages
35
+ [features.multi_modal]
36
+ enabled = true
37
+ accept = ["*/*"]
38
+ max_files = 20
39
+ max_size_mb = 500
40
+
41
+ # Allows user to use speech to text
42
+ [features.speech_to_text]
43
+ enabled = false
44
+ # See all languages here https://github.com/JamesBrill/react-speech-recognition/blob/HEAD/docs/API.md#language-string
45
+ # language = "en-US"
46
+
47
+ [UI]
48
+ # Name of the app and chatbot.
49
+ name = "Chatbot"
50
+
51
+ # Show the readme while the thread is empty.
52
+ show_readme_as_default = true
53
+
54
+ # Description of the app and chatbot. This is used for HTML tags.
55
+ # description = ""
56
+
57
+ # Large size content are by default collapsed for a cleaner ui
58
+ default_collapse_content = true
59
+
60
+ # The default value for the expand messages settings.
61
+ default_expand_messages = false
62
+
63
+ # Hide the chain of thought details from the user in the UI.
64
+ hide_cot = false
65
+
66
+ # Link to your github repo. This will add a github button in the UI's header.
67
+ # github = ""
68
+
69
+ # Specify a CSS file that can be used to customize the user interface.
70
+ # The CSS file can be served from the public directory or via an external link.
71
+ # custom_css = "/public/test.css"
72
+
73
+ # Specify a Javascript file that can be used to customize the user interface.
74
+ # The Javascript file can be served from the public directory.
75
+ # custom_js = "/public/test.js"
76
+
77
+ # Specify a custom font url.
78
+ # custom_font = "https://fonts.googleapis.com/css2?family=Inter:wght@400;500;700&display=swap"
79
+
80
+ # Specify a custom build directory for the frontend.
81
+ # This can be used to customize the frontend code.
82
+ # Be careful: If this is a relative path, it should not start with a slash.
83
+ # custom_build = "./public/build"
84
+
85
+ # Override default MUI light theme. (Check theme.ts)
86
+ [UI.theme]
87
+ #font_family = "Inter, sans-serif"
88
+ [UI.theme.light]
89
+ #background = "#FAFAFA"
90
+ #paper = "#FFFFFF"
91
+
92
+ [UI.theme.light.primary]
93
+ #main = "#F80061"
94
+ #dark = "#980039"
95
+ #light = "#FFE7EB"
96
+
97
+ # Override default MUI dark theme. (Check theme.ts)
98
+ [UI.theme.dark]
99
+ #background = "#FAFAFA"
100
+ #paper = "#FFFFFF"
101
+
102
+ [UI.theme.dark.primary]
103
+ #main = "#F80061"
104
+ #dark = "#980039"
105
+ #light = "#FFE7EB"
106
+
107
+
108
+ [meta]
109
+ generated_by = "1.0.505"
.chainlit/translations/en-US.json ADDED
@@ -0,0 +1,231 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "components": {
3
+ "atoms": {
4
+ "buttons": {
5
+ "userButton": {
6
+ "menu": {
7
+ "settings": "Settings",
8
+ "settingsKey": "S",
9
+ "APIKeys": "API Keys",
10
+ "logout": "Logout"
11
+ }
12
+ }
13
+ }
14
+ },
15
+ "molecules": {
16
+ "newChatButton": {
17
+ "newChat": "New Chat"
18
+ },
19
+ "tasklist": {
20
+ "TaskList": {
21
+ "title": "\ud83d\uddd2\ufe0f Task List",
22
+ "loading": "Loading...",
23
+ "error": "An error occured"
24
+ }
25
+ },
26
+ "attachments": {
27
+ "cancelUpload": "Cancel upload",
28
+ "removeAttachment": "Remove attachment"
29
+ },
30
+ "newChatDialog": {
31
+ "createNewChat": "Create new chat?",
32
+ "clearChat": "This will clear the current messages and start a new chat.",
33
+ "cancel": "Cancel",
34
+ "confirm": "Confirm"
35
+ },
36
+ "settingsModal": {
37
+ "settings": "Settings",
38
+ "expandMessages": "Expand Messages",
39
+ "hideChainOfThought": "Hide Chain of Thought",
40
+ "darkMode": "Dark Mode"
41
+ },
42
+ "detailsButton": {
43
+ "using": "Using",
44
+ "running": "Running",
45
+ "took_one": "Took {{count}} step",
46
+ "took_other": "Took {{count}} steps"
47
+ },
48
+ "auth": {
49
+ "authLogin": {
50
+ "title": "Login to access the app.",
51
+ "form": {
52
+ "email": "Email address",
53
+ "password": "Password",
54
+ "noAccount": "Don't have an account?",
55
+ "alreadyHaveAccount": "Already have an account?",
56
+ "signup": "Sign Up",
57
+ "signin": "Sign In",
58
+ "or": "OR",
59
+ "continue": "Continue",
60
+ "forgotPassword": "Forgot password?",
61
+ "passwordMustContain": "Your password must contain:",
62
+ "emailRequired": "email is a required field",
63
+ "passwordRequired": "password is a required field"
64
+ },
65
+ "error": {
66
+ "default": "Unable to sign in.",
67
+ "signin": "Try signing in with a different account.",
68
+ "oauthsignin": "Try signing in with a different account.",
69
+ "redirect_uri_mismatch": "The redirect URI is not matching the oauth app configuration.",
70
+ "oauthcallbackerror": "Try signing in with a different account.",
71
+ "oauthcreateaccount": "Try signing in with a different account.",
72
+ "emailcreateaccount": "Try signing in with a different account.",
73
+ "callback": "Try signing in with a different account.",
74
+ "oauthaccountnotlinked": "To confirm your identity, sign in with the same account you used originally.",
75
+ "emailsignin": "The e-mail could not be sent.",
76
+ "emailverify": "Please verify your email, a new email has been sent.",
77
+ "credentialssignin": "Sign in failed. Check the details you provided are correct.",
78
+ "sessionrequired": "Please sign in to access this page."
79
+ }
80
+ },
81
+ "authVerifyEmail": {
82
+ "almostThere": "You're almost there! We've sent an email to ",
83
+ "verifyEmailLink": "Please click on the link in that email to complete your signup.",
84
+ "didNotReceive": "Can't find the email?",
85
+ "resendEmail": "Resend email",
86
+ "goBack": "Go Back",
87
+ "emailSent": "Email sent successfully.",
88
+ "verifyEmail": "Verify your email address"
89
+ },
90
+ "providerButton": {
91
+ "continue": "Continue with {{provider}}",
92
+ "signup": "Sign up with {{provider}}"
93
+ },
94
+ "authResetPassword": {
95
+ "newPasswordRequired": "New password is a required field",
96
+ "passwordsMustMatch": "Passwords must match",
97
+ "confirmPasswordRequired": "Confirm password is a required field",
98
+ "newPassword": "New password",
99
+ "confirmPassword": "Confirm password",
100
+ "resetPassword": "Reset Password"
101
+ },
102
+ "authForgotPassword": {
103
+ "email": "Email address",
104
+ "emailRequired": "email is a required field",
105
+ "emailSent": "Please check the email address {{email}} for instructions to reset your password.",
106
+ "enterEmail": "Enter your email address and we will send you instructions to reset your password.",
107
+ "resendEmail": "Resend email",
108
+ "continue": "Continue",
109
+ "goBack": "Go Back"
110
+ }
111
+ }
112
+ },
113
+ "organisms": {
114
+ "chat": {
115
+ "history": {
116
+ "index": {
117
+ "showHistory": "Show history",
118
+ "lastInputs": "Last Inputs",
119
+ "noInputs": "Such empty...",
120
+ "loading": "Loading..."
121
+ }
122
+ },
123
+ "inputBox": {
124
+ "input": {
125
+ "placeholder": "Type your message here..."
126
+ },
127
+ "speechButton": {
128
+ "start": "Start recording",
129
+ "stop": "Stop recording"
130
+ },
131
+ "SubmitButton": {
132
+ "sendMessage": "Send message",
133
+ "stopTask": "Stop Task"
134
+ },
135
+ "UploadButton": {
136
+ "attachFiles": "Attach files"
137
+ },
138
+ "waterMark": {
139
+ "text": "Built with"
140
+ }
141
+ },
142
+ "Messages": {
143
+ "index": {
144
+ "running": "Running",
145
+ "executedSuccessfully": "executed successfully",
146
+ "failed": "failed",
147
+ "feedbackUpdated": "Feedback updated",
148
+ "updating": "Updating"
149
+ }
150
+ },
151
+ "dropScreen": {
152
+ "dropYourFilesHere": "Drop your files here"
153
+ },
154
+ "index": {
155
+ "failedToUpload": "Failed to upload",
156
+ "cancelledUploadOf": "Cancelled upload of",
157
+ "couldNotReachServer": "Could not reach the server",
158
+ "continuingChat": "Continuing previous chat"
159
+ },
160
+ "settings": {
161
+ "settingsPanel": "Settings panel",
162
+ "reset": "Reset",
163
+ "cancel": "Cancel",
164
+ "confirm": "Confirm"
165
+ }
166
+ },
167
+ "threadHistory": {
168
+ "sidebar": {
169
+ "filters": {
170
+ "FeedbackSelect": {
171
+ "feedbackAll": "Feedback: All",
172
+ "feedbackPositive": "Feedback: Positive",
173
+ "feedbackNegative": "Feedback: Negative"
174
+ },
175
+ "SearchBar": {
176
+ "search": "Search"
177
+ }
178
+ },
179
+ "DeleteThreadButton": {
180
+ "confirmMessage": "This will delete the thread as well as it's messages and elements.",
181
+ "cancel": "Cancel",
182
+ "confirm": "Confirm",
183
+ "deletingChat": "Deleting chat",
184
+ "chatDeleted": "Chat deleted"
185
+ },
186
+ "index": {
187
+ "pastChats": "Past Chats"
188
+ },
189
+ "ThreadList": {
190
+ "empty": "Empty...",
191
+ "today": "Today",
192
+ "yesterday": "Yesterday",
193
+ "previous7days": "Previous 7 days",
194
+ "previous30days": "Previous 30 days"
195
+ },
196
+ "TriggerButton": {
197
+ "closeSidebar": "Close sidebar",
198
+ "openSidebar": "Open sidebar"
199
+ }
200
+ },
201
+ "Thread": {
202
+ "backToChat": "Go back to chat",
203
+ "chatCreatedOn": "This chat was created on"
204
+ }
205
+ },
206
+ "header": {
207
+ "chat": "Chat",
208
+ "readme": "Readme"
209
+ }
210
+ }
211
+ },
212
+ "hooks": {
213
+ "useLLMProviders": {
214
+ "failedToFetchProviders": "Failed to fetch providers:"
215
+ }
216
+ },
217
+ "pages": {
218
+ "Design": {},
219
+ "Env": {
220
+ "savedSuccessfully": "Saved successfully",
221
+ "requiredApiKeys": "Required API Keys",
222
+ "requiredApiKeysInfo": "To use this app, the following API keys are required. The keys are stored on your device's local storage."
223
+ },
224
+ "Page": {
225
+ "notPartOfProject": "You are not part of this project."
226
+ },
227
+ "ResumeButton": {
228
+ "resumeChat": "Resume Chat"
229
+ }
230
+ }
231
+ }
.gitattributes CHANGED
@@ -17,6 +17,7 @@
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
 
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
+ *.pdf filter=lfs diff=lfs merge=lfs -text
21
  *.pickle filter=lfs diff=lfs merge=lfs -text
22
  *.pkl filter=lfs diff=lfs merge=lfs -text
23
  *.pt filter=lfs diff=lfs merge=lfs -text
.gitignore ADDED
@@ -0,0 +1,4 @@
 
 
 
 
 
1
+ wandb/
2
+ .env
3
+ __pycache__/data/qdrant/*
4
+ *.sqlite
__pycache__/chat.cpython-311.pyc ADDED
Binary file (3.94 kB). View file
 
__pycache__/globals.cpython-311.pyc ADDED
Binary file (1.17 kB). View file
 
__pycache__/lang-chat.cpython-311.pyc ADDED
Binary file (3.94 kB). View file
 
__pycache__/semantic.cpython-311.pyc ADDED
Binary file (6.99 kB). View file
 
chainlit.md ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ # Welcome to Meta's 2013 10K Analysis 🚀🤖
2
+
3
+ If you have any question, please send a note to: thephilmui@gmail.com
chat.py ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import chainlit as cl
2
+ import logging
3
+ import sys
4
+
5
+ logging.basicConfig(stream=sys.stdout, level=logging.INFO)
6
+ _logger = logging.getLogger("lang-chat")
7
+ _logger.addHandler(logging.StreamHandler(stream=sys.stdout))
8
+
9
+ from langchain_core.prompts import ChatPromptTemplate
10
+ from langchain_core.vectorstores import VectorStore
11
+
12
+ from globals import (
13
+ DEFAULT_QUESTION1,
14
+ DEFAULT_QUESTION2,
15
+ gpt35_model,
16
+ gpt4_model
17
+ )
18
+
19
+ from semantic import (
20
+ SemanticStoreFactory,
21
+ SemanticRAGChainFactory
22
+ )
23
+
24
+ _semantic_rag_chain = SemanticRAGChainFactory.get_semantic_rag_chain()
25
+
26
+ @cl.on_message
27
+ async def main(message: cl.Message):
28
+
29
+ content = "> "
30
+ try:
31
+ response = _semantic_rag_chain.invoke({"question": message.content})
32
+ content += response["response"].content
33
+ except Exception as e:
34
+ _logger.error(f"chat error: {e}")
35
+
36
+ # Send a response back to the user
37
+ await cl.Message(
38
+ content=f"{content}",
39
+ ).send()
40
+
41
+ @cl.on_chat_start
42
+ async def start():
43
+
44
+ await cl.Avatar(
45
+ name="Chatbot",
46
+ url="https://cdn-icons-png.flaticon.com/512/8649/8649595.png"
47
+ ).send()
48
+ await cl.Avatar(
49
+ name="User",
50
+ url="https://media.architecturaldigest.com/photos/5f241de2c850b2a36b415024/master/w_1600%2Cc_limit/Luke-logo.png"
51
+ ).send()
52
+
53
+ content = ""
54
+ if _semantic_rag_chain is not None:
55
+ try:
56
+ response1 = _semantic_rag_chain.invoke({"question": DEFAULT_QUESTION1})
57
+ response2 = _semantic_rag_chain.invoke({"question": DEFAULT_QUESTION2})
58
+
59
+ content = (
60
+ f"**Question**: {DEFAULT_QUESTION1}\n\n"
61
+ f"{response1['response'].content}\n\n"
62
+ f"**Question**: {DEFAULT_QUESTION2}\n\n"
63
+ f"{response2['response'].content}\n\n"
64
+ )
65
+ except Exception as e:
66
+ _logger.error(f"init error: {e}")
67
+
68
+ cl.user_session.set("message_history", [{"role": "system", "content": "Welcome to the chat!"}])
69
+ await cl.Message(
70
+ content=content + "\nHow can I help you with Meta's 2023 10K?"
71
+ ).send()
data/qdrant/semantic-chunks/.lock ADDED
@@ -0,0 +1 @@
 
 
1
+ tmp lock file
data/qdrant/semantic-chunks/meta.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"collections": {"meta10k-semantic": {"vectors": {"size": 1536, "distance": "Cosine", "hnsw_config": null, "quantization_config": null, "on_disk": null, "datatype": null}, "shard_number": null, "sharding_method": null, "replication_factor": null, "write_consistency_factor": null, "on_disk_payload": null, "hnsw_config": null, "wal_config": null, "optimizers_config": null, "init_from": null, "quantization_config": null, "sparse_vectors": null}}, "aliases": {}}
globals.py ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from dotenv import find_dotenv, load_dotenv
2
+ load_dotenv(find_dotenv())
3
+
4
+ from langchain_openai import ChatOpenAI
5
+ from langchain_openai import OpenAIEmbeddings
6
+
7
+ GPT4_MODEL_NAME = "gpt-4-turbo-2024-04-09"
8
+ GPT35_MODEL_NAME = "gpt-3.5-turbo-1106"
9
+
10
+ gpt35_model = ChatOpenAI(model=GPT35_MODEL_NAME, temperature=0.0)
11
+ gpt4_model = ChatOpenAI(model=GPT4_MODEL_NAME, temperature=0.0)
12
+ embeddings = OpenAIEmbeddings(model="text-embedding-3-small")
13
+
14
+ DEFAULT_QUESTION1 = "What was the total value of 'Cash and cash equivalents' as of December 31, 2023?"
15
+ DEFAULT_QUESTION2 = "Who are 'Directors' (i.e., members of the Board of Directors) for Meta?"
16
+
17
+ VECTOR_STORE_PATH = "./data/qdrant/semantic-chunks"
18
+ META_10K_FILE_PATH = "./data/meta-10k-2023.pdf"
19
+ META_SEMANTIC_COLLECTION = "meta10k-semantic"
20
+
llama-chat.py ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import chainlit as cl
2
+ import logging
3
+ import sys
4
+ from dotenv import find_dotenv, load_dotenv
5
+
6
+ load_dotenv(find_dotenv())
7
+ logging.basicConfig(stream=sys.stdout, level=logging.INFO)
8
+ logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stdout))
9
+
10
+ import llama_index
11
+ from llama_index.core import set_global_handler
12
+
13
+ # set_global_handler("wandb", run_args={"project": "meta-10k"})
14
+ # wandb_callback = llama_index.core.global_handler
15
+
16
+ from .globals import (
17
+ DEFAULT_QUESTION1,
18
+ DEFAULT_QUESTION2,
19
+ gpt35_model,
20
+ gpt4_mode
21
+ )
22
+
23
+ @cl.on_message
24
+ async def main(message: cl.Message):
25
+ # Your custom logic goes here...
26
+
27
+ # Send a response back to the user
28
+ await cl.Message(
29
+ content=f"Received: {message.content}",
30
+ ).send()
31
+
32
+ @cl.on_chat_start
33
+ async def start():
34
+
35
+ await cl.Message(
36
+ content="How can I help you about Meta's 2023 10K?"
37
+ ).send()
notebook/Lang Process Meta 10K.ipynb ADDED
@@ -0,0 +1,662 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "markdown",
5
+ "metadata": {},
6
+ "source": [
7
+ "# Langchain Processing of Meta 10K 2023\n",
8
+ "\n",
9
+ "- Google Doc with [instructions](https://docs.google.com/forms/d/e/1FAIpQLSfRHORtHFiPUGCiYNt2NfapWtgUQWbv5V75kUPwUAkx20r9Eg/viewform)"
10
+ ]
11
+ },
12
+ {
13
+ "cell_type": "markdown",
14
+ "metadata": {},
15
+ "source": [
16
+ "## 1. Setup"
17
+ ]
18
+ },
19
+ {
20
+ "cell_type": "code",
21
+ "execution_count": 1,
22
+ "metadata": {},
23
+ "outputs": [
24
+ {
25
+ "data": {
26
+ "text/plain": [
27
+ "True"
28
+ ]
29
+ },
30
+ "execution_count": 1,
31
+ "metadata": {},
32
+ "output_type": "execute_result"
33
+ }
34
+ ],
35
+ "source": [
36
+ "import nest_asyncio\n",
37
+ "\n",
38
+ "nest_asyncio.apply()\n",
39
+ "\n",
40
+ "import logging\n",
41
+ "import sys\n",
42
+ "import os\n",
43
+ "from dotenv import find_dotenv, load_dotenv\n",
44
+ "\n",
45
+ "load_dotenv(find_dotenv())"
46
+ ]
47
+ },
48
+ {
49
+ "cell_type": "code",
50
+ "execution_count": 2,
51
+ "metadata": {},
52
+ "outputs": [],
53
+ "source": [
54
+ "DEFAULT_QUESTION1 = \"What was the total value of 'Cash and cash equivalents' as of December 31, 2023?\"\n",
55
+ "DEFAULT_QUESTION2 = \"Who are Meta's 'Directors' (i.e., members of the Board of Directors)?\""
56
+ ]
57
+ },
58
+ {
59
+ "cell_type": "markdown",
60
+ "metadata": {},
61
+ "source": [
62
+ "## 2. Loading Document"
63
+ ]
64
+ },
65
+ {
66
+ "cell_type": "code",
67
+ "execution_count": 3,
68
+ "metadata": {},
69
+ "outputs": [
70
+ {
71
+ "data": {
72
+ "text/plain": [
73
+ "147"
74
+ ]
75
+ },
76
+ "execution_count": 3,
77
+ "metadata": {},
78
+ "output_type": "execute_result"
79
+ }
80
+ ],
81
+ "source": [
82
+ "from langchain_community.document_loaders import PyMuPDFLoader\n",
83
+ "loader = PyMuPDFLoader(\n",
84
+ " \"../data/meta-10k-2023.pdf\",\n",
85
+ ")\n",
86
+ "\n",
87
+ "# from langchain_community.document_loaders import UnstructuredPDFLoader\n",
88
+ "# loader = UnstructuredPDFLoader(\n",
89
+ "# file_path=\"../data/meta-10k-2023.pdf\",\n",
90
+ "# mode=\"elements\"\n",
91
+ "# )\n",
92
+ "\n",
93
+ "documents = loader.load()\n",
94
+ "len(documents)"
95
+ ]
96
+ },
97
+ {
98
+ "cell_type": "code",
99
+ "execution_count": 4,
100
+ "metadata": {},
101
+ "outputs": [
102
+ {
103
+ "data": {
104
+ "text/plain": [
105
+ "{'source': '../data/meta-10k-2023.pdf',\n",
106
+ " 'file_path': '../data/meta-10k-2023.pdf',\n",
107
+ " 'page': 0,\n",
108
+ " 'total_pages': 147,\n",
109
+ " 'format': 'PDF 1.4',\n",
110
+ " 'title': '0001326801-24-000012',\n",
111
+ " 'author': 'EDGAR® Online LLC, a subsidiary of OTC Markets Group',\n",
112
+ " 'subject': 'Form 10-K filed on 2024-02-02 for the period ending 2023-12-31',\n",
113
+ " 'keywords': '0001326801-24-000012; ; 10-K',\n",
114
+ " 'creator': 'EDGAR Filing HTML Converter',\n",
115
+ " 'producer': 'EDGRpdf Service w/ EO.Pdf 22.0.40.0',\n",
116
+ " 'creationDate': \"D:20240202060356-05'00'\",\n",
117
+ " 'modDate': \"D:20240202060413-05'00'\",\n",
118
+ " 'trapped': '',\n",
119
+ " 'encryption': 'Standard V2 R3 128-bit RC4'}"
120
+ ]
121
+ },
122
+ "execution_count": 4,
123
+ "metadata": {},
124
+ "output_type": "execute_result"
125
+ }
126
+ ],
127
+ "source": [
128
+ "documents[0].metadata"
129
+ ]
130
+ },
131
+ {
132
+ "cell_type": "markdown",
133
+ "metadata": {},
134
+ "source": [
135
+ "## 3. Transforming Data"
136
+ ]
137
+ },
138
+ {
139
+ "cell_type": "code",
140
+ "execution_count": 5,
141
+ "metadata": {},
142
+ "outputs": [
143
+ {
144
+ "data": {
145
+ "text/plain": [
146
+ "621"
147
+ ]
148
+ },
149
+ "execution_count": 5,
150
+ "metadata": {},
151
+ "output_type": "execute_result"
152
+ }
153
+ ],
154
+ "source": [
155
+ "from langchain.text_splitter import RecursiveCharacterTextSplitter\n",
156
+ "from langchain_core.prompts import ChatPromptTemplate\n",
157
+ "\n",
158
+ "text_splitter = RecursiveCharacterTextSplitter(\n",
159
+ " chunk_size = 1024,\n",
160
+ " chunk_overlap = 64\n",
161
+ ")\n",
162
+ "\n",
163
+ "docs = text_splitter.split_documents(documents)\n",
164
+ "len(docs)"
165
+ ]
166
+ },
167
+ {
168
+ "cell_type": "markdown",
169
+ "metadata": {},
170
+ "source": [
171
+ "## 4. Embedding & Vector Storage"
172
+ ]
173
+ },
174
+ {
175
+ "cell_type": "code",
176
+ "execution_count": 6,
177
+ "metadata": {},
178
+ "outputs": [],
179
+ "source": [
180
+ "from langchain_openai import ChatOpenAI\n",
181
+ "chat_model = ChatOpenAI(model=\"gpt-3.5-turbo\", temperature=0.0)\n",
182
+ "\n",
183
+ "# from llama_index.llms.ollama import Ollama\n",
184
+ "# chat_model = Ollama(model=\"llama3\", request_timeout=30.0)"
185
+ ]
186
+ },
187
+ {
188
+ "cell_type": "code",
189
+ "execution_count": 7,
190
+ "metadata": {},
191
+ "outputs": [],
192
+ "source": [
193
+ "from langchain_openai import OpenAIEmbeddings\n",
194
+ "embeddings = OpenAIEmbeddings(\n",
195
+ " model=\"text-embedding-3-small\"\n",
196
+ ")\n",
197
+ "\n",
198
+ "# from langchain_voyageai import VoyageAIEmbeddings\n",
199
+ "# EMBEDDING_MODEL = \"voyage-2\" # Alternative: \"voyage-lite-02-instruct\"\n",
200
+ "# embeddings = VoyageAIEmbeddings(model=EMBEDDING_MODEL, batch_size=12)\n"
201
+ ]
202
+ },
203
+ {
204
+ "cell_type": "code",
205
+ "execution_count": 8,
206
+ "metadata": {},
207
+ "outputs": [],
208
+ "source": [
209
+ "from langchain.vectorstores import Qdrant\n",
210
+ "\n",
211
+ "qdrant_vectorstore = Qdrant.from_documents(\n",
212
+ " docs,\n",
213
+ " embeddings,\n",
214
+ " path=\"../data\",\n",
215
+ " # location=\":memory:\",\n",
216
+ " collection_name=\"meta10k\",\n",
217
+ ")"
218
+ ]
219
+ },
220
+ {
221
+ "cell_type": "code",
222
+ "execution_count": null,
223
+ "metadata": {},
224
+ "outputs": [],
225
+ "source": [
226
+ "]"
227
+ ]
228
+ },
229
+ {
230
+ "cell_type": "code",
231
+ "execution_count": 9,
232
+ "metadata": {},
233
+ "outputs": [],
234
+ "source": [
235
+ "qdrant_retriever = qdrant_vectorstore.as_retriever()"
236
+ ]
237
+ },
238
+ {
239
+ "cell_type": "code",
240
+ "execution_count": 10,
241
+ "metadata": {},
242
+ "outputs": [],
243
+ "source": [
244
+ "from langchain.retrievers.multi_query import MultiQueryRetriever\n",
245
+ "\n",
246
+ "mquery_retriever = MultiQueryRetriever.from_llm(\n",
247
+ " retriever=qdrant_retriever, llm=chat_model\n",
248
+ ")"
249
+ ]
250
+ },
251
+ {
252
+ "cell_type": "markdown",
253
+ "metadata": {},
254
+ "source": [
255
+ "## 4. LCEL\n",
256
+ "\n"
257
+ ]
258
+ },
259
+ {
260
+ "cell_type": "code",
261
+ "execution_count": 11,
262
+ "metadata": {},
263
+ "outputs": [],
264
+ "source": [
265
+ "RAG_PROMPT = \"\"\"\n",
266
+ "CONTEXT:\n",
267
+ "{context}\n",
268
+ "\n",
269
+ "QUERY:\n",
270
+ "{question}\n",
271
+ "\n",
272
+ "You should only respond to user's query if the context is related to the query. If not, please reply \"I don't know\".\n",
273
+ "\"\"\"\n",
274
+ "\n",
275
+ "rag_prompt = ChatPromptTemplate.from_template(RAG_PROMPT)"
276
+ ]
277
+ },
278
+ {
279
+ "cell_type": "code",
280
+ "execution_count": 12,
281
+ "metadata": {},
282
+ "outputs": [],
283
+ "source": [
284
+ "from operator import itemgetter\n",
285
+ "from langchain.schema.output_parser import StrOutputParser\n",
286
+ "from langchain.schema.runnable import RunnablePassthrough\n",
287
+ "\n",
288
+ "retrieval_augmented_qa_chain = (\n",
289
+ " # INVOKE CHAIN WITH: {\"question\" : \"<<SOME USER QUESTION>>\"}\n",
290
+ " # \"question\" : populated by getting the value of the \"question\" key\n",
291
+ " # \"context\" : populated by getting the value of the \"question\" key and chaining it into the base_retriever\n",
292
+ " {\"context\": itemgetter(\"question\") | mquery_retriever, \"question\": itemgetter(\"question\")}\n",
293
+ " # \"context\" : is assigned to a RunnablePassthrough object (will not be called or considered in the next step)\n",
294
+ " # by getting the value of the \"context\" key from the previous step\n",
295
+ " | RunnablePassthrough.assign(context=itemgetter(\"context\"))\n",
296
+ " # \"response\" : the \"context\" and \"question\" values are used to format our prompt object and then piped\n",
297
+ " # into the LLM and stored in a key called \"response\"\n",
298
+ " # \"context\" : populated by getting the value of the \"context\" key from the previous step\n",
299
+ " | {\"response\": rag_prompt | chat_model, \"context\": itemgetter(\"context\")}\n",
300
+ ")"
301
+ ]
302
+ },
303
+ {
304
+ "cell_type": "markdown",
305
+ "metadata": {},
306
+ "source": [
307
+ "## Testing with basic RAG"
308
+ ]
309
+ },
310
+ {
311
+ "cell_type": "code",
312
+ "execution_count": 13,
313
+ "metadata": {},
314
+ "outputs": [
315
+ {
316
+ "name": "stdout",
317
+ "output_type": "stream",
318
+ "text": [
319
+ "The total value of 'Cash and cash equivalents' as of December 31, 2023, was $65.40 billion.\n"
320
+ ]
321
+ }
322
+ ],
323
+ "source": [
324
+ "response1 = retrieval_augmented_qa_chain.invoke({\"question\": DEFAULT_QUESTION1})\n",
325
+ "print(response1[\"response\"].content)"
326
+ ]
327
+ },
328
+ {
329
+ "cell_type": "code",
330
+ "execution_count": 14,
331
+ "metadata": {},
332
+ "outputs": [
333
+ {
334
+ "name": "stdout",
335
+ "output_type": "stream",
336
+ "text": [
337
+ "The Directors of Meta Platforms, Inc. mentioned in the document are:\n",
338
+ "- Robert M. Kimmitt\n",
339
+ "- Sheryl K. Sandberg\n",
340
+ "- Tracey T. Travis\n",
341
+ "- Tony Xu\n"
342
+ ]
343
+ }
344
+ ],
345
+ "source": [
346
+ "response2 = retrieval_augmented_qa_chain.invoke({\"question\": DEFAULT_QUESTION2})\n",
347
+ "print(response2[\"response\"].content)"
348
+ ]
349
+ },
350
+ {
351
+ "cell_type": "code",
352
+ "execution_count": 15,
353
+ "metadata": {},
354
+ "outputs": [
355
+ {
356
+ "name": "stdout",
357
+ "output_type": "stream",
358
+ "text": [
359
+ "The Directors mentioned in the context are Robert M. Kimmitt, Sheryl K. Sandberg, Tracey T. Travis, Tony Xu, Mark Zuckerberg, Susan Li, Aaron Anderson, Peggy Alford, Marc L. Andreessen, Andrew W. Houston, Nancy Killefer.\n"
360
+ ]
361
+ }
362
+ ],
363
+ "source": [
364
+ "response2 = retrieval_augmented_qa_chain.invoke(\n",
365
+ " {\"question\": \"Who are the 'Directors' (i.e., members of the Board of Directors)?\"})\n",
366
+ "print(response2[\"response\"].content)"
367
+ ]
368
+ },
369
+ {
370
+ "cell_type": "markdown",
371
+ "metadata": {},
372
+ "source": [
373
+ "## Semantic Chunking"
374
+ ]
375
+ },
376
+ {
377
+ "cell_type": "code",
378
+ "execution_count": 18,
379
+ "metadata": {},
380
+ "outputs": [],
381
+ "source": [
382
+ "from langchain_experimental.text_splitter import SemanticChunker\n",
383
+ "\n",
384
+ "semantic_chunker = SemanticChunker(\n",
385
+ " OpenAIEmbeddings(model=\"text-embedding-3-large\"), \n",
386
+ " breakpoint_threshold_type=\"percentile\"\n",
387
+ ")"
388
+ ]
389
+ },
390
+ {
391
+ "cell_type": "code",
392
+ "execution_count": 21,
393
+ "metadata": {},
394
+ "outputs": [
395
+ {
396
+ "data": {
397
+ "text/plain": [
398
+ "147"
399
+ ]
400
+ },
401
+ "execution_count": 21,
402
+ "metadata": {},
403
+ "output_type": "execute_result"
404
+ }
405
+ ],
406
+ "source": [
407
+ "len(documents)"
408
+ ]
409
+ },
410
+ {
411
+ "cell_type": "code",
412
+ "execution_count": 22,
413
+ "metadata": {},
414
+ "outputs": [
415
+ {
416
+ "data": {
417
+ "text/plain": [
418
+ "Document(page_content='UNITED STATES\\nSECURITIES AND EXCHANGE COMMISSION\\nWashington, D.C.\\xa020549\\n__________________________\\nFORM 10-K\\n__________________________\\n(Mark One)\\n☒\\xa0\\xa0\\xa0\\xa0ANNUAL REPORT PURSUANT TO SECTION 13 OR 15(d)\\xa0OF THE SECURITIES EXCHANGE ACT OF 1934\\nFor the fiscal year ended December\\xa031, 2023\\nor\\n☐\\xa0\\xa0\\xa0\\xa0TRANSITION REPORT PURSUANT TO SECTION 13 OR 15(d)\\xa0OF THE SECURITIES EXCHANGE ACT OF 1934\\nFor the transition period from\\xa0\\xa0\\xa0\\xa0\\xa0\\xa0\\xa0\\xa0\\xa0\\xa0\\xa0\\xa0to\\xa0\\xa0\\xa0\\xa0\\xa0\\xa0\\xa0\\xa0\\xa0\\xa0\\xa0\\xa0\\nCommission File Number:\\xa0001-35551\\n__________________________\\nMeta Platforms, Inc.\\n(Exact name of registrant as specified in its charter)\\n__________________________\\nDelaware\\n20-1665019\\n(State or other jurisdiction of incorporation or organization)\\n(I.R.S. Employer Identification Number)\\n1 Meta Way, Menlo Park, California 94025\\n(Address of principal executive offices and Zip Code)\\n(650)\\xa0543-4800\\n(Registrant\\'s telephone number, including area code)\\n__________________________\\nSecurities registered pursuant to Section 12(b) of the Act:\\nTitle of each class\\nTrading symbol(s)\\nName of each exchange on which registered\\nClass A Common Stock, $0.000006 par value\\nMETA\\nThe Nasdaq Stock Market LLC\\nSecurities registered pursuant to Section 12(g) of the Act: None\\nIndicate by check mark if the registrant is a well-known seasoned issuer, as defined in Rule 405 of the Securities Act.\\xa0\\xa0\\xa0\\xa0Yes\\xa0\\xa0☒\\xa0\\xa0No\\xa0\\xa0 ☐\\nIndicate by check mark if the registrant is not required to file reports pursuant to Section 13 or Section 15(d) of the Act.\\xa0\\xa0\\xa0\\xa0Yes \\xa0☐\\xa0No\\xa0 ☒\\nIndicate by check mark whether the registrant\\xa0(1)\\xa0has filed all reports required to be filed by Section\\xa013 or 15(d) of the Securities Exchange Act of 1934 (Exchange Act) during the preceding\\n12\\xa0months (or for such shorter period that the registrant was required to file such reports), and\\xa0(2)\\xa0has been subject to such filing requirements for the past 90\\xa0days.\\xa0\\xa0\\xa0\\xa0Yes\\xa0\\xa0☒\\xa0\\xa0\\xa0\\xa0No\\xa0\\xa0☐\\nIndicate by check mark whether the registrant has submitted electronically every Interactive Data File required to be submitted pursuant to Rule 405 of Regulation S-T (§\\xa0232.405 of this chapter)\\nduring the preceding 12 months (or for such shorter period that the registrant was required to submit such files).\\xa0\\xa0\\xa0\\xa0Yes\\xa0\\xa0☒\\xa0\\xa0\\xa0\\xa0No\\xa0\\xa0☐\\nIndicate by check mark whether the registrant is a large accelerated filer, an accelerated filer, a non-accelerated filer, a smaller reporting company, or an emerging growth company. See the definitions\\nof \"large accelerated filer,\" \"accelerated filer,\" \"smaller reporting company,\" and \"emerging growth company\" in Rule 12b-2 of the Exchange Act.\\nLarge accelerated filer\\n☒\\nAccelerated\\xa0filer\\n☐\\nNon-accelerated filer\\n☐\\nSmaller\\xa0reporting\\xa0company\\n☐\\nEmerging growth company\\n☐\\nIf an emerging growth company, indicate by check mark if the registrant has elected not to use the extended transition period for complying with any new or revised financial accounting standards\\nprovided pursuant to Section 13(a) of the Exchange Act. ☐\\nIndicate by check mark whether the registrant has filed a report on and attestation to its management\\'s assessment of the effectiveness of its internal control over financial reporting under Section\\n404(b) of the Sarbanes-Oxley Act (15 U.S.C. 7262(b)) by the registered public accounting firm that prepared or issued its audit report. ☒\\nIf securities are registered pursuant to Section 12(b) of the Act, indicate by check mark whether the financial statements of the registrant included in the filing reflect the correction of an error to\\npreviously issued financial statements. ☐\\nIndicate by check mark whether any of those error corrections are restatements that required a recovery analysis of incentive-based compensation received by any of the registrant’s executive officers\\nduring the relevant recovery period pursuant to §240.10D-1(b). ☐\\nIndicate by check mark whether the registrant is a shell company (as defined in Rule 12b-2 of the Exchange Act).\\xa0\\xa0\\xa0\\xa0Yes\\xa0\\xa0☐\\xa0\\xa0\\xa0\\xa0No\\xa0\\xa0 ☒\\nThe aggregate market value of the voting and non-voting stock held by non-affiliates of the registrant as of June\\xa030, 2023, the last business day of the registrant\\'s most recently completed second fiscal\\nquarter, was $637\\xa0billion based upon the closing price reported for such date on the Nasdaq Global Select Market. On January\\xa026, 2024, the registrant had 2,200,048,907 shares of Class\\xa0A common\\nstock and 349,356,199 shares of Class B common stock outstanding.\\n', metadata={'source': '../data/meta-10k-2023.pdf', 'file_path': '../data/meta-10k-2023.pdf', 'page': 0, 'total_pages': 147, 'format': 'PDF 1.4', 'title': '0001326801-24-000012', 'author': 'EDGAR® Online LLC, a subsidiary of OTC Markets Group', 'subject': 'Form 10-K filed on 2024-02-02 for the period ending 2023-12-31', 'keywords': '0001326801-24-000012; ; 10-K', 'creator': 'EDGAR Filing HTML Converter', 'producer': 'EDGRpdf Service w/ EO.Pdf 22.0.40.0', 'creationDate': \"D:20240202060356-05'00'\", 'modDate': \"D:20240202060413-05'00'\", 'trapped': '', 'encryption': 'Standard V2 R3 128-bit RC4'})"
419
+ ]
420
+ },
421
+ "execution_count": 22,
422
+ "metadata": {},
423
+ "output_type": "execute_result"
424
+ }
425
+ ],
426
+ "source": [
427
+ "documents[0]"
428
+ ]
429
+ },
430
+ {
431
+ "cell_type": "code",
432
+ "execution_count": 23,
433
+ "metadata": {},
434
+ "outputs": [],
435
+ "source": [
436
+ "semantic_chunks = semantic_chunker.create_documents([d.page_content for d in documents])"
437
+ ]
438
+ },
439
+ {
440
+ "cell_type": "code",
441
+ "execution_count": 24,
442
+ "metadata": {},
443
+ "outputs": [
444
+ {
445
+ "data": {
446
+ "text/plain": [
447
+ "346"
448
+ ]
449
+ },
450
+ "execution_count": 24,
451
+ "metadata": {},
452
+ "output_type": "execute_result"
453
+ }
454
+ ],
455
+ "source": [
456
+ "len(semantic_chunks)"
457
+ ]
458
+ },
459
+ {
460
+ "cell_type": "markdown",
461
+ "metadata": {},
462
+ "source": [
463
+ "## Creating a RAG Pipeline using Semantic Chunks"
464
+ ]
465
+ },
466
+ {
467
+ "cell_type": "code",
468
+ "execution_count": 26,
469
+ "metadata": {},
470
+ "outputs": [],
471
+ "source": [
472
+ "semantic_chunk_vectorstore = Qdrant.from_documents(\n",
473
+ " semantic_chunks,\n",
474
+ " embeddings,\n",
475
+ " path=\"../data/semantic-chunks\",\n",
476
+ " # location=\":memory:\",\n",
477
+ " collection_name=\"meta10k-semantic\",\n",
478
+ ")"
479
+ ]
480
+ },
481
+ {
482
+ "cell_type": "code",
483
+ "execution_count": null,
484
+ "metadata": {},
485
+ "outputs": [],
486
+ "source": [
487
+ "semantic_chunk_vectorstore"
488
+ ]
489
+ },
490
+ {
491
+ "cell_type": "code",
492
+ "execution_count": 27,
493
+ "metadata": {},
494
+ "outputs": [],
495
+ "source": [
496
+ "semantic_chunk_retriever = semantic_chunk_vectorstore.as_retriever()"
497
+ ]
498
+ },
499
+ {
500
+ "cell_type": "code",
501
+ "execution_count": 28,
502
+ "metadata": {},
503
+ "outputs": [],
504
+ "source": [
505
+ "from langchain.retrievers.multi_query import MultiQueryRetriever\n",
506
+ "\n",
507
+ "semantic_mquery_retriever = MultiQueryRetriever.from_llm(\n",
508
+ " retriever=semantic_chunk_retriever, \n",
509
+ " llm=chat_model\n",
510
+ ")"
511
+ ]
512
+ },
513
+ {
514
+ "cell_type": "code",
515
+ "execution_count": 32,
516
+ "metadata": {},
517
+ "outputs": [],
518
+ "source": [
519
+ "semantic_retrieval_augmented_qa_chain = (\n",
520
+ " # INVOKE CHAIN WITH: {\"question\" : \"<<SOME USER QUESTION>>\"}\n",
521
+ " # \"question\" : populated by getting the value of the \"question\" key\n",
522
+ " # \"context\" : populated by getting the value of the \"question\" key and chaining it into the base_retriever\n",
523
+ " {\"context\": itemgetter(\"question\") | semantic_mquery_retriever, \"question\": itemgetter(\"question\")}\n",
524
+ " # \"context\" : is assigned to a RunnablePassthrough object (will not be called or considered in the next step)\n",
525
+ " # by getting the value of the \"context\" key from the previous step\n",
526
+ " | RunnablePassthrough.assign(context=itemgetter(\"context\"))\n",
527
+ " # \"response\" : the \"context\" and \"question\" values are used to format our prompt object and then piped\n",
528
+ " # into the LLM and stored in a key called \"response\"\n",
529
+ " # \"context\" : populated by getting the value of the \"context\" key from the previous step\n",
530
+ " | {\"response\": rag_prompt | chat_model, \"context\": itemgetter(\"context\")}\n",
531
+ ")"
532
+ ]
533
+ },
534
+ {
535
+ "cell_type": "code",
536
+ "execution_count": 36,
537
+ "metadata": {},
538
+ "outputs": [
539
+ {
540
+ "data": {
541
+ "text/plain": [
542
+ "langchain_core.runnables.base.RunnableSequence"
543
+ ]
544
+ },
545
+ "execution_count": 36,
546
+ "metadata": {},
547
+ "output_type": "execute_result"
548
+ }
549
+ ],
550
+ "source": [
551
+ "type(semantic_retrieval_augmented_qa_chain)"
552
+ ]
553
+ },
554
+ {
555
+ "cell_type": "markdown",
556
+ "metadata": {},
557
+ "source": [
558
+ "## Testing with Semantic Chunk RAG"
559
+ ]
560
+ },
561
+ {
562
+ "cell_type": "code",
563
+ "execution_count": 33,
564
+ "metadata": {},
565
+ "outputs": [
566
+ {
567
+ "name": "stdout",
568
+ "output_type": "stream",
569
+ "text": [
570
+ "The total value of 'Cash and cash equivalents' as of December 31, 2023, was $41.862 billion.\n"
571
+ ]
572
+ }
573
+ ],
574
+ "source": [
575
+ "semantic_response1 = semantic_retrieval_augmented_qa_chain.invoke({\"question\": DEFAULT_QUESTION1})\n",
576
+ "print(semantic_response1[\"response\"].content)"
577
+ ]
578
+ },
579
+ {
580
+ "cell_type": "code",
581
+ "execution_count": 34,
582
+ "metadata": {},
583
+ "outputs": [
584
+ {
585
+ "name": "stdout",
586
+ "output_type": "stream",
587
+ "text": [
588
+ "The Directors of Meta, as mentioned in the provided documents, include:\n",
589
+ "- Andrew W. Houston\n",
590
+ "- Nancy Killefer\n",
591
+ "- Robert M. Kimmitt\n",
592
+ "- Sheryl K. Sandberg\n",
593
+ "- Tracey T. Travis\n",
594
+ "- Tony Xu\n"
595
+ ]
596
+ }
597
+ ],
598
+ "source": [
599
+ "semantic_response2 = semantic_retrieval_augmented_qa_chain.invoke({\"question\": DEFAULT_QUESTION2})\n",
600
+ "print(semantic_response2[\"response\"].content)"
601
+ ]
602
+ },
603
+ {
604
+ "cell_type": "code",
605
+ "execution_count": 35,
606
+ "metadata": {},
607
+ "outputs": [
608
+ {
609
+ "name": "stdout",
610
+ "output_type": "stream",
611
+ "text": [
612
+ "The members of the Board of Directors mentioned in the provided documents are:\n",
613
+ "- Andrew W. Houston\n",
614
+ "- Nancy Killefer\n",
615
+ "- Robert M. Kimmitt\n",
616
+ "- Sheryl K. Sandberg\n",
617
+ "- Tracey T. Travis\n",
618
+ "- Tony Xu\n",
619
+ "- Mark Zuckerberg\n",
620
+ "- Susan Li\n",
621
+ "- Aaron Anderson\n",
622
+ "- Peggy Alford\n",
623
+ "- Marc L. Andreessen\n"
624
+ ]
625
+ }
626
+ ],
627
+ "source": [
628
+ "response2 = semantic_retrieval_augmented_qa_chain.invoke(\n",
629
+ " {\"question\": \"Who are the 'Directors' (i.e., members of the Board of Directors)?\"})\n",
630
+ "print(response2[\"response\"].content)"
631
+ ]
632
+ },
633
+ {
634
+ "cell_type": "code",
635
+ "execution_count": null,
636
+ "metadata": {},
637
+ "outputs": [],
638
+ "source": []
639
+ }
640
+ ],
641
+ "metadata": {
642
+ "kernelspec": {
643
+ "display_name": "llmops",
644
+ "language": "python",
645
+ "name": "python3"
646
+ },
647
+ "language_info": {
648
+ "codemirror_mode": {
649
+ "name": "ipython",
650
+ "version": 3
651
+ },
652
+ "file_extension": ".py",
653
+ "mimetype": "text/x-python",
654
+ "name": "python",
655
+ "nbconvert_exporter": "python",
656
+ "pygments_lexer": "ipython3",
657
+ "version": "3.11.8"
658
+ }
659
+ },
660
+ "nbformat": 4,
661
+ "nbformat_minor": 2
662
+ }
notebook/Llama Process Meta 10K.ipynb ADDED
@@ -0,0 +1,875 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "markdown",
5
+ "metadata": {},
6
+ "source": [
7
+ "# Notebook for ingesting & processing Meta's 2023 10K\n",
8
+ "\n",
9
+ "- Google Doc with [instructions](https://docs.google.com/forms/d/e/1FAIpQLSfRHORtHFiPUGCiYNt2NfapWtgUQWbv5V75kUPwUAkx20r9Eg/viewform)"
10
+ ]
11
+ },
12
+ {
13
+ "cell_type": "markdown",
14
+ "metadata": {},
15
+ "source": [
16
+ "## 1. Setup"
17
+ ]
18
+ },
19
+ {
20
+ "cell_type": "code",
21
+ "execution_count": 2,
22
+ "metadata": {},
23
+ "outputs": [],
24
+ "source": [
25
+ "import nest_asyncio\n",
26
+ "\n",
27
+ "nest_asyncio.apply()\n",
28
+ "\n",
29
+ "import logging\n",
30
+ "import sys\n",
31
+ "import os\n",
32
+ "from dotenv import find_dotenv, load_dotenv\n",
33
+ "\n",
34
+ "load_dotenv(find_dotenv())\n",
35
+ "logging.basicConfig(stream=sys.stdout, level=logging.INFO)\n",
36
+ "logging.getLogger().addHandler(logging.StreamHandler(stream=sys.stdout))"
37
+ ]
38
+ },
39
+ {
40
+ "cell_type": "code",
41
+ "execution_count": 3,
42
+ "metadata": {},
43
+ "outputs": [],
44
+ "source": [
45
+ "import llama_index\n",
46
+ "# from llama_index.core import set_global_handler\n",
47
+ "\n",
48
+ "# os.environ[\"WANDB_NOTEBOOK_NAME\"] = \"Process Meta 10K.ipynb\"\n",
49
+ "# set_global_handler(\"wandb\", run_args={\"project\": \"meta-10k\"})\n",
50
+ "# wandb_callback = llama_index.core.global_handler"
51
+ ]
52
+ },
53
+ {
54
+ "cell_type": "code",
55
+ "execution_count": 14,
56
+ "metadata": {},
57
+ "outputs": [],
58
+ "source": [
59
+ "from llama_index.llms.openai import OpenAI\n",
60
+ "from llama_index.embeddings.openai import OpenAIEmbedding\n",
61
+ "from llama_index.core import Settings\n",
62
+ "\n",
63
+ "GPT4_MODEL_NAME = \"gpt-4-turbo-2024-04-09\"\n",
64
+ "GPT35_MODEL_NAME = \"gpt-3.5-turbo-1106\"\n",
65
+ "\n",
66
+ "gpt35_model = OpenAI(model=GPT35_MODEL_NAME, temperature=0.0)\n",
67
+ "gpt4_model = OpenAI(model=GPT4_MODEL_NAME, temperature=0.0)\n",
68
+ "\n",
69
+ "Settings.llm = OpenAI(model=GPT35_MODEL_NAME)\n",
70
+ "Settings.embed_model = OpenAIEmbedding(model=\"text-embedding-3-small\")\n",
71
+ "\n",
72
+ "DEFAULT_QUESTION1 = \"What was the total value of 'Cash and cash equivalents' as of December 31, 2023?\"\n",
73
+ "DEFAULT_QUESTION2 = \"Who are Meta's 'Directors' (i.e., members of the Board of Directors)?\""
74
+ ]
75
+ },
76
+ {
77
+ "cell_type": "markdown",
78
+ "metadata": {},
79
+ "source": [
80
+ "## 2. Ingest Document"
81
+ ]
82
+ },
83
+ {
84
+ "cell_type": "code",
85
+ "execution_count": 5,
86
+ "metadata": {},
87
+ "outputs": [
88
+ {
89
+ "name": "stdout",
90
+ "output_type": "stream",
91
+ "text": [
92
+ "Started parsing the file under job_id fa8037ef-65ef-40e0-a756-a09f00a05502\n",
93
+ "1\n"
94
+ ]
95
+ }
96
+ ],
97
+ "source": [
98
+ "from llama_parse import LlamaParse\n",
99
+ "from llama_index.core import SimpleDirectoryReader\n",
100
+ "\n",
101
+ "# assumes that the env has the key LLAMA_CLOUD_API_KEY\n",
102
+ "parser = LlamaParse(\n",
103
+ " result_type=\"markdown\",\n",
104
+ " verbose=True\n",
105
+ ")\n",
106
+ "\n",
107
+ "file_extractor = {\".pdf\": parser}\n",
108
+ "documents = SimpleDirectoryReader(\n",
109
+ " input_dir=\"../data\", \n",
110
+ " file_extractor=file_extractor\n",
111
+ ").load_data(num_workers=10)\n",
112
+ "\n",
113
+ "print(len(documents))"
114
+ ]
115
+ },
116
+ {
117
+ "cell_type": "code",
118
+ "execution_count": 6,
119
+ "metadata": {},
120
+ "outputs": [
121
+ {
122
+ "name": "stdout",
123
+ "output_type": "stream",
124
+ "text": [
125
+ "## SECURITIES AND EXCHANGE COMMISSION UNITED STATES Washington, D.C. 20549\n",
126
+ "\n",
127
+ "## FORM 10-K\n",
128
+ "\n",
129
+ "(Mark One)\n",
130
+ "\n",
131
+ "☒ ANNUAL REPORT PURSUANT TO SECTION 13 OR 15(d) OF THE SECURITIES EXCHANGE ACT OF 1934\n",
132
+ "\n",
133
+ "For the fiscal year ended December or 31, 2023\n",
134
+ "\n",
135
+ "☐ TRANSITION REPORT PURSUANT TO SECTION 13 OR 15(d) OF THE SECURITIES EXCHANGE ACT OF 1934\n",
136
+ "\n",
137
+ "For the transition period from to\n",
138
+ "\n",
139
+ "Commission File Number: 001-35551\n",
140
+ "\n",
141
+ "Meta Platforms, Inc. Meta\n",
142
+ "\n",
143
+ "(Exact name of registrant as specified in its charter)\n",
144
+ "\n",
145
+ "Delaware 20-1665019\n",
146
+ "\n",
147
+ "(State or other jurisdiction of incorporation or organization) 1 Meta Way, Menlo Park, California 94025 (I.R.S. Employer Identification Number)\n",
148
+ "\n",
149
+ "(Address of principal executive offices and Zip Code)\n",
150
+ "\n",
151
+ "(650) 543-4800\n",
152
+ "\n",
153
+ "(Registrant's telephone number, including area code)\n",
154
+ "\n",
155
+ "Securities registered pursuant to Section 12(b) of the Act:\n",
156
+ "\n",
157
+ "|Title of each class|Trading symbol(s)|Name of each exchange on which registered|\n",
158
+ "|---|---|---|\n",
159
+ "|Class A Common Stock, $0.000006 par value|META|The Nasdaq Stock Mark...\n"
160
+ ]
161
+ }
162
+ ],
163
+ "source": [
164
+ "# let's check to make sure that this is a 10-K file\n",
165
+ "print(documents[0].text[:1000] + \"...\")"
166
+ ]
167
+ },
168
+ {
169
+ "cell_type": "markdown",
170
+ "metadata": {},
171
+ "source": [
172
+ "## 3. Indexing "
173
+ ]
174
+ },
175
+ {
176
+ "cell_type": "code",
177
+ "execution_count": 7,
178
+ "metadata": {},
179
+ "outputs": [],
180
+ "source": [
181
+ "from llama_index.core.node_parser import MarkdownElementNodeParser\n",
182
+ "from llama_index.core import VectorStoreIndex\n",
183
+ "\n",
184
+ "node_parser = MarkdownElementNodeParser(\n",
185
+ " llm=gpt35_model,\n",
186
+ " num_workers=10\n",
187
+ ")"
188
+ ]
189
+ },
190
+ {
191
+ "cell_type": "code",
192
+ "execution_count": null,
193
+ "metadata": {},
194
+ "outputs": [],
195
+ "source": [
196
+ "nodes = node_parser.get_nodes_from_documents(documents=documents)\n",
197
+ "base_nodes, objects = node_parser.get_nodes_and_objects(nodes=nodes)"
198
+ ]
199
+ },
200
+ {
201
+ "cell_type": "code",
202
+ "execution_count": 9,
203
+ "metadata": {},
204
+ "outputs": [
205
+ {
206
+ "name": "stdout",
207
+ "output_type": "stream",
208
+ "text": [
209
+ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
210
+ "HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
211
+ "HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
212
+ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
213
+ "HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
214
+ "HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
215
+ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
216
+ "HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
217
+ "HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
218
+ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
219
+ "HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
220
+ "HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
221
+ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
222
+ "HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
223
+ "HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n"
224
+ ]
225
+ }
226
+ ],
227
+ "source": [
228
+ "recursive_index = VectorStoreIndex(nodes=base_nodes + objects)\n",
229
+ "raw_index = VectorStoreIndex.from_documents(documents=documents)"
230
+ ]
231
+ },
232
+ {
233
+ "cell_type": "markdown",
234
+ "metadata": {},
235
+ "source": [
236
+ "## 4. Raw Query Engine"
237
+ ]
238
+ },
239
+ {
240
+ "cell_type": "code",
241
+ "execution_count": 35,
242
+ "metadata": {},
243
+ "outputs": [],
244
+ "source": [
245
+ "from llama_index.postprocessor.cohere_rerank import CohereRerank\n",
246
+ "reranker = CohereRerank(top_n=6)\n",
247
+ "\n",
248
+ "raw_query_engine = recursive_index.as_query_engine(\n",
249
+ " llm=gpt4_model,\n",
250
+ " similarity_top_k=15,\n",
251
+ " node_postprocessors=[reranker],\n",
252
+ " verbose = True\n",
253
+ ")"
254
+ ]
255
+ },
256
+ {
257
+ "cell_type": "code",
258
+ "execution_count": 36,
259
+ "metadata": {},
260
+ "outputs": [
261
+ {
262
+ "name": "stdout",
263
+ "output_type": "stream",
264
+ "text": [
265
+ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
266
+ "HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
267
+ "HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
268
+ "\u001b[1;3;38;2;11;159;203mRetrieval entering 7873de31-b332-4365-bd65-0a4b84f47da6: TextNode\n",
269
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query What was the total value of 'Cash and cash equivalents' as of December 31, 2023?\n",
270
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering 4e8c6d95-87fd-423a-84ca-06c2d21c427e: TextNode\n",
271
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query What was the total value of 'Cash and cash equivalents' as of December 31, 2023?\n",
272
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering c7ec1eec-24ee-4c3e-81ba-ca81d1a91389: TextNode\n",
273
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query What was the total value of 'Cash and cash equivalents' as of December 31, 2023?\n",
274
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering 99462df3-001a-458a-97ef-89bd51518f88: TextNode\n",
275
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query What was the total value of 'Cash and cash equivalents' as of December 31, 2023?\n",
276
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering 580282f7-7c4e-4ba5-a559-636959b71ec8: TextNode\n",
277
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query What was the total value of 'Cash and cash equivalents' as of December 31, 2023?\n",
278
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering f333c293-2f5b-4a99-a1e8-4bc9a22a1508: TextNode\n",
279
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query What was the total value of 'Cash and cash equivalents' as of December 31, 2023?\n",
280
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering 4044f21f-899a-4fcc-8caa-3b6f8fc4e92c: TextNode\n",
281
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query What was the total value of 'Cash and cash equivalents' as of December 31, 2023?\n",
282
+ "\u001b[0mINFO:httpx:HTTP Request: POST https://api.cohere.ai/v1/rerank \"HTTP/1.1 200 OK\"\n",
283
+ "HTTP Request: POST https://api.cohere.ai/v1/rerank \"HTTP/1.1 200 OK\"\n",
284
+ "HTTP Request: POST https://api.cohere.ai/v1/rerank \"HTTP/1.1 200 OK\"\n",
285
+ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
286
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
287
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
288
+ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
289
+ "HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
290
+ "HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
291
+ "\u001b[1;3;38;2;11;159;203mRetrieval entering 3bdc6a30-8c4e-41d0-935f-78cb3888a00c: TextNode\n",
292
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query Who are Meta's 'Directors' (i.e., members of the Board of Directors)?\n",
293
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering 94beb3bf-edb3-42d1-a7fe-9b7691f219ca: TextNode\n",
294
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query Who are Meta's 'Directors' (i.e., members of the Board of Directors)?\n",
295
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering caf09ded-aadb-479d-a589-28f16b4e9a93: TextNode\n",
296
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query Who are Meta's 'Directors' (i.e., members of the Board of Directors)?\n",
297
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering 20b634e2-27ce-4343-ae60-3694cc2c276d: TextNode\n",
298
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query Who are Meta's 'Directors' (i.e., members of the Board of Directors)?\n",
299
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering 3ead0e8d-0e03-4a0c-9908-ea1e3f9375be: TextNode\n",
300
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query Who are Meta's 'Directors' (i.e., members of the Board of Directors)?\n",
301
+ "\u001b[0mINFO:httpx:HTTP Request: POST https://api.cohere.ai/v1/rerank \"HTTP/1.1 200 OK\"\n",
302
+ "HTTP Request: POST https://api.cohere.ai/v1/rerank \"HTTP/1.1 200 OK\"\n",
303
+ "HTTP Request: POST https://api.cohere.ai/v1/rerank \"HTTP/1.1 200 OK\"\n",
304
+ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
305
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
306
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
307
+ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
308
+ "HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
309
+ "HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
310
+ "\u001b[1;3;38;2;11;159;203mRetrieval entering 7873de31-b332-4365-bd65-0a4b84f47da6: TextNode\n",
311
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query What was the total value of 'Cash and cash equivalents' as of December 31, 2023?\n",
312
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering 4e8c6d95-87fd-423a-84ca-06c2d21c427e: TextNode\n",
313
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query What was the total value of 'Cash and cash equivalents' as of December 31, 2023?\n",
314
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering c7ec1eec-24ee-4c3e-81ba-ca81d1a91389: TextNode\n",
315
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query What was the total value of 'Cash and cash equivalents' as of December 31, 2023?\n",
316
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering 99462df3-001a-458a-97ef-89bd51518f88: TextNode\n",
317
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query What was the total value of 'Cash and cash equivalents' as of December 31, 2023?\n",
318
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering 580282f7-7c4e-4ba5-a559-636959b71ec8: TextNode\n",
319
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query What was the total value of 'Cash and cash equivalents' as of December 31, 2023?\n",
320
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering f333c293-2f5b-4a99-a1e8-4bc9a22a1508: TextNode\n",
321
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query What was the total value of 'Cash and cash equivalents' as of December 31, 2023?\n",
322
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering 4044f21f-899a-4fcc-8caa-3b6f8fc4e92c: TextNode\n",
323
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query What was the total value of 'Cash and cash equivalents' as of December 31, 2023?\n",
324
+ "\u001b[0mINFO:httpx:HTTP Request: POST https://api.cohere.ai/v1/rerank \"HTTP/1.1 200 OK\"\n",
325
+ "HTTP Request: POST https://api.cohere.ai/v1/rerank \"HTTP/1.1 200 OK\"\n",
326
+ "HTTP Request: POST https://api.cohere.ai/v1/rerank \"HTTP/1.1 200 OK\"\n",
327
+ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
328
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
329
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
330
+ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
331
+ "HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
332
+ "HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
333
+ "\u001b[1;3;38;2;11;159;203mRetrieval entering 3bdc6a30-8c4e-41d0-935f-78cb3888a00c: TextNode\n",
334
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query Who are Meta's 'Directors' (i.e., members of the Board of Directors)?\n",
335
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering 94beb3bf-edb3-42d1-a7fe-9b7691f219ca: TextNode\n",
336
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query Who are Meta's 'Directors' (i.e., members of the Board of Directors)?\n",
337
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering caf09ded-aadb-479d-a589-28f16b4e9a93: TextNode\n",
338
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query Who are Meta's 'Directors' (i.e., members of the Board of Directors)?\n",
339
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering 20b634e2-27ce-4343-ae60-3694cc2c276d: TextNode\n",
340
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query Who are Meta's 'Directors' (i.e., members of the Board of Directors)?\n",
341
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering 3ead0e8d-0e03-4a0c-9908-ea1e3f9375be: TextNode\n",
342
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query Who are Meta's 'Directors' (i.e., members of the Board of Directors)?\n",
343
+ "\u001b[0mINFO:httpx:HTTP Request: POST https://api.cohere.ai/v1/rerank \"HTTP/1.1 200 OK\"\n",
344
+ "HTTP Request: POST https://api.cohere.ai/v1/rerank \"HTTP/1.1 200 OK\"\n",
345
+ "HTTP Request: POST https://api.cohere.ai/v1/rerank \"HTTP/1.1 200 OK\"\n",
346
+ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
347
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
348
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n"
349
+ ]
350
+ }
351
+ ],
352
+ "source": [
353
+ "raw_response1 = recursive_query_engine.query(DEFAULT_QUESTION1)\n",
354
+ "raw_response2 = recursive_query_engine.query(DEFAULT_QUESTION2)"
355
+ ]
356
+ },
357
+ {
358
+ "cell_type": "code",
359
+ "execution_count": 37,
360
+ "metadata": {},
361
+ "outputs": [
362
+ {
363
+ "name": "stdout",
364
+ "output_type": "stream",
365
+ "text": [
366
+ "**********RAW**********\n",
367
+ "raw_response1: The total value of 'Cash and cash equivalents' as of December 31, 2023, was $41,862 million.\n",
368
+ "raw_response2: The provided text does not specify the names or identities of the members of Meta Platforms, Inc.'s Board of Directors. Therefore, I cannot provide the names of the directors based on the information available.\n"
369
+ ]
370
+ }
371
+ ],
372
+ "source": [
373
+ "print(\"**********RAW**********\")\n",
374
+ "print(f\"raw_response1: {raw_response1}\")\n",
375
+ "print(f\"raw_response2: {raw_response2}\")\n"
376
+ ]
377
+ },
378
+ {
379
+ "cell_type": "markdown",
380
+ "metadata": {},
381
+ "source": [
382
+ "## 5. Recursive Query Engine"
383
+ ]
384
+ },
385
+ {
386
+ "cell_type": "code",
387
+ "execution_count": 49,
388
+ "metadata": {},
389
+ "outputs": [],
390
+ "source": [
391
+ "recursive_query_engine = recursive_index.as_query_engine(\n",
392
+ " llm=gpt4_model,\n",
393
+ " similarity_top_k=15,\n",
394
+ " node_postprocessors=[reranker],\n",
395
+ " verbose = True\n",
396
+ ")"
397
+ ]
398
+ },
399
+ {
400
+ "cell_type": "code",
401
+ "execution_count": 50,
402
+ "metadata": {},
403
+ "outputs": [
404
+ {
405
+ "name": "stdout",
406
+ "output_type": "stream",
407
+ "text": [
408
+ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
409
+ "HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
410
+ "HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
411
+ "\u001b[1;3;38;2;11;159;203mRetrieval entering 7873de31-b332-4365-bd65-0a4b84f47da6: TextNode\n",
412
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query What was the total value of 'Cash and cash equivalents' as of December 31, 2023?\n",
413
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering 4e8c6d95-87fd-423a-84ca-06c2d21c427e: TextNode\n",
414
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query What was the total value of 'Cash and cash equivalents' as of December 31, 2023?\n",
415
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering c7ec1eec-24ee-4c3e-81ba-ca81d1a91389: TextNode\n",
416
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query What was the total value of 'Cash and cash equivalents' as of December 31, 2023?\n",
417
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering 99462df3-001a-458a-97ef-89bd51518f88: TextNode\n",
418
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query What was the total value of 'Cash and cash equivalents' as of December 31, 2023?\n",
419
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering 580282f7-7c4e-4ba5-a559-636959b71ec8: TextNode\n",
420
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query What was the total value of 'Cash and cash equivalents' as of December 31, 2023?\n",
421
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering f333c293-2f5b-4a99-a1e8-4bc9a22a1508: TextNode\n",
422
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query What was the total value of 'Cash and cash equivalents' as of December 31, 2023?\n",
423
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering 4044f21f-899a-4fcc-8caa-3b6f8fc4e92c: TextNode\n",
424
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query What was the total value of 'Cash and cash equivalents' as of December 31, 2023?\n",
425
+ "\u001b[0mINFO:httpx:HTTP Request: POST https://api.cohere.ai/v1/rerank \"HTTP/1.1 200 OK\"\n",
426
+ "HTTP Request: POST https://api.cohere.ai/v1/rerank \"HTTP/1.1 200 OK\"\n",
427
+ "HTTP Request: POST https://api.cohere.ai/v1/rerank \"HTTP/1.1 200 OK\"\n",
428
+ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
429
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
430
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
431
+ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
432
+ "HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
433
+ "HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
434
+ "\u001b[1;3;38;2;11;159;203mRetrieval entering 3bdc6a30-8c4e-41d0-935f-78cb3888a00c: TextNode\n",
435
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query Who are Meta's 'Directors' (i.e., members of the Board of Directors)?\n",
436
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering 94beb3bf-edb3-42d1-a7fe-9b7691f219ca: TextNode\n",
437
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query Who are Meta's 'Directors' (i.e., members of the Board of Directors)?\n",
438
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering caf09ded-aadb-479d-a589-28f16b4e9a93: TextNode\n",
439
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query Who are Meta's 'Directors' (i.e., members of the Board of Directors)?\n",
440
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering 20b634e2-27ce-4343-ae60-3694cc2c276d: TextNode\n",
441
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query Who are Meta's 'Directors' (i.e., members of the Board of Directors)?\n",
442
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering 3ead0e8d-0e03-4a0c-9908-ea1e3f9375be: TextNode\n",
443
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query Who are Meta's 'Directors' (i.e., members of the Board of Directors)?\n",
444
+ "\u001b[0mINFO:httpx:HTTP Request: POST https://api.cohere.ai/v1/rerank \"HTTP/1.1 200 OK\"\n",
445
+ "HTTP Request: POST https://api.cohere.ai/v1/rerank \"HTTP/1.1 200 OK\"\n",
446
+ "HTTP Request: POST https://api.cohere.ai/v1/rerank \"HTTP/1.1 200 OK\"\n",
447
+ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
448
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
449
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n"
450
+ ]
451
+ }
452
+ ],
453
+ "source": [
454
+ "recursive_response1 = recursive_query_engine.query(DEFAULT_QUESTION1)\n",
455
+ "recursive_response2 = recursive_query_engine.query(DEFAULT_QUESTION2)"
456
+ ]
457
+ },
458
+ {
459
+ "cell_type": "code",
460
+ "execution_count": 51,
461
+ "metadata": {},
462
+ "outputs": [
463
+ {
464
+ "name": "stdout",
465
+ "output_type": "stream",
466
+ "text": [
467
+ "**********RECURSIVE**********\n",
468
+ "recursive_response1: The total value of 'Cash and cash equivalents' as of December 31, 2023, was $41,862 million.\n",
469
+ "recursive_response2: The provided text does not specify the names or identities of the members of Meta Platforms, Inc.'s Board of Directors.\n"
470
+ ]
471
+ }
472
+ ],
473
+ "source": [
474
+ "print(\"**********RECURSIVE**********\")\n",
475
+ "print(f\"recursive_response1: {recursive_response1}\")\n",
476
+ "print(f\"recursive_response2: {recursive_response2}\")"
477
+ ]
478
+ },
479
+ {
480
+ "cell_type": "markdown",
481
+ "metadata": {},
482
+ "source": [
483
+ "## 6. Subquestion Query Engine"
484
+ ]
485
+ },
486
+ {
487
+ "cell_type": "code",
488
+ "execution_count": 32,
489
+ "metadata": {},
490
+ "outputs": [],
491
+ "source": [
492
+ "from llama_index.core.indices.query.query_transform.base import (\n",
493
+ " StepDecomposeQueryTransform,\n",
494
+ ")\n",
495
+ "\n",
496
+ "# gpt-4\n",
497
+ "step_decompose_transform = StepDecomposeQueryTransform(llm=gpt4_model, verbose=True)"
498
+ ]
499
+ },
500
+ {
501
+ "cell_type": "code",
502
+ "execution_count": 64,
503
+ "metadata": {},
504
+ "outputs": [],
505
+ "source": [
506
+ "from llama_index.core.query_engine import MultiStepQueryEngine\n",
507
+ "index_summary = \"Used to answer questions about Meta's 10-K and financial performance during 2023\"\n",
508
+ "\n",
509
+ "subquestion_query_engine = MultiStepQueryEngine(\n",
510
+ " query_engine=recursive_query_engine,\n",
511
+ " query_transform=step_decompose_transform,\n",
512
+ " index_summary=index_summary,\n",
513
+ ")"
514
+ ]
515
+ },
516
+ {
517
+ "cell_type": "code",
518
+ "execution_count": 65,
519
+ "metadata": {},
520
+ "outputs": [
521
+ {
522
+ "name": "stdout",
523
+ "output_type": "stream",
524
+ "text": [
525
+ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
526
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
527
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
528
+ "\u001b[1;3;33m> Current query: What was the total value of 'Cash and cash equivalents' as of December 31, 2023?\n",
529
+ "\u001b[0m\u001b[1;3;38;5;200m> New query: What was the total value of 'Cash and cash equivalents' reported in Meta's 10-K for the year ending December 31, 2023?\n",
530
+ "\u001b[0mINFO:httpx:HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
531
+ "HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
532
+ "HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
533
+ "\u001b[1;3;38;2;11;159;203mRetrieval entering 7873de31-b332-4365-bd65-0a4b84f47da6: TextNode\n",
534
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query What was the total value of 'Cash and cash equivalents' reported in Meta's 10-K for the year ending December 31, 2023?\n",
535
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering 4e8c6d95-87fd-423a-84ca-06c2d21c427e: TextNode\n",
536
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query What was the total value of 'Cash and cash equivalents' reported in Meta's 10-K for the year ending December 31, 2023?\n",
537
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering 580282f7-7c4e-4ba5-a559-636959b71ec8: TextNode\n",
538
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query What was the total value of 'Cash and cash equivalents' reported in Meta's 10-K for the year ending December 31, 2023?\n",
539
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering 37f1e0f8-73cb-4de9-975d-460bd6a51249: TextNode\n",
540
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query What was the total value of 'Cash and cash equivalents' reported in Meta's 10-K for the year ending December 31, 2023?\n",
541
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering e61666fc-2ca4-4544-af68-66fe2b85b442: TextNode\n",
542
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query What was the total value of 'Cash and cash equivalents' reported in Meta's 10-K for the year ending December 31, 2023?\n",
543
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering 99462df3-001a-458a-97ef-89bd51518f88: TextNode\n",
544
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query What was the total value of 'Cash and cash equivalents' reported in Meta's 10-K for the year ending December 31, 2023?\n",
545
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering eef206a0-f79f-4e6e-a3fe-fd72010be2b7: TextNode\n",
546
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query What was the total value of 'Cash and cash equivalents' reported in Meta's 10-K for the year ending December 31, 2023?\n",
547
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering f333c293-2f5b-4a99-a1e8-4bc9a22a1508: TextNode\n",
548
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query What was the total value of 'Cash and cash equivalents' reported in Meta's 10-K for the year ending December 31, 2023?\n",
549
+ "\u001b[0mINFO:httpx:HTTP Request: POST https://api.cohere.ai/v1/rerank \"HTTP/1.1 200 OK\"\n",
550
+ "HTTP Request: POST https://api.cohere.ai/v1/rerank \"HTTP/1.1 200 OK\"\n",
551
+ "HTTP Request: POST https://api.cohere.ai/v1/rerank \"HTTP/1.1 200 OK\"\n",
552
+ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
553
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
554
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
555
+ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
556
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
557
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
558
+ "\u001b[1;3;33m> Current query: What was the total value of 'Cash and cash equivalents' as of December 31, 2023?\n",
559
+ "\u001b[0m\u001b[1;3;38;5;200m> New query: None\n",
560
+ "\u001b[0mINFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
561
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
562
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
563
+ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
564
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
565
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
566
+ "\u001b[1;3;33m> Current query: Who are Meta's 'Directors' (i.e., members of the Board of Directors)?\n",
567
+ "\u001b[0m\u001b[1;3;38;5;200m> New query: Who are the members of Meta's Board of Directors as listed in their 2023 10-K report?\n",
568
+ "\u001b[0mINFO:httpx:HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
569
+ "HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
570
+ "HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
571
+ "\u001b[1;3;38;2;11;159;203mRetrieval entering 94beb3bf-edb3-42d1-a7fe-9b7691f219ca: TextNode\n",
572
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query Who are the members of Meta's Board of Directors as listed in their 2023 10-K report?\n",
573
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering 20b634e2-27ce-4343-ae60-3694cc2c276d: TextNode\n",
574
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query Who are the members of Meta's Board of Directors as listed in their 2023 10-K report?\n",
575
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering 3bdc6a30-8c4e-41d0-935f-78cb3888a00c: TextNode\n",
576
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query Who are the members of Meta's Board of Directors as listed in their 2023 10-K report?\n",
577
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering 0bd582c3-c59b-48a3-a988-8042937c7d7d: TextNode\n",
578
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query Who are the members of Meta's Board of Directors as listed in their 2023 10-K report?\n",
579
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering caf09ded-aadb-479d-a589-28f16b4e9a93: TextNode\n",
580
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query Who are the members of Meta's Board of Directors as listed in their 2023 10-K report?\n",
581
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering e61666fc-2ca4-4544-af68-66fe2b85b442: TextNode\n",
582
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query Who are the members of Meta's Board of Directors as listed in their 2023 10-K report?\n",
583
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering bef70b75-d90b-48f7-9c87-ce32b2b091d0: TextNode\n",
584
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query Who are the members of Meta's Board of Directors as listed in their 2023 10-K report?\n",
585
+ "\u001b[0mINFO:httpx:HTTP Request: POST https://api.cohere.ai/v1/rerank \"HTTP/1.1 200 OK\"\n",
586
+ "HTTP Request: POST https://api.cohere.ai/v1/rerank \"HTTP/1.1 200 OK\"\n",
587
+ "HTTP Request: POST https://api.cohere.ai/v1/rerank \"HTTP/1.1 200 OK\"\n",
588
+ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
589
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
590
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
591
+ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
592
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
593
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
594
+ "\u001b[1;3;33m> Current query: Who are Meta's 'Directors' (i.e., members of the Board of Directors)?\n",
595
+ "\u001b[0m\u001b[1;3;38;5;200m> New query: None\n",
596
+ "\u001b[0mINFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
597
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
598
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n"
599
+ ]
600
+ }
601
+ ],
602
+ "source": [
603
+ "sq_response1 = subquestion_query_engine.query(DEFAULT_QUESTION1)\n",
604
+ "sq_response2 = subquestion_query_engine.query(DEFAULT_QUESTION2)"
605
+ ]
606
+ },
607
+ {
608
+ "cell_type": "code",
609
+ "execution_count": 66,
610
+ "metadata": {},
611
+ "outputs": [
612
+ {
613
+ "name": "stdout",
614
+ "output_type": "stream",
615
+ "text": [
616
+ "**********RECURSIVE**********\n",
617
+ "sq_response1: The total value of 'Cash and cash equivalents' as of December 31, 2023, was $41,862 million.\n",
618
+ "sq_response2: I'm sorry, I cannot provide the information you requested.\n"
619
+ ]
620
+ }
621
+ ],
622
+ "source": [
623
+ "print(\"**********RECURSIVE**********\")\n",
624
+ "print(f\"sq_response1: {sq_response1}\")\n",
625
+ "print(f\"sq_response2: {sq_response2}\")"
626
+ ]
627
+ },
628
+ {
629
+ "cell_type": "markdown",
630
+ "metadata": {},
631
+ "source": [
632
+ "## 7. Multi-Step Query Engine"
633
+ ]
634
+ },
635
+ {
636
+ "cell_type": "code",
637
+ "execution_count": 42,
638
+ "metadata": {},
639
+ "outputs": [],
640
+ "source": [
641
+ "\n",
642
+ "from llama_index.core.indices.query.query_transform.base import (\n",
643
+ " StepDecomposeQueryTransform,\n",
644
+ ")\n",
645
+ "\n",
646
+ "# gpt-4\n",
647
+ "step_decompose_transform = StepDecomposeQueryTransform(llm=gpt4_model, verbose=True)\n"
648
+ ]
649
+ },
650
+ {
651
+ "cell_type": "code",
652
+ "execution_count": 69,
653
+ "metadata": {},
654
+ "outputs": [],
655
+ "source": [
656
+ "mstep_query_engine = MultiStepQueryEngine(\n",
657
+ " query_engine=recursive_query_engine,\n",
658
+ " query_transform=step_decompose_transform,\n",
659
+ " index_summary=index_summary,\n",
660
+ ")"
661
+ ]
662
+ },
663
+ {
664
+ "cell_type": "code",
665
+ "execution_count": 70,
666
+ "metadata": {},
667
+ "outputs": [
668
+ {
669
+ "name": "stdout",
670
+ "output_type": "stream",
671
+ "text": [
672
+ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
673
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
674
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
675
+ "\u001b[1;3;33m> Current query: What was the total value of 'Cash and cash equivalents' as of December 31, 2023?\n",
676
+ "\u001b[0m\u001b[1;3;38;5;200m> New query: What was the total value of 'Cash and cash equivalents' for Meta as of December 31, 2023?\n",
677
+ "\u001b[0mINFO:httpx:HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
678
+ "HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
679
+ "HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
680
+ "\u001b[1;3;38;2;11;159;203mRetrieval entering 7873de31-b332-4365-bd65-0a4b84f47da6: TextNode\n",
681
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query What was the total value of 'Cash and cash equivalents' for Meta as of December 31, 2023?\n",
682
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering 4e8c6d95-87fd-423a-84ca-06c2d21c427e: TextNode\n",
683
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query What was the total value of 'Cash and cash equivalents' for Meta as of December 31, 2023?\n",
684
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering 580282f7-7c4e-4ba5-a559-636959b71ec8: TextNode\n",
685
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query What was the total value of 'Cash and cash equivalents' for Meta as of December 31, 2023?\n",
686
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering 37f1e0f8-73cb-4de9-975d-460bd6a51249: TextNode\n",
687
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query What was the total value of 'Cash and cash equivalents' for Meta as of December 31, 2023?\n",
688
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering e61666fc-2ca4-4544-af68-66fe2b85b442: TextNode\n",
689
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query What was the total value of 'Cash and cash equivalents' for Meta as of December 31, 2023?\n",
690
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering 99462df3-001a-458a-97ef-89bd51518f88: TextNode\n",
691
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query What was the total value of 'Cash and cash equivalents' for Meta as of December 31, 2023?\n",
692
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering f333c293-2f5b-4a99-a1e8-4bc9a22a1508: TextNode\n",
693
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query What was the total value of 'Cash and cash equivalents' for Meta as of December 31, 2023?\n",
694
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering eef206a0-f79f-4e6e-a3fe-fd72010be2b7: TextNode\n",
695
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query What was the total value of 'Cash and cash equivalents' for Meta as of December 31, 2023?\n",
696
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering c7ec1eec-24ee-4c3e-81ba-ca81d1a91389: TextNode\n",
697
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query What was the total value of 'Cash and cash equivalents' for Meta as of December 31, 2023?\n",
698
+ "\u001b[0mINFO:httpx:HTTP Request: POST https://api.cohere.ai/v1/rerank \"HTTP/1.1 200 OK\"\n",
699
+ "HTTP Request: POST https://api.cohere.ai/v1/rerank \"HTTP/1.1 200 OK\"\n",
700
+ "HTTP Request: POST https://api.cohere.ai/v1/rerank \"HTTP/1.1 200 OK\"\n",
701
+ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
702
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
703
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
704
+ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
705
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
706
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
707
+ "\u001b[1;3;33m> Current query: What was the total value of 'Cash and cash equivalents' as of December 31, 2023?\n",
708
+ "\u001b[0m\u001b[1;3;38;5;200m> New query: None\n",
709
+ "\u001b[0mINFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
710
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
711
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
712
+ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
713
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
714
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
715
+ "\u001b[1;3;33m> Current query: Who are Meta's 'Directors' (i.e., members of the Board of Directors)?\n",
716
+ "\u001b[0m\u001b[1;3;38;5;200m> New query: Who are the members of Meta's Board of Directors as listed in their 2023 10-K report?\n",
717
+ "\u001b[0mINFO:httpx:HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
718
+ "HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
719
+ "HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
720
+ "\u001b[1;3;38;2;11;159;203mRetrieval entering 94beb3bf-edb3-42d1-a7fe-9b7691f219ca: TextNode\n",
721
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query Who are the members of Meta's Board of Directors as listed in their 2023 10-K report?\n",
722
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering 20b634e2-27ce-4343-ae60-3694cc2c276d: TextNode\n",
723
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query Who are the members of Meta's Board of Directors as listed in their 2023 10-K report?\n",
724
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering 3bdc6a30-8c4e-41d0-935f-78cb3888a00c: TextNode\n",
725
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query Who are the members of Meta's Board of Directors as listed in their 2023 10-K report?\n",
726
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering 0bd582c3-c59b-48a3-a988-8042937c7d7d: TextNode\n",
727
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query Who are the members of Meta's Board of Directors as listed in their 2023 10-K report?\n",
728
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering caf09ded-aadb-479d-a589-28f16b4e9a93: TextNode\n",
729
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query Who are the members of Meta's Board of Directors as listed in their 2023 10-K report?\n",
730
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering e61666fc-2ca4-4544-af68-66fe2b85b442: TextNode\n",
731
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query Who are the members of Meta's Board of Directors as listed in their 2023 10-K report?\n",
732
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering bef70b75-d90b-48f7-9c87-ce32b2b091d0: TextNode\n",
733
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query Who are the members of Meta's Board of Directors as listed in their 2023 10-K report?\n",
734
+ "\u001b[0mINFO:httpx:HTTP Request: POST https://api.cohere.ai/v1/rerank \"HTTP/1.1 200 OK\"\n",
735
+ "HTTP Request: POST https://api.cohere.ai/v1/rerank \"HTTP/1.1 200 OK\"\n",
736
+ "HTTP Request: POST https://api.cohere.ai/v1/rerank \"HTTP/1.1 200 OK\"\n",
737
+ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
738
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
739
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
740
+ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
741
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
742
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
743
+ "\u001b[1;3;33m> Current query: Who are Meta's 'Directors' (i.e., members of the Board of Directors)?\n",
744
+ "\u001b[0m\u001b[1;3;38;5;200m> New query: None\n",
745
+ "\u001b[0mINFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
746
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
747
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n"
748
+ ]
749
+ }
750
+ ],
751
+ "source": [
752
+ "mstep_response1 = mstep_query_engine.query(DEFAULT_QUESTION1)\n",
753
+ "mstep_response2 = mstep_query_engine.query(DEFAULT_QUESTION2)"
754
+ ]
755
+ },
756
+ {
757
+ "cell_type": "code",
758
+ "execution_count": 71,
759
+ "metadata": {},
760
+ "outputs": [
761
+ {
762
+ "name": "stdout",
763
+ "output_type": "stream",
764
+ "text": [
765
+ "**********RECURSIVE**********\n",
766
+ "mstep_response1: The total value of 'Cash and cash equivalents' as of December 31, 2023, was $41,862 million.\n",
767
+ "mstep_response2: I'm sorry, I cannot provide the information you requested.\n"
768
+ ]
769
+ }
770
+ ],
771
+ "source": [
772
+ "print(\"**********RECURSIVE**********\")\n",
773
+ "print(f\"mstep_response1: {mstep_response1}\")\n",
774
+ "print(f\"mstep_response2: {mstep_response2}\")"
775
+ ]
776
+ },
777
+ {
778
+ "cell_type": "code",
779
+ "execution_count": 73,
780
+ "metadata": {},
781
+ "outputs": [
782
+ {
783
+ "name": "stdout",
784
+ "output_type": "stream",
785
+ "text": [
786
+ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
787
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
788
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
789
+ "\u001b[1;3;33m> Current query: How is the metaverse investment doing?\n",
790
+ "\u001b[0m\u001b[1;3;38;5;200m> New query: What is the financial performance of Meta in 2023?\n",
791
+ "\u001b[0mINFO:httpx:HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
792
+ "HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
793
+ "HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
794
+ "\u001b[1;3;38;2;11;159;203mRetrieval entering e61666fc-2ca4-4544-af68-66fe2b85b442: TextNode\n",
795
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query What is the financial performance of Meta in 2023?\n",
796
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering 580282f7-7c4e-4ba5-a559-636959b71ec8: TextNode\n",
797
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query What is the financial performance of Meta in 2023?\n",
798
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering b1ecd789-6349-4192-a7fd-bdad5c340daf: TextNode\n",
799
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query What is the financial performance of Meta in 2023?\n",
800
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering eef206a0-f79f-4e6e-a3fe-fd72010be2b7: TextNode\n",
801
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query What is the financial performance of Meta in 2023?\n",
802
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering 37f1e0f8-73cb-4de9-975d-460bd6a51249: TextNode\n",
803
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query What is the financial performance of Meta in 2023?\n",
804
+ "\u001b[0m\u001b[1;3;38;2;11;159;203mRetrieval entering 021c3a54-74cd-4cb3-8608-48d611bd4646: TextNode\n",
805
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query What is the financial performance of Meta in 2023?\n",
806
+ "\u001b[0mINFO:httpx:HTTP Request: POST https://api.cohere.ai/v1/rerank \"HTTP/1.1 200 OK\"\n",
807
+ "HTTP Request: POST https://api.cohere.ai/v1/rerank \"HTTP/1.1 200 OK\"\n",
808
+ "HTTP Request: POST https://api.cohere.ai/v1/rerank \"HTTP/1.1 200 OK\"\n",
809
+ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
810
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
811
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
812
+ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
813
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
814
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
815
+ "\u001b[1;3;33m> Current query: How is the metaverse investment doing?\n",
816
+ "\u001b[0m\u001b[1;3;38;5;200m> New query: How has the investment in Reality Labs affected Meta's overall financial performance in 2023?\n",
817
+ "\u001b[0mINFO:httpx:HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
818
+ "HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
819
+ "HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
820
+ "INFO:httpx:HTTP Request: POST https://api.cohere.ai/v1/rerank \"HTTP/1.1 200 OK\"\n",
821
+ "HTTP Request: POST https://api.cohere.ai/v1/rerank \"HTTP/1.1 200 OK\"\n",
822
+ "HTTP Request: POST https://api.cohere.ai/v1/rerank \"HTTP/1.1 200 OK\"\n",
823
+ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
824
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
825
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
826
+ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
827
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
828
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
829
+ "\u001b[1;3;33m> Current query: How is the metaverse investment doing?\n",
830
+ "\u001b[0m\u001b[1;3;38;5;200m> New query: How has the performance of Reality Labs influenced the overall valuation of Meta's investments in the metaverse?\n",
831
+ "\u001b[0mINFO:httpx:HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
832
+ "HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
833
+ "HTTP Request: POST https://api.openai.com/v1/embeddings \"HTTP/1.1 200 OK\"\n",
834
+ "\u001b[1;3;38;2;11;159;203mRetrieval entering eef206a0-f79f-4e6e-a3fe-fd72010be2b7: TextNode\n",
835
+ "\u001b[0m\u001b[1;3;38;2;237;90;200mRetrieving from object TextNode with query How has the performance of Reality Labs influenced the overall valuation of Meta's investments in the metaverse?\n",
836
+ "\u001b[0mINFO:httpx:HTTP Request: POST https://api.cohere.ai/v1/rerank \"HTTP/1.1 200 OK\"\n",
837
+ "HTTP Request: POST https://api.cohere.ai/v1/rerank \"HTTP/1.1 200 OK\"\n",
838
+ "HTTP Request: POST https://api.cohere.ai/v1/rerank \"HTTP/1.1 200 OK\"\n",
839
+ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
840
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
841
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
842
+ "INFO:httpx:HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
843
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
844
+ "HTTP Request: POST https://api.openai.com/v1/chat/completions \"HTTP/1.1 200 OK\"\n",
845
+ "The metaverse investment is facing financial challenges due to the substantial operating losses incurred by Reality Labs. These losses have significantly impacted Meta's overall operating profit in 2023 and are expected to increase further in 2024. Despite these financial setbacks, Meta continues to invest in Reality Labs as part of a long-term strategy to develop the metaverse, which is considered the next chapter of the internet with potential future monetization opportunities. However, the current financial performance of Reality Labs is reducing Meta's operating margin and profitability, which could affect the company's overall financial health if these investments do not yield successful outcomes in the longer term.\n"
846
+ ]
847
+ }
848
+ ],
849
+ "source": [
850
+ "print(subquestion_query_engine.query(\"How is the metaverse investment doing?\"))"
851
+ ]
852
+ }
853
+ ],
854
+ "metadata": {
855
+ "kernelspec": {
856
+ "display_name": "llmops",
857
+ "language": "python",
858
+ "name": "python3"
859
+ },
860
+ "language_info": {
861
+ "codemirror_mode": {
862
+ "name": "ipython",
863
+ "version": 3
864
+ },
865
+ "file_extension": ".py",
866
+ "mimetype": "text/x-python",
867
+ "name": "python",
868
+ "nbconvert_exporter": "python",
869
+ "pygments_lexer": "ipython3",
870
+ "version": "3.11.8"
871
+ }
872
+ },
873
+ "nbformat": 4,
874
+ "nbformat_minor": 2
875
+ }
requirements.txt ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ beautifulsoup4==4.12.3
2
+ bs4==0.0.2
3
+ chainlit==1.0.505
4
+ cohere==5.3.3
5
+ huggingface-hub==0.21.4
6
+ langchain==0.1.16
7
+ langchain-community==0.0.36
8
+ langchain-core==0.1.48
9
+ langchain-experimental==0.0.57
10
+ langchain-openai==0.1.3
11
+ langchain-text-splitters==0.0.1
12
+ langchain-voyageai==0.1.0
13
+ langchainhub==0.1.15
14
+ llama-index==0.10.32
15
+ llama-index-agent-openai==0.1.6
16
+ llama-index-callbacks-wandb==0.1.2
17
+ llama-index-cli==0.1.12
18
+ llama-index-core==0.10.32
19
+ llama-index-embeddings-adapter==0.1.3
20
+ llama-index-embeddings-azure-openai==0.1.6
21
+ llama-index-embeddings-huggingface==0.2.0
22
+ llama-index-embeddings-openai==0.1.9
23
+ llama-index-embeddings-voyageai==0.1.4
24
+ llama-index-indices-managed-llama-cloud==0.1.4
25
+ llama-index-legacy==0.9.48
26
+ llama-index-llms-gradient==0.1.2
27
+ llama-index-llms-openai==0.1.16
28
+ llama-index-postprocessor-cohere-rerank==0.1.4
29
+ llama-index-program-openai==0.1.4
30
+ llama-index-readers-file==0.1.19
31
+ llama-index-vector-stores-qdrant==0.2.8
32
+ llama-parse==0.4.2
33
+ llamaindex-py-client==0.1.18
34
+ openai==1.23.3
35
+ pandas==2.2.2
36
+ pillow==10.2.0
37
+ PyMuPDF==1.24.2
38
+ PyMuPDFb==1.24.1
39
+ qdrant-client==1.9.0
40
+ scipy==1.13.0
41
+ sentence-transformers==2.7.0
42
+ unstructured==0.13.6
43
+ unstructured-client==0.22.0
44
+ voyageai==0.2.2
45
+ wandb==0.16.6
semantic.py ADDED
@@ -0,0 +1,140 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import logging
2
+ import shutil
3
+ from pathlib import Path
4
+
5
+ logging.basicConfig(level=logging.INFO)
6
+ _logger = logging.getLogger("chunking")
7
+
8
+ from operator import itemgetter
9
+ from langchain_core.prompts import ChatPromptTemplate
10
+ from langchain_core.runnables.base import RunnableSequence
11
+ from langchain_core.vectorstores import VectorStore
12
+ from langchain.retrievers.multi_query import MultiQueryRetriever
13
+ from langchain_community.vectorstores import Qdrant
14
+ from langchain.schema.output_parser import StrOutputParser
15
+ from langchain.schema.runnable import RunnablePassthrough
16
+ from langchain.text_splitter import RecursiveCharacterTextSplitter
17
+ from langchain_community.document_loaders import PyMuPDFLoader
18
+ from langchain_experimental.text_splitter import SemanticChunker
19
+
20
+ from globals import (
21
+ embeddings,
22
+ gpt35_model,
23
+ gpt4_model,
24
+ META_10K_FILE_PATH,
25
+ META_SEMANTIC_COLLECTION,
26
+ VECTOR_STORE_PATH
27
+ )
28
+
29
+ from qdrant_client import QdrantClient
30
+ qdrant_client = QdrantClient(path=VECTOR_STORE_PATH)
31
+
32
+
33
+ RAG_PROMPT = """
34
+ Reply the user's query thoughtfully and clearly.
35
+ You should only respond to user's query if the context is related to the query.
36
+ If you are not sure how to answer, please reply "I don't know".
37
+ Respond with structure in markdown.
38
+
39
+ CONTEXT:
40
+ {context}
41
+
42
+ QUERY:
43
+ {question}
44
+
45
+ YOUR REPLY: """
46
+
47
+ rag_prompt = ChatPromptTemplate.from_template(RAG_PROMPT)
48
+
49
+
50
+ class SemanticStoreFactory:
51
+ _semantic_vectorstore: VectorStore = None
52
+
53
+ @classmethod
54
+ def __load_semantic_store(
55
+ cls
56
+ ) -> VectorStore:
57
+ path = Path(VECTOR_STORE_PATH)
58
+ store = None
59
+ # check if path exists and if it is not empty
60
+ if path.exists() and path.is_dir() and any(path.iterdir()):
61
+ store = Qdrant(
62
+ client=qdrant_client,
63
+ embeddings=embeddings,
64
+ collection_name=META_SEMANTIC_COLLECTION,
65
+ )
66
+ else:
67
+ store = cls.__create_semantic_store()
68
+ return store
69
+
70
+ @classmethod
71
+ def __create_semantic_store(
72
+ cls
73
+ ) -> VectorStore:
74
+
75
+ _logger.info(f"creating semantic vector store: {VECTOR_STORE_PATH}")
76
+ path = Path(VECTOR_STORE_PATH)
77
+ if not path.exists():
78
+ path.mkdir(parents=True, exist_ok=True)
79
+ _logger.info(f"Directory '{path}' created.")
80
+
81
+ documents = PyMuPDFLoader(META_10K_FILE_PATH).load()
82
+ semantic_chunker = SemanticChunker(
83
+ embeddings=embeddings,
84
+ breakpoint_threshold_type="percentile"
85
+ )
86
+ semantic_chunks = semantic_chunker.create_documents([d.page_content for d in documents])
87
+ semantic_chunk_vectorstore = Qdrant.from_documents(
88
+ semantic_chunks,
89
+ embeddings,
90
+ qdrant_client=qdrant_client,
91
+ collection_name=META_SEMANTIC_COLLECTION,
92
+ force_recreate=True
93
+ )
94
+ return semantic_chunk_vectorstore
95
+
96
+ @classmethod
97
+ def get_semantic_store(
98
+ cls
99
+ ) -> VectorStore:
100
+ if cls._semantic_vectorstore is None:
101
+ print(f"Loading semantic vectorstore {META_SEMANTIC_COLLECTION} from: {VECTOR_STORE_PATH}")
102
+ try:
103
+ # first try to load the store
104
+ cls._semantic_vectorstore = cls.__load_semantic_store()
105
+ except Exception as e:
106
+ _logger.warning(f"cannot load: {e}")
107
+ cls._semantic_vectorstore = cls.__create_semantic_store()
108
+
109
+ return cls._semantic_vectorstore
110
+
111
+ class SemanticRAGChainFactory:
112
+ _chain: RunnableSequence = None
113
+
114
+ @classmethod
115
+ def get_semantic_rag_chain(
116
+ cls
117
+ ) -> RunnableSequence:
118
+ if cls._chain is None:
119
+ semantic_store = SemanticStoreFactory.get_semantic_store()
120
+ if semantic_store is not None:
121
+ semantic_chunk_retriever = semantic_store.as_retriever()
122
+ semantic_mquery_retriever = MultiQueryRetriever.from_llm(
123
+ retriever=semantic_chunk_retriever,
124
+ llm=gpt4_model
125
+ )
126
+ cls._chain = (
127
+ # INVOKE CHAIN WITH: {"question" : "<<SOME USER QUESTION>>"}
128
+ # "question" : populated by getting the value of the "question" key
129
+ # "context" : populated by getting the value of the "question" key and chaining it into the base_retriever
130
+ {"context": itemgetter("question") | semantic_mquery_retriever, "question": itemgetter("question")}
131
+ # "context" : is assigned to a RunnablePassthrough object (will not be called or considered in the next step)
132
+ # by getting the value of the "context" key from the previous step
133
+ | RunnablePassthrough.assign(context=itemgetter("context"))
134
+ # "response" : the "context" and "question" values are used to format our prompt object and then piped
135
+ # into the LLM and stored in a key called "response"
136
+ # "context" : populated by getting the value of the "context" key from the previous step
137
+ | {"response": rag_prompt | gpt4_model, "context": itemgetter("context")}
138
+ )
139
+
140
+ return cls._chain