Task 02 - Create and store vector embeddings (45 minutes)
Introduction
Vectors, also known as embeddings or vector embeddings, are mathematical representations of data in a high-dimensional space. Each dimension corresponds to a feature of the data in this space, and tens of thousands of dimensions might be used to represent sophisticated data. A vector’s position in this space represents its characteristics. Words, phrases, or entire documents, as well as images, audio, and other types of data, can all be vectorized. An embedding is a data representation format that machine learning models and algorithms can efficiently utilize. The embedding is an information-dense representation of the semantic meaning of a piece of text. Each embedding is a vector of floating point numbers. Hence, the distance between two embeddings in the vector space correlates with the semantic similarity between two inputs in the original format. Azure OpenAI provides several models for creating vector embeddings, and for this exercise, you will use the text-embedding-ada-002
model.
You will use a vector database to store the generated embeddings. Vector databases are designed to store and manage vector embeddings. The vector database you will use is Azure Cosmos DB for NoSQL. It allows you to store vectors alongside traditional schema-free data within your documents, streamlining data management and significantly enhancing the efficiency of vector operations. Keeping all relevant data in a single logical unit simplifies your data architecture, making it easy to understand and manage.
Description
You configured Azure Cosmos DB for NoSQL as an integrated vector database in the prior task. In this task, you will use an Azure Function, Azure OpenAI, and the Azure Cosmos DB change feed to generate vector embeddings for property maintenance requests and save those into the MaintenanceRequests
container in Cosmos DB.
You will conclude by uploading data supplied by the Contoso Suites staff into the MaintenanceRequests
container you created in Cosmos DB and allowing the deployed function app to generate vectors for each record. The JSON data files provided by Contoso Suites contain maintenance requests for several hotels on their resorts. They offer an example of the types of data the company believes can benefit from the similarity search capabilities provided by Vector Search in Cosmos DB for NoSQL, so they would like you to incorporate this data into the proof of concept.
Success Criteria
- You have tested the function locally.
- You have deployed the function to your Azure Function app.
- You have successfully created vector embeddings for each document in the
PropertyMaintenance.json
file using the deployed Function App and written them into Azure Cosmos DB. - You have executed a
VectorDistance()
function via the Cosmos DB Data Explorer.
Learning Resources
- What are vector embeddings?
- Understand embeddings in Azure OpenAI service
- Azure OpenAI embeddings models
- Learn how to generate embeddings with Azure OpenAI
- VectorDistance (NoSQL query)
- OpenAI Inference
- AzureOpenAIClient class
- Serverless event-based architectures with Azure Cosmos DB and Azure Functions
- Connect Azure Functions to Azure Cosmos DB using Visual Studio Code
- Azure Cosmos DB output binding for Azure Functions
Tips
-
You may get the following error when trying to deploy the Azure Function:
If you get this error message, you must set the default Azure Functions project in the workspace folder. Close and re-open Visual Studio Code, and you should see a warning message that you have multiple function projects in the same workspace folder.
After selecting the Set Default button, you will receive a prompt to choose a default project subpath. Choose the
src\ContosoSuites\VectorizationFunction
option.You may receive a warning message asking if you wish to initialize this function for optimal use with Visual Studio Code. Select Yes to do this.
You will receive a warning modal that this operation will overwrite your task.json. Select Overwrite to complete this task.
-
If you receive authentication errors for Cosmos DB when running the Azure Function locally, it may be that internal policies have disabled key-based authentication. To fix this:
Navigate to the
src\InfrastructureAsCode
folder to Visual Studio Code and right-click theDeployAzureResources.bicep
file. Then, select Deploy Bicep File… in the context menu. This will update your Azure Cosmos DB instance to re-enable key-based authentication.The update may take up to 10 minutes before you see the change apply.
Key Tasks
01: Review Azure function code
Review the Azure Function code in the CosmosChangeFeedVectorization.cs
file in the src\ContosoSuitesVectorizationFunction
folder. The function:
- Is triggered whenever a document is inserted or updated in the
MaintenanceRequests
container using the Azure Cosmos DB change feed. - Combines the contents of a maintenance request’s
hotel
anddetails
fields and vectorizes the resulting text using atext-embedding-ada-002
model in Azure OpenAI. - Writes generated vectors into the
request_embeddings
fields of the document and updates it in theMaintenanceRequests
container. - Marks the document as “Vectorized.”
Expand this section to view the solution
The steps to review the function app are as follows:
- Open the
CosmosChangeFeedVectorization.cs
file in thesrc\ContosoSuitesVectorizationFunction
folder. - The
DatabaseName
andContainerName
constants defined on lines 16 and 17 refer to the Azure Cosmos DB database created by the Bicep script and the container you created in task 1 of this exercise, respectively. If those values differ in your environment, the values assigned to the constants must be updated to reflect what is in your environment. - Locate the
Run
function starting on line 42 and examine the code contained within it.- The code on line 49 reduces the list of documents sent to the function to only those that do not have a
Type
of “Vectorized”. This prevents the updates pushed by the function back to theMaintenanceRequests
container from being revectorized by the function. - If no documents require vectorization, the function will exit without making any changes to the input documents.
- The
foreach
loop starting on line 52 iterates through each document in the change feed that requires vectorization. Thehotel
anddetails
fields are combined, and the text is sent to Azure OpenAI to create vector embeddings using the deployment for thetext-embedding-ada-002
model. The returned vector embeddings are saved into theRequestVector
field of the document. - The document’s
Type
field is “Vectorized.” - On line 74, the list of input documents is returned, which uses the Cosmos DB output binding to write the documents updated with vector embeddings back into the
MaintenanceRequests
container in Cosmos DB.
- The code on line 49 reduces the list of documents sent to the function to only those that do not have a
02: Create settings file
Create a local.settings.json
file in the src\ContosoSuitesVectorizationFunction
folder and populate it with the settings the function needs to run the function locally. Hint: the required values can be identified using the calls to Environment.GetEnvironmentVariable
in the CosmosChangeFeedVectorization.cs
file, as well as providing the Cosmos DB connection string required by the input and output bindings of the function.
Expand this section to view the solution
To create a local.settings.json
file, navigate to the src\ContosoSuitesVectorizationFunction
directory, create a new file named local.settings.json
, and add the following content, replacing the bracketed tokens with values from your Azure OpenAI and Azure Cosmos DB services.
{
"IsEncrypted": false,
"Values": {
"AzureWebJobsStorage": "",
"FUNCTIONS_WORKER_RUNTIME": "dotnet-isolated",
"AZURE_TENANT_ID": "[YOUR_AZURE_TENANT_ID]",
"AzureOpenAIEndpoint": "[YOUR_AZURE_OPENAI_ENDPOINT]",
"AzureOpenAIKey": "[YOUR_AZURE_OPENAI_KEY]",
"CosmosDBConnection__accountEndpoint": "[YOUR_COSMOS_DB_ENDPOINT]",
"EmbeddingDeploymentName": "text-embedding-ada-002"
}
}
To retrieve the required Azure OpenAI and Cosmos DB values:
- Open the Azure portal in a web browser and navigate to the resource group you created.
- Select the Azure OpenAI service in the resource group.
- Under the Resource Management menu, select Keys and Endpoint.
- Copy the value of KEY 1 and paste it into the
AzureOpenAIKey
value of thelocal.settings.json
file. - Copy the value of Endpoint and paste it into the
AzureOpenAIEndpoint
value.
- Return to your resource group and select the Azure Cosmos DB resource.
- Under the Settings menu, select Keys, then show and copy the URI value and paste it as the
CosmosDBConnection__accountEndpoint
value in thelocal.settings.json
file.
- Find and copy the ClientId of the User-Assigned Managed Identity in your resource group. Paste it as the
CosmosDBConnection__clientId
value in thelocal.settings.json
file.
- Under the Settings menu, select Keys, then show and copy the URI value and paste it as the
- The
EmbeddingDeploymentName
value is preset, based on the deployment created by the Bicep script for thetext-embedding-ada-002
model. If that value differs in your environment, you must update this setting accordingly.
03: Test the function
Test the function locally and evaluate the inputs and outputs of the function.
- Use breakpoints in the function’s
Run
method to examine the input collection and processing as a new record is added. -
After starting a local debug session, insert the following document into the
MaintenanceRequests
container and observe the function execution results as your breakpoints are hit.{ "hotel_id": 1, "hotel": "Oceanview Inn", "source": "customer", "date": "2024-08-10", "details": "The air conditioning (A/C) unit in room 227 is malfunctioning and making a loud noise. Customer will be out of the room between 5:00 and 8:30 PM this evening. This needs immediate maintenance attention. If the issue cannot be resolved, we will need to move the customer to a new room.", "room_number": 227 }
- Once the function execution is complete, examine the document in Cosmos DB and inspect the vector embeddings inserted into the
request_vector
field of the document.
Expand this section to view the solution
To test the function locally:
- Open a new terminal window in Visual Studio Code and change the path to the
src\ContosoSuitesVectorizationFunction
folder. - Open the
CosmosChangeFeedVectorization.cs
file in thesrc\ContosoSuitesVectorizationFunction
folder. - Set a breakpoint on line 50 so you can examine the values of the
documentsToVectorize
,task.RequestVector
, andinput
as you step through the function. - Select F5 on your keyboard to start a debug session in Visual Studio Code. In the terminal window created, wait until the function has started.
- In a browser window, open the Azure portal and navigate to your Cosmos DB account.
- On the Azure Cosmos DB account page, select Data Explorer from the left-hand menu, expand the ContosoSuites database and the MaintenanceRequests container, and select Items under the container.
-
Select New item on the toolbar, then paste the following document into the window that appears.
{ "hotel_id": 1, "hotel": "Oceanview Inn", "source": "customer", "date": "2024-08-10", "details": "The air conditioning (A/C) unit in room 227 is malfunctioning and making a loud noise. Customer will be out of the room between 5:00 and 8:30 PM this evening. This needs immediate maintenance attention. If the issue cannot be resolved, we will need to move the customer to a new room.", "room_number": 227 }
- Select Save on the toolbar to insert the document into the
MaintenanceRequests
container: - Return to Visual Studio Code and wait for your breakpoint to be hit.
- Observe the values of the
documentsToVectorize
,task.RequestVector
, andinput
variables as you step through the code (F11), allowing the function to run completely. - Return to the Cosmos DB Data Explorer in the Azure portal and select the document that was inserted into the
MaintenanceRequests
container. Inspect therequest_vector
property to review the structure of the generated vector embeddings. Also, note thetype
field has been set to “Vectorized.” - Return to Visual Studio Code and select “Shift+F5” on the keyboard to stop the function app debug session.
04: Deploy the function app
Use VS Code to deploy the function to the Azure Function App in your resource group and add the required app configuration settings.
Expand this section to view the solution
The steps to deploy the function to Azure are as follows:
- In Visual Studio Code, open a new terminal window and change the directory to the
src\ContosoSuitesVectorizationFunction
project folder. -
At the terminal prompt, execute the following command to build a release version of the function:
dotnet build --configuration Release dotnet publish
- In the explorer pane in Visual Studio Code, navigate to the
src\ContosoSuitesVectorizationFunction\bin\Release\net8.0
folder, then right-click on thepublish
folder, and in the context menu, select Deploy to Function App. - In the Select Function App command pallet dialog that appears at the top of Visual Studio Code:
- Select the subscription you are using for this exercise.
- Choose the function app in your resource group.
- Select Deploy in the Visual Studio Code dialog asking about deploying and overwriting previous deployments.
- Use the Output window at the bottom of Visual Studio Code to monitor the deployment.
-
When the deployment is complete, you will get a notification in the bottom right-hand corner of Visual Studio Code. In this notification window, select Upload settings. This will upload the values from the
local.settings.json
file into environment variables in your function app.
05: Check environment variables
Confirm the settings were uploaded correctly by navigating to the Settings menu of your function app in the Azure portal and selecting Environment variables. Along with other settings added by the Bicep script and deployment process, you should see the following settings:
AzureOpenAIEndpoint
AzureOpenAIKey
CosmosDBConnection__accountEndpoint
EmbeddingDeploymentName
If you do not see these settings, add them using the App settings tab’s + Add button.
06: Verify function behavior
Verify that the deployed function is working correctly by inserting the following record into the MaintenanceRequests
container in Cosmos DB. Then, use the Log Stream for the Function App to observe the output.
{
"hotel_id": 12,
"hotel": "The Downtown Plaza Hotel",
"source": "customer",
"date": "2024-08-11",
"details": "The thermostat does not appear to be working in room 328, and the air conditioning (A/C) unit will not turn on to cool down the room.",
"room_number": 328
}
Expand this section to view the solution
To verify the function app was deployed successfully and is working correctly:
- Open the Log Stream for the Function App by selecting Log Stream under Monitoring in the left-hand menu of the Function App page in the Azure portal.
- Open a new browser window or tab, navigate to the
MaintenanceRequests
container in your Cosmos DB account, and selectItems
. -
Insert the following record into the
MaintenanceRequests
container in Cosmos DB.{ "hotel_id": 12, "hotel": "The Downtown Plaza Hotel", "source": "customer", "date": "2024-08-11", "details": "The thermostat does not appear to be working in room 328, and the air conditioning (A/C) unit will not turn on to cool down the room.", "room_number": 328 }
- Return to the Function Apps Log Stream browser window and observe the logs to ensure you see the function execute and verify that it generated vector embeddings for the maintenance request.
- Return to the Cosmos DB
MaintenanceRequests
browser window and select the request item that was just inserted to ensure it refreshes and contains arequest_vector
value.
07: Populate maintenance requests container
Populate the MaintenanceRequests
container with data from the PropertyMaintenance.json
file in the src\data folder of the repository.
Expand this section to view the solution
Use the Data Explorer to populate the MaintenanceRequests
container with data from the PropertyMaintenance.json
file provided by Contoso Suites.
- In the Azure portal, navigate to your Cosmos DB resource and select Data Explorer in the left-hand menu.
-
In the Data Explorer, expand the ContosoSuites database and the MaintenanceRequests container, then select Items.
-
Select Upload Item on the toolbar.
-
In the Upload Items dialog, select the browse button and navigate to the
PropertyMaintenance.json
file in thesrc\data
directory in the location where cloned the repository, then select Upload to import the data in the file.If you are using a GitHub Codespaces instance, you can right-click on the
PropertyMaintenance.json
file and select Download to save a local copy of this file.The upload status should indicate 48 documents created.
- Return to the Function Apps Log Stream browser window you opened in the previous step and observe the logs as the maintenance requests are uploaded and processed in bulk.
-
Return to the Cosmos DB
MaintenanceRequests
browser window, close the upload dialog, and select the refresh icon on the MaintenanceRequests>Items tab in the Data Explorer. - Select a few random request items to ensure they contain a
request_vector
value and have atype
of “Vectorized.”
08: Review results
- Observe the files being processed in the Log Stream and review documents in the Cosmos DB Data Explorer to confirm the function correctly populated the
request_vector
field for newly added documents. - Execute a query to find documents similar to “air conditioning malfunction” using the
VectorDistance()
function via Cosmos DB Data Explorer. You can find the vector embeddings for “air conditioning malfunction” in theQuery_Vector.txt
file in the src\data folder.
Expand this section to view the solution
To execute a query using the VectorDistance()
function for “air conditioning malfunction”:
- In the Azure portal, navigate to your Cosmos DB resource and select Data Explorer in the left-hand menu.
- In the Data Explorer, expand the ContosoSuites database and the MaintenanceRequests container, then select Items.
-
On the toolbar, select New SQL Query.
-
In the new query window, paste in the following query:
SELECT c.hotel_id, c.hotel, c.details, VectorDistance(c.request_vector, <QUERY_VECTOR>) AS SimilarityScore FROM c
- Replace the
<QUERY_VECTOR>
token in the query with the vectorized representation of “air conditioning malfunction,” which you can find in theQuery_Vector.txt
file in the src\data folder. Copy the entire contents of the file, and paste it into the query in place of<QUERY_VECTOR>
. -
Select Execute Query on the toolbar and observe the output in the Results panel. You should see a list of results similar to the following (abbreviated for brevity):
{ "hotel_id": 1, "hotel": "Oceanview Inn", "details": "The air conditioning (A/C) unit in room 227 is malfunctioning and making a loud noise. Customer will be out of the room between 5:00 and 8:30 PM this evening. This needs immediate maintenance attention. If the issue cannot be resolved, we will need to move the customer to a new room.", "SimilarityScore": 0.847799148429741 }, { "hotel_id": 12, "hotel": "The Downtown Plaza Hotel", "details": "The thermostat does not appear to be working in room 328, and the air conditioning (A/C) unit will not turn on to cool down the room.", "SimilarityScore": 0.838297398035295 }