Skip to content

Commit 99af0f0

Browse files
authored
Merge pull request #62 from gsa9989/users/garagundi/cosmosdbnosql
Adding LlamaIndex RAG Chatbot Sample for Azure CosmosDB NoSql
2 parents 3c856ca + 18e96fe commit 99af0f0

File tree

1 file changed

+311
-0
lines changed

1 file changed

+311
-0
lines changed
Lines changed: 311 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,311 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "markdown",
5+
"id": "936cff50-b7ff-434a-b6ae-558f6288a5fb",
6+
"metadata": {},
7+
"source": [
8+
"# Building a RAG Chatbot Using LlamaIndex\n",
9+
"\n",
10+
"LlamaIndex provides users with a simple way of creating a chatbot that works both with an LLM and data from a database. This combination is called Retrieval-Augmented Generation (RAG) and is used to give LLM's the ability to answer queries using data it was not trained on. This notebook will cover each step necessary to create a RAG chatbot using the Python SDK for Azure Cosmos DB for NoSQL. At the end, we create a UX using gradio to allow users to type in questions and see the response displayed in a chatbot style.\n",
11+
"\n",
12+
"Important Note: This sample requires you to have Azure Cosmos DB for NoSQL and Azure OpenAI accounts setup. To get started, visit:\n",
13+
"- [Azure Cosmos DB for NoSQL Python Quickstart](https://learn.microsoft.com/en-us/azure/cosmos-db/nosql/quickstart-python?pivots=devcontainer-codespace)\n",
14+
"- [Azure Cosmos DB for NoSQL Vector Search](https://learn.microsoft.com/en-us/azure/cosmos-db/nosql/vector-search)\n",
15+
"- [Azure OpenAI](https://learn.microsoft.com/en-us/azure/ai-services/openai/)"
16+
]
17+
},
18+
{
19+
"cell_type": "code",
20+
"execution_count": null,
21+
"id": "25524f64-e833-419f-9762-1b07e426e55b",
22+
"metadata": {},
23+
"outputs": [],
24+
"source": [
25+
"%pip install llama-index-embeddings-openai\n",
26+
"%pip install llama-index-llms-azure-openai"
27+
]
28+
},
29+
{
30+
"cell_type": "code",
31+
"execution_count": null,
32+
"id": "43ab1fab-06be-4b81-aa12-0f0aa84d5780",
33+
"metadata": {},
34+
"outputs": [],
35+
"source": [
36+
"!pip install llama-index"
37+
]
38+
},
39+
{
40+
"cell_type": "markdown",
41+
"id": "593a3558-fba4-406c-bf1d-c9c3d577a165",
42+
"metadata": {},
43+
"source": [
44+
"## Setup Azure OpenAI\n",
45+
"Prior to beginning we need to set up the llm and embedding model that will be used in the RAG chatbot."
46+
]
47+
},
48+
{
49+
"cell_type": "code",
50+
"execution_count": null,
51+
"id": "92116904-efcd-41f1-8abf-afd63863062d",
52+
"metadata": {},
53+
"outputs": [],
54+
"source": [
55+
"from llama_index.llms.azure_openai import AzureOpenAI\n",
56+
"from llama_index.embeddings.azure_openai import AzureOpenAIEmbedding\n",
57+
"import os\n",
58+
"from dotenv import load_dotenv"
59+
]
60+
},
61+
{
62+
"cell_type": "code",
63+
"execution_count": null,
64+
"id": "f45c2108-ac32-42f6-9e12-1f58c65cd453",
65+
"metadata": {},
66+
"outputs": [],
67+
"source": [
68+
"llm = AzureOpenAI(\n",
69+
" model = \"gpt-35-turbo\",\n",
70+
" deployment_name = \"gpt-35-turbo\",\n",
71+
" azure_endpoint = os.getenv('AZURE_OPENAI_API_ENDPOINT'),\n",
72+
" api_key = os.getenv('AZURE_OPENAI_API_KEY'),\n",
73+
" api_version = \"2023-05-15\"\n",
74+
")\n",
75+
"\n",
76+
"embed_model = AzureOpenAIEmbedding(\n",
77+
" model = \"text-embedding-3-large\",\n",
78+
" deployment_name = \"text-embedding-3-large\",\n",
79+
" azure_endpoint = os.getenv('AZURE_OPENAI_API_ENDPOINT'),\n",
80+
" api_key = os.getenv('AZURE_OPENAI_API_KEY'),\n",
81+
" api_version = \"2023-05-15\"\n",
82+
")"
83+
]
84+
},
85+
{
86+
"cell_type": "markdown",
87+
"id": "a9c75260-482f-4405-a831-b912d0c782ce",
88+
"metadata": {},
89+
"source": [
90+
"## Loading the data\n",
91+
"The first step is to load the data using the LlamaIndex function SimpleDirectoryReader."
92+
]
93+
},
94+
{
95+
"cell_type": "code",
96+
"execution_count": null,
97+
"id": "1453d69b-d409-4eae-8048-e102ca46ca0e",
98+
"metadata": {},
99+
"outputs": [],
100+
"source": [
101+
"import time\n",
102+
"import nest_asyncio\n",
103+
"from llama_index.core import SimpleDirectoryReader\n",
104+
"from llama_index.core.readers.base import BaseReader\n",
105+
"from llama_index.core import Document"
106+
]
107+
},
108+
{
109+
"cell_type": "code",
110+
"execution_count": null,
111+
"id": "d7be5ce9-b30b-4511-94c4-3c15f8011d4a",
112+
"metadata": {},
113+
"outputs": [],
114+
"source": [
115+
"documents = SimpleDirectoryReader(input_files = [r\"DataSet/CVPR2019/abstracts_pdf\"]).load_data()"
116+
]
117+
},
118+
{
119+
"cell_type": "markdown",
120+
"id": "2aa21a24-eac7-49c2-a53a-20beb6d21aaa",
121+
"metadata": {},
122+
"source": [
123+
"## Create the Index\n",
124+
"The next step is to index the data loaded, this is done through vector embeddings. Prior to indexing it is important to initialize a Cosmos DB NoSql vector store where the embeddings will be stored."
125+
]
126+
},
127+
{
128+
"cell_type": "code",
129+
"execution_count": null,
130+
"id": "c401450f-187a-41b7-8e77-fb7367081e13",
131+
"metadata": {},
132+
"outputs": [],
133+
"source": [
134+
"from azure.cosmos import CosmosClient, PartitionKey\n",
135+
"from llama_index.vector_stores.azurecosmosnosql import AzureCosmosDBNoSqlVectorSearch\n",
136+
"from llama_index.core import StorageContext\n",
137+
"from llama_index.core import VectorStoreIndex, SimpleDirectoryReader"
138+
]
139+
},
140+
{
141+
"cell_type": "code",
142+
"execution_count": null,
143+
"id": "d28f8d88-bc16-47fa-8088-a091c0d33a1a",
144+
"metadata": {},
145+
"outputs": [],
146+
"source": [
147+
"from llama_index.core import Settings\n",
148+
"\n",
149+
"Settings.llm = llm\n",
150+
"Settings.embed_model = embed_model"
151+
]
152+
},
153+
{
154+
"cell_type": "code",
155+
"execution_count": null,
156+
"id": "c35af3eb-b733-4e09-a98f-8557e14a7522",
157+
"metadata": {},
158+
"outputs": [],
159+
"source": [
160+
"#create cosmos client\n",
161+
"URI = os.getenv('COSMOS_DB_URI')\n",
162+
"KEY = os.getenv('COSMOS_DB_API_KEY')\n",
163+
"client = CosmosClient(URI, credential=KEY)\n",
164+
"\n",
165+
"#specify vector store properties\n",
166+
"indexing_policy = {\n",
167+
" \"indexingMode\": \"consistent\",\n",
168+
" \"includedPaths\": [{\"path\": \"/*\"}],\n",
169+
" \"excludedPaths\": [{\"path\": '/\"_etag\"/?'}],\n",
170+
" \"vectorIndexes\": [{\"path\": \"/embedding\", \"type\": \"quantizedFlat\"}],\n",
171+
"}\n",
172+
"\n",
173+
"vector_embedding_policy = {\n",
174+
" \"vectorEmbeddings\": [\n",
175+
" {\n",
176+
" \"path\": \"/embedding\",\n",
177+
" \"dataType\": \"float32\",\n",
178+
" \"distanceFunction\": \"cosine\",\n",
179+
" \"dimensions\": 3072,\n",
180+
" }\n",
181+
" ]\n",
182+
"}\n",
183+
"\n",
184+
"partition_key = PartitionKey(path=\"/id\")\n",
185+
"cosmos_container_properties_test = {\"partition_key\": partition_key}\n",
186+
"cosmos_database_properties_test = {}\n",
187+
"\n",
188+
"#create vector store\n",
189+
"store = AzureCosmosDBNoSqlVectorSearch(cosmos_client=client,\n",
190+
" vector_embedding_policy=vector_embedding_policy,\n",
191+
" indexing_policy=indexing_policy,\n",
192+
" cosmos_container_properties=cosmos_container_properties_test,\n",
193+
" cosmos_database_properties=cosmos_database_properties_test,\n",
194+
" create_container=True,\n",
195+
" database_name = \"rag_chatbot_example\")\n",
196+
"\n",
197+
"storage_context = StorageContext.from_defaults(vector_store=store)\n",
198+
"\n",
199+
"#index the data\n",
200+
"index = VectorStoreIndex.from_documents(\n",
201+
" documents, storage_context=storage_context\n",
202+
")"
203+
]
204+
},
205+
{
206+
"cell_type": "markdown",
207+
"id": "5018f41f-a8e3-4a6b-9733-e7a4359b2f9d",
208+
"metadata": {},
209+
"source": [
210+
"## Query the data"
211+
]
212+
},
213+
{
214+
"cell_type": "code",
215+
"execution_count": null,
216+
"id": "956c80f1-5b95-4833-b82d-bc2848bf01c6",
217+
"metadata": {},
218+
"outputs": [],
219+
"source": [
220+
"!pip install gradio"
221+
]
222+
},
223+
{
224+
"cell_type": "code",
225+
"execution_count": null,
226+
"id": "2ed68388-1910-401c-89d7-f957bbce2831",
227+
"metadata": {},
228+
"outputs": [],
229+
"source": [
230+
"import gradio as gr"
231+
]
232+
},
233+
{
234+
"cell_type": "code",
235+
"execution_count": null,
236+
"id": "38e1b8d4-ef27-47e9-af8f-fb487000719a",
237+
"metadata": {},
238+
"outputs": [],
239+
"source": [
240+
"query_engine = index.as_query_engine()\n",
241+
"def user_query(user_prompt, chat_history):\n",
242+
" # Create a timer to measure the time it takes to complete the request\n",
243+
" start_time = time.time()\n",
244+
" # Get LLM completion\n",
245+
" response = query_engine.query(user_prompt) \n",
246+
" # Stop the timer\n",
247+
" end_time = time.time()\n",
248+
" elapsed_time = round((end_time - start_time) * 1000, 2)\n",
249+
" print(response)\n",
250+
" # Append user message and response to chat history\n",
251+
" details = f\"\\n (Time: {elapsed_time}ms)\"\n",
252+
" chat_history.append([user_prompt, str(response) + details])\n",
253+
" \n",
254+
" return gr.update(value=\"\"), chat_history"
255+
]
256+
},
257+
{
258+
"cell_type": "code",
259+
"execution_count": null,
260+
"id": "5f643488-442b-41e4-8dcb-d279c9310183",
261+
"metadata": {},
262+
"outputs": [],
263+
"source": [
264+
"chat_history = []\n",
265+
"with gr.Blocks() as demo:\n",
266+
" chatbot = gr.Chatbot(label=\"RAG Chatbot\")\n",
267+
" \n",
268+
" msg = gr.Textbox(label=\"Ask me anything about the document!\")\n",
269+
" clear = gr.Button(\"Clear\")\n",
270+
" \n",
271+
" msg.submit(user_query, [msg, chatbot], [msg, chatbot], queue=False)\n",
272+
"\n",
273+
" clear.click(lambda: None, None, chatbot, queue=False)\n",
274+
"\n",
275+
"# Launch the Gradio interface\n",
276+
"demo.launch(debug=True)"
277+
]
278+
},
279+
{
280+
"cell_type": "code",
281+
"execution_count": null,
282+
"id": "1874d1c5-7ed1-43c2-a1f2-604f043fa449",
283+
"metadata": {},
284+
"outputs": [],
285+
"source": [
286+
"demo.close()"
287+
]
288+
}
289+
],
290+
"metadata": {
291+
"kernelspec": {
292+
"display_name": "Python 3 (ipykernel)",
293+
"language": "python",
294+
"name": "python3"
295+
},
296+
"language_info": {
297+
"codemirror_mode": {
298+
"name": "ipython",
299+
"version": 3
300+
},
301+
"file_extension": ".py",
302+
"mimetype": "text/x-python",
303+
"name": "python",
304+
"nbconvert_exporter": "python",
305+
"pygments_lexer": "ipython3",
306+
"version": "3.12.3"
307+
}
308+
},
309+
"nbformat": 4,
310+
"nbformat_minor": 5
311+
}

0 commit comments

Comments
 (0)