Skip to main content Link Menu Expand (external link) Document Search Copy Copied

Task 03 - Integrate vector search capabilities into the Contoso Suites CIS (30 minutes)

Introduction

Implementing vector search capabilities in the Contoso Suites UI will allow customer service representatives to use natural language queries to find maintenance requests. This functionality relies on vector search’s ability to find items based on data characteristics instead of exact matches on a specific property field. In the prior task, you vectorized maintenance request content that combined the hotel’s name with the request details, allowing searching for requests at a specific hotel or across various properties.

Description

In the previous task, you added vector embeddings to property maintenance request data stored in Azure Cosmos DB for NoSQL and then performed a vector search using query embeddings stored in a file. It is necessary to create embeddings for incoming query text to perform vector searches, so in this task, you will integrate vector search capabilities into the Contoso Suites Customer Information System (CIS) application, leveraging a vectorization API endpoint in the Contoso Suites Web API to create embeddings for the query being performed. The API will vectorize incoming questions from the UI, which can be used in queries executing the VectorDistance() function.

Success Criteria

  • You have tested the /Vectorize endpoint of the ContosoSuitesWebAPI locally and used the generated vectors to execute similarity search queries in Azure Cosmos DB.
  • You have updated the VectorizationService and its interface to include an ExecuteVectorSearch(float[] queryVector, int count = 0) method that returns List<VectorSearchResult>>.
  • You have added a /VectorSearch endpoint to the API.
  • You have tested the /VectorSearch endpoint using the Swagger UI by passing in vector embeddings generated by the /Vectorize endpoint.
  • You have successfully added the ability to perform vector searches to the UI and submitted queries.

Tips

  • If the ContosoSuitesWebAPI .NET application build is failing when you try to run dotnet run and you receive an error that the build cannot load the required packages from NuGet, you may be missing a link to the Microsoft NuGet repository. Run the command dotnet nuget list source and see if you have an entry enabled for nuget.org. If not, add it with the following command: dotnet nuget add source https://api.nuget.org/v3/index.json -n nuget.org. If you have one but it is currently disabled, you can enable it with the command dotnet nuget enable source nuget.org.

Learning Resources

Key Tasks

01: Add user secrets

Add new .NET user secrets called CosmosDB:AccountEndpoint and AZURE_CLIENT_ID. These values should be your Cosmos DB URI and your Managed Identity Client ID. Add a third user secret called AzureOpenAI:EmbeddingDeploymentName, which should take on a value of text-embedding-ada-002.

Expand this section to view the solution

To add the user secrets, run the following command:

  dotnet user-secrets set "CosmosDB:AccountEndpoint" "{YOUR_COSMOSDB_URI}"
  dotnet user-secrets set "AZURE_CLIENT_ID" "{YOUR_CLIENT_ID_FROM_RESOUREC_GROUP}"
  dotnet user-secrets set "CosmosDB:DatabaseName" "ContosoSuites"
  dotnet user-secrets set "CosmosDB:MaintenanceRequestsContainerName" "MaintenanceRequests"
  dotnet user-secrets set "AzureOpenAI:EmbeddingDeploymentName" "text-embedding-ada-002"

02: Generate query embedding

Generate query text embeddings using the /Vectorize endpoint of the ContosoSuitesWebAPI.

Expand this section to view the solution

The steps to generate vector embeddings for query text using the ContosoSuitesWebAPI’s /Vectorize endpoint are as follows:

  1. In Visual Studio Code, open a new terminal window and change the directory to src\ContotoSuitesWebAPI.
  2. At the terminal prompt, enter the following command to run the API locally:

     dotnet run
    
  3. Once the API has started, as indicated by output in the terminal stating Now listening on: http://localhost:5292, open a web browser and navigate to the Swagger UI page for the API.

    If you are using a GitHub Codespaces instance, open the website in a browser and navigate to the /swagger URL.

  4. Expand the /Vectorize endpoint block on the Swagger UI page.

    The Swagger UI page is displayed with the expand button for the Vectorize endpoint highlighted.

  5. Within the /Vectorize block, select Try it out.

    The try it out button is highlighted for the Vectorize endpoint.

  6. Enter the query “rooms where the air conditioning is not working” into the text box, then select Execute.

    In the Vectorize block, the text block is highlighted with the query text above entered and the execute button is highlighted.

  7. Observe the Response body returned. The response contains an array of floating point values representing the query text. This array contains 1536 dimensions.
  8. Copy the entire response body, including the opening and closing square brackets.

    The Response body block for the vectorization request is highlighted.

  9. In the Azure portal, navigate to your Cosmos DB resource and select Data Explorer in the left-hand menu.
  10. In the Data Explorer, expand the ContosoSuites database and the MaintenanceRequests container, then select Items.
  11. On the toolbar, select New SQL Query.
  12. In the new query window, paste in the following query:

    SELECT c.hotel, c.details, VectorDistance(c.request_vector, <QUERY_VECTOR>) AS SimilarityScore
    FROM c
    
  13. Replace the <QUERY_VECTOR> token in the query with the vector output you copied from the API response body.
  14. Select Execute Query on the toolbar and observe the output in the Results panel.
  15. In Visual Studio Code, stop the API project by selecting the terminal window where it is running and pressing CTRL+C.

Provide a method named ExecuteVectorSearch in the VectorizationService for executing a vector search query against Azure Cosmos DB. The method should accept vectorized query text (called queryVector), the maximum number of results to return (named max_results), and the minimum similarity score (named minimum_similarity_score) and execute a query using the VectorDistance() function. It should return a list of VectorSearchResult objects. The count should limit the number of results returned. The query executed in Cosmos DB should use the following pattern:

var vectorString = string.Join(", ", queryVector.Select(v => v.ToString(CultureInfo.InvariantCulture)).ToArray());

var query = $"SELECT c.hotel_id AS HotelId, c.hotel AS Hotel, c.details AS Details, c.source AS Source, VectorDistance(c.request_vector, [{vectorString}]) AS SimilarityScore FROM c";
query += $" WHERE VectorDistance(c.request_vector, [{vectorString}]) > {minimum_similarity_score.ToString(CultureInfo.InvariantCulture)}";
query += $" ORDER BY VectorDistance(c.request_vector, [{vectorString}])";
Expand this section to view the solution

To provide a method in the VectorizationService and an API endpoint for executing a vector search query against Azure Cosmos DB:

  1. In Visual Studio Code, open the IVectorizationService.cs file in the src\ContosoSuitesWebAPI folder and complete Exercise 3 Task 3 TODO #1 by uncommenting the interface definition for the ExecuteVectorSearch method.
  2. Next, open the VectorizationService.cs file in the src\ContosoSuitesWebAPI folder and complete Exercise 3 Task 3 TODO #2 by uncommenting the method definition for the ExecuteVectorSearch method.

04: Update vector search route handler

Update the /VectorSearch route handler in the Program.cs file to call the ExecuteVectorSearch method on the VectorizationService and return the results.

Expand this section to view the solution

To complete the code for the exposing /VectorSearch endpoint on the API:

  1. Open the Program.cs file in the src\ContosoSuitesWebAPI folder, locate the app.MapPost("/VectorSearch"...) route handler, and complete Exercise 3 Task 3 TODO #3 by writing code to call the ExecuteVectorSearch method on the VectorizationService and returning the results. The body of the route handler should contain the following or similar code:

     var results = await vectorizationService.ExecuteVectorSearch(queryVector, max_results, minimum_similarity_score);
     return results;
    
  2. Return to the terminal prompt and enter the following command again to start the API locally:

     dotnet run
    
  3. Once the API has started, test the /VectorSearch endpoint by opening a web browser and navigating to the Swagger UI page for the API.
  4. On the Swagger UI page, use the /Vectorize endpoint to generate embeddings for the query text “rooms where the air conditioning is not working”, as you did previously.
  5. Copy the entire response body, including the opening and closing square brackets.
  6. Expand the /VectorSearch endpoint block and select Try it out.
  7. Enter “5” into the max_results parameter box.
  8. Enter “0.5” into the minimum_similarity_score parameter box.
  9. Paste the vector embeddings you copied from the output of the /Vectorize endpoint into the Request body block, and select Execute.

    The inputs into the max_results, minimum_similarity_score, and request body boxes are highlighted in the VectorSearch block, and the Execute button is highlighted.

  10. Ensure the response body contains a collection of VectorSearchResult objects. The output should look similar to the following:

    [
      {
        "hotelId": 13,
        "hotel": "Seaside Luxury Resort",
        "details": "Guest in room 220 reported that the air conditioning is not cooling properly.",
        "source": "customer",
        "similarityScore": 0.8718685
      },
      {
        "hotelId": 1,
        "hotel": "Oceanview Inn",
        "details": "The air conditioning (A/C) unit in room 105 is malfunctioning and making a loud noise. This needs maintenance attention.",
        "source": "staff",
        "similarityScore": 0.8505241
      },
      {
        "hotelId": 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.",
        "source": "customer",
        "similarityScore": 0.8503952
      },
      {
        "hotelId": 13,
        "hotel": "Seaside Luxury Resort",
        "details": "Reported issue with the thermostat in room 110. Maintenance needs to check the HVAC system.",
        "source": "staff",
        "similarityScore": 0.8419426
      },
      {
        "hotelId": 1,
        "hotel": "Oceanview Inn",
        "details": "Reported issue with the thermostat in room 210. Maintenance needs to check the HVAC system.",
        "source": "staff",
        "similarityScore": 0.8410596
      }
    ]
    
  11. Leave the Web API running for the next step.

05: Update and test dashboard

Implement vector search capabilities to the UI and submit the following queries for maintenance requests:

  1. Set the search query to “Show me rooms where the air conditioning unit is malfunctioning,” enter ten as the max result count and select a minimum similarity score of 0.80.
  2. Execute the same query a second time, this time setting the minimum similarity score to 0.82, and observe how that setting can be used to reduce the number of irrelevant results.
  3. Search for “Rooms at the Oceanview Inn where there are air conditioning issues, “ enter five as the maximum number of results to return and set the minimum similarity score slider to 0.85.
  4. Finally, find fire safety requests using the search query, “Are there any requests about fire and safety equipment at any hotels?” Set the max results to 10.
Expand this section to view the solution

To add vector search capabilities to the UI, open the file src\ContosoSuitesDashboard\pages\3_Vector_Search.py. The code will run as-is, but will not have knowledge of how to vectorize query text or perform vector searches. To support vector search capabilities, make the following changes to the Python script.

  1. In the if query: block of the Submit button code in the main() function:
    1. Vectorize the search query text by completing Exercise 3 Task 3 TODO #4. Send the search query text to the handle_query_vectorization() method and set the results to a variable.
    2. Perform a vector search by completing Exercise 3 Task 3 TODO #5. Pass the vectorized search query, along with the desired number of results, to the handle_vector_search() function.
    3. Display the results in a table by completing Exercise 3 Task 3 TODO #6. Use the st.table() method and provide the JSON value from the search results.
  2. The completed code for the if st.button("Submit") block should look like the following:

     if st.button("Submit"):
               with st.spinner("Performing vector search..."):
                   if query:
                       # Vectorize the query text.
                       # Exercise 3 Task 3 TODO #4: Get the vectorized query text by calling handle_query_vectorization.
                       query_vector = handle_query_vectorization(query)
                       # Perform the vector search.
                       # Exercise 3 Task 3 TODO #5: Get the vector search results by calling handle_vector_search.
                       vector_search_results = handle_vector_search(query_vector, max_results, minimum_similarity_score)
                       # Display the results.
                       st.write("## Results")
                       # Exercise 3 Task 3 TODO #6: Display the results as a table.
                       st.table(vector_search_results.json())
                   else:
                       st.warning("Please enter a query.")
    

    Python code is sensitive to indentation and formatting, so pay close attention to indentation if copying and pasting the above code into the 3_Vector_Search.py file.

  3. Test your completed code by opening a new terminal window in Visual Studio Code, navigating to the src\ContosoSuitesDashboard folder, and running the following command to start the Streamlit dashboard:

     python -m streamlit run Index.py
    
  4. Navigate to the Vector Search page using the left-hand menu in the browser windows that opens, and then submit the following queries for maintenance requests and observe the results:
    1. Set the search query to “Show me rooms where the air conditioning unit is malfunctioning,” enter ten as the max result count and select a minimum similarity score of 0.80.
    2. Execute the same query a second time, this time setting the minimum similarity score to 0.82, and observe how that setting can be used to reduce the number of irrelevant results.
    3. Search for “Rooms at the Oceanview Inn where there are air conditioning issues, “ enter five as the maximum number of results to return and set the minimum similarity score slider to 0.85.
    4. Find fire safety requests using the search query, “Are there any requests about fire and safety equipment at any hotels?” Set the max results to 10.