From ddd0d3c019f576a9bc7ed68d8eb1a0418e9dee37 Mon Sep 17 00:00:00 2001 From: alexwolfmsft <93200798+alexwolfmsft@users.noreply.github.com> Date: Wed, 18 Dec 2024 09:16:20 -0500 Subject: [PATCH] New vector search quickstart (#43894) * New vector search quickstart --------- Co-authored-by: Genevieve Warren <24882762+gewarren@users.noreply.github.com> --- .../includes/prerequisites-azure-openai.md | 2 +- .../includes/prerequisites-openai.md | 3 +- .../quickstart-ai-chat-with-data.md | 250 ++++++++---------- .../azure-openai/CloudService.cs | 24 ++ .../chat-with-data/azure-openai/Program.cs | 88 ++++++ .../azure-openai/VectorDataAI.csproj | 20 ++ .../chat-with-data/openai/CloudService.cs | 24 ++ .../snippets/chat-with-data/openai/Program.cs | 86 ++++++ .../chat-with-data/openai/VectorDataAI.csproj | 18 ++ docs/ai/toc.yml | 2 +- 10 files changed, 375 insertions(+), 142 deletions(-) create mode 100644 docs/ai/quickstarts/snippets/chat-with-data/azure-openai/CloudService.cs create mode 100644 docs/ai/quickstarts/snippets/chat-with-data/azure-openai/Program.cs create mode 100644 docs/ai/quickstarts/snippets/chat-with-data/azure-openai/VectorDataAI.csproj create mode 100644 docs/ai/quickstarts/snippets/chat-with-data/openai/CloudService.cs create mode 100644 docs/ai/quickstarts/snippets/chat-with-data/openai/Program.cs create mode 100644 docs/ai/quickstarts/snippets/chat-with-data/openai/VectorDataAI.csproj diff --git a/docs/ai/quickstarts/includes/prerequisites-azure-openai.md b/docs/ai/quickstarts/includes/prerequisites-azure-openai.md index 40739e00c7ddf..252db4971b233 100644 --- a/docs/ai/quickstarts/includes/prerequisites-azure-openai.md +++ b/docs/ai/quickstarts/includes/prerequisites-azure-openai.md @@ -7,7 +7,7 @@ ms.topic: include ## Prerequisites -- .NET 8 SDK - [Install the .NET 8 SDK](https://dotnet.microsoft.com/download/dotnet/8.0). +- .NET 8.0 SDK or higher - [Install the .NET 8 SDK](https://dotnet.microsoft.com/download/dotnet/8.0). - An Azure subscription - [Create one for free](https://azure.microsoft.com/free). - Access to [Azure OpenAI service](/azure/ai-services/openai/overview#how-do-i-get-access-to-azure-openai). - Azure Developer CLI (Optional) - [Install or update the Azure Developer CLI](/azure/developer/azure-developer-cli/install-azd). diff --git a/docs/ai/quickstarts/includes/prerequisites-openai.md b/docs/ai/quickstarts/includes/prerequisites-openai.md index d3f9d5c0a1160..d4222270ce398 100644 --- a/docs/ai/quickstarts/includes/prerequisites-openai.md +++ b/docs/ai/quickstarts/includes/prerequisites-openai.md @@ -7,6 +7,5 @@ ms.topic: include ## Prerequisites -- .NET 8.0 SDK - [Install the .NET 8.0 SDK](https://dotnet.microsoft.com/download/dotnet/8.0). +- .NET 8.0 SDK or higher - [Install the .NET 8.0 SDK](https://dotnet.microsoft.com/download/dotnet/8.0). - An [API key from OpenAI](https://platform.openai.com/docs/quickstart/account-setup) so you can run this sample. -- On Windows, PowerShell `v7+` is required. To validate your version, run `pwsh` in a terminal. It should return the current version. If it returns an error, execute the following command: `dotnet tool update --global PowerShell`. diff --git a/docs/ai/quickstarts/quickstart-ai-chat-with-data.md b/docs/ai/quickstarts/quickstart-ai-chat-with-data.md index 581c100a5b922..0f1c677f2a24c 100644 --- a/docs/ai/quickstarts/quickstart-ai-chat-with-data.md +++ b/docs/ai/quickstarts/quickstart-ai-chat-with-data.md @@ -1,215 +1,191 @@ --- -title: Quickstart - Get insight about your data from a .NET AI chat app -description: Create a simple chat app using your data, Semantic Kernel, and OpenAI. -ms.date: 07/17/2024 +title: Quickstart - Build a minimal .NET AI RAG app +description: Create an AI powered app to search and integrate with vector stores using embeddings and the Microsoft.Extensions.VectorData package for .NET +ms.date: 12/06/2024 ms.topic: quickstart ms.custom: devx-track-dotnet, devx-track-dotnet-ai author: fboucher ms.author: frbouche zone_pivot_groups: openai-library -# CustomerIntent: As a .NET developer new to AI development with OpenAI, I want deploy and use sample code and data to interact to learn from the sample code. +# CustomerIntent: As a .NET developer new to AI, I want deploy and use sample code to interact to learn from the sample code. --- -# Get insight about your data from a .NET AI chat app +# Build a .NET AI vector search app + +In this quickstart, you create a .NET console app to perform semantic search on a vector store to find relevant results for the user's query. You learn how to generate embeddings for user prompts and use those embeddings to query the vector data store. Vector search functionality is also a key component for Retrieval Augmented Generation (RAG) scenarios. The app uses the [Microsoft.Extensions.AI](https://www.nuget.org/packages/Microsoft.Extensions.AI) and [Microsoft.Extensions.VectorData.Abstractions](https://www.nuget.org/packages/Microsoft.Extensions.VectorData.Abstractions) libraries so you can write code using AI abstractions rather than a specific SDK. AI abstractions help create loosely coupled code that allows you to change the underlying AI model with minimal app changes. - :::zone target="docs" pivot="openai" - -Get started with AI development using a .NET 8 console app to connect to an OpenAI `gpt-3.5-turbo` model. You'll connect to the AI model using [Semantic Kernel](../semantic-kernel-dotnet-overview.md) to analyze hiking data and provide insights. +[!INCLUDE [openai-prereqs](includes/prerequisites-openai.md)] -[!INCLUDE [download-alert](includes/prerequisites-openai.md)] :::zone-end - :::zone target="docs" pivot="azure-openai" - -Get started with AI development using a .NET 8 console app to connect to an OpenAI `gpt-3.5-turbo` model deployed on Azure. You'll connect to the AI model using [Semantic Kernel](../semantic-kernel-dotnet-overview.md) to analyze hiking data and provide insights. +[!INCLUDE [azure-openai-prereqs](includes/prerequisites-azure-openai.md)] -[!INCLUDE [download-alert](includes/prerequisites-azure-openai.md)] :::zone-end -## Get the sample project - [!INCLUDE [clone-sample-repo](includes/clone-sample-repo.md)] -:::zone target="docs" pivot="azure-openai" - -## Create the Azure OpenAI service +## Interact with your data using vector stores -# [Azure Developer CLI](#tab/azd) +Vector stores or vector databases are essential for tasks like semantic search, Retrieval Augmented Generation (RAG), and other scenarios that require grounding generative AI responses. While relational databases and document databases are optimized for structured and semi-structured data, vector databases are built to efficiently store, index, and manage data represented as embedding vectors. As a result, the indexing and search algorithms used by vector databases are optimized to efficiently retrieve data that can be used downstream in your applications. -[!INCLUDE [deploy-azd](includes/deploy-azd.md)] +### Explore Microsoft.Extensions.VectorData.Abstractions -# [Azure CLI](#tab/azure-cli) +[Microsoft.Extensions.VectorData.Abstractions](https://www.nuget.org/packages/Microsoft.Extensions.VectorData.Abstractions/) is a .NET library developed in collaboration with Semantic Kernel and the broader .NET ecosystem to provide a unified layer of abstractions for interacting with vector stores. -1. To provision an Azure OpenAI service and model using the Azure CLI, complete the steps in the [Create and deploy an Azure OpenAI Service resource](/azure/ai-services/openai/how-to/create-resource?pivots=cli) article. +The abstractions in `Microsoft.Extensions.VectorData.Abstractions` provide library authors and developers with the following functionality: -1. From a terminal or command prompt, navigate to the `src\quickstarts\azure-openai\semantic-kernel\03-ChattingAboutMyHikes` directory. +- Perform Create-Read-Update-Delete (CRUD) operations on vector stores +- Use vector and text search on vector stores -1. Run the following commands to configure your OpenAI API key as a secret for the sample app: +> [!NOTE] +> The [Microsoft.Extensions.VectorData.Abstractions](https://www.nuget.org/packages/Microsoft.Extensions.VectorData.Abstractions/) library is currently in Preview. - ```bash - dotnet user-secrets init - dotnet user-secrets set OpenAIKey +## Create the app -# [Azure Portal](#tab/azure-portal) +Complete the following steps to create a .NET console app that can accomplish the following: -1. To provision an Azure OpenAI service and model using the Azure portal, complete the steps in the [Create and deploy an Azure OpenAI Service resource](/azure/ai-services/openai/how-to/create-resource?pivots=web-portal) article. +- Create and populate a vector store by generating embeddings for a data set +- Generate an embedding for the user prompt +- Query the vector store using the user prompt embedding +- Displays the relevant results from the vector search -1. From a terminal or command prompt, navigate to the `src\quickstarts\azure-openai\semantic-kernel\03-ChattingAboutMyHikes` directory. +1. In an empty directory on your computer, use the `dotnet new` command to create a new console app: -1. Run the following commands to configure your OpenAI API key as a secret for the sample app: + ```dotnetcli + dotnet new console -o VectorDataAI + ``` - ```bash - dotnet user-secrets init - dotnet user-secrets set OpenAIKey +1. Change directory into the app folder: ---- + ```dotnetcli + cd VectorDataAI + ``` -:::zone-end +1. Install the required packages: -## Try the hiking chat sample + :::zone target="docs" pivot="azure-openai" - -:::zone target="docs" pivot="openai" + ```bash + dotnet add package Azure.Identity + dotnet add package Azure.AI.OpenAI + dotnet add package Microsoft.Extensions.AI.OpenAI --prerelease + dotnet add package Microsoft.Extensions.VectorData.Abstractions --prerelease + dotnet add package Microsoft.SemanticKernel.Connectors.InMemory --prerelease + dotnet add package Microsoft.Extensions.Configuration + dotnet add package Microsoft.Extensions.Configuration.UserSecrets + ``` -1. From a terminal or command prompt, navigate to the `src\quickstarts\openai\semantic-kernel\03-ChattingAboutMyHikes` directory. + The following list describes what each package is used for in the `VectorDataAI` app: -1. Run the following commands to configure your OpenAI API key as a secret for the sample app: + - [`Azure.Identity`](https://www.nuget.org/packages/Azure.Identity) provides [`Microsoft Entra ID`](https://learn.microsoft.com/entra/fundamentals/whatis) token authentication support across the Azure SDK using classes such as `DefaultAzureCredential`. + - [`Azure.AI.OpenAI`](https://www.nuget.org/packages/Azure.AI.OpenAI) is the official package for using OpenAI's .NET library with the Azure OpenAI Service. + - [`Microsoft.SemanticKernel.Connectors.InMemory`](https://www.nuget.org/packages/Microsoft.SemanticKernel.Connectors.InMemory) provides an in-memory vector store class to hold queryable vector data records. + - [`Microsoft.Extensions.VectorData.Abstractions`](https://www.nuget.org/packages/Microsoft.Extensions.AI) enables Create-Read-Update-Delete (CRUD) and search operations on vector stores. + - [Microsoft.Extensions.Configuration](https://www.nuget.org/packages/Microsoft.Extensions.Configuration) provides implementation of key-value pair based configuration. + - [`Microsoft.Extensions.Configuration.UserSecrets`](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.UserSecrets) is a user secrets configuration provider implementation for `Microsoft.Extensions.Configuration`. - ```bash - dotnet user-secrets init - dotnet user-secrets set OpenAIKey - ``` + :::zone-end -1. Use the `dotnet run` command to run the app: + :::zone target="docs" pivot="openai" - ```dotnetcli - dotnet run + ```bash + dotnet add package Microsoft.Extensions.AI.OpenAI --prerelease + dotnet add package Microsoft.Extensions.VectorData.Abstractions --prerelease + dotnet add package Microsoft.SemanticKernel.Connectors.InMemory --prerelease + dotnet add package Microsoft.Extensions.Configuration + dotnet add package Microsoft.Extensions.Configuration.UserSecrets ``` -:::zone-end + The following list describes what each package is used for in the `VectorDataAI` app: -:::zone target="docs" pivot="azure-openai" + - [`Microsoft.Extensions.AI.OpenAI`](https://www.nuget.org/packages/Microsoft.Extensions.AI.OpenAI) provides AI abstractions for OpenAI-compatible models or endpoints. This library also includes the official [`OpenAI`](https://www.nuget.org/packages/OpenAI) library for the OpenAI service API as a dependency. + - [`Microsoft.SemanticKernel.Connectors.InMemory`](https://www.nuget.org/packages/Microsoft.SemanticKernel.Connectors.InMemory) provides an in-memory vector store class to hold queryable vector data records. + - [`Microsoft.Extensions.VectorData.Abstractions`](https://www.nuget.org/packages/Microsoft.Extensions.AI) enables Create-Read-Update-Delete (CRUD) and search operations on vector stores. + - [Microsoft.Extensions.Configuration](https://www.nuget.org/packages/Microsoft.Extensions.Configuration) provides implementation of key-value pair based configuration. + - [`Microsoft.Extensions.Configuration.UserSecrets`](https://www.nuget.org/packages/Microsoft.Extensions.Configuration.UserSecrets) is a user secrets configuration provider implementation for `Microsoft.Extensions.Configuration`. -1. From a terminal or command prompt, navigate to the `semantic-kernel\02-HikerAI` directory. + :::zone-end -2. Use the `dotnet run` command to run the app: +1. Open the app in Visual Studio Code (or your editor of choice). - ```dotnetcli - dotnet run + ```bash + code . ``` - > [!TIP] - > If you get an error message, the Azure OpenAI resources might not have finished deploying. Wait a couple of minutes and try again. - -:::zone-end +:::zone target="docs" pivot="azure-openai" - +[!INCLUDE [create-ai-service](includes/create-ai-service.md)] -## Explore the code +:::zone-end - :::zone target="docs" pivot="openai" - -The application uses the [`Microsoft.SemanticKernel`](https://www.nuget.org/packages/Microsoft.SemanticKernel) package to send and receive requests to an OpenAI service. -The entire application is contained within the **Program.cs** file. The first several lines of code set configuration values and gets the OpenAI Key that was previously set using the `dotnet user-secrets` command. +## Configure the app -```csharp -var config = new ConfigurationBuilder().AddUserSecrets().Build(); -string model = "gpt-3.5-turbo"; -string key = config["OpenAIKey"]; -``` +1. Navigate to the root of your .NET project from a terminal or command prompt. -The `OpenAIChatCompletionService` service facilitates the requests and responses. +1. Run the following commands to configure your OpenAI API key as a secret for the sample app: -```csharp -// Create the OpenAI Chat Completion Service -OpenAIChatCompletionService service = new(model, key); -``` + ```bash + dotnet user-secrets init + dotnet user-secrets set OpenAIKey + dotnet user-secrets set ModelName + ``` -Once the `OpenAIChatCompletionService` client is created, the app reads the content of the file `hikes.md` and uses it to provide more context to the model by adding a system prompt. This influences model behavior and the generated completions during the conversation. :::zone-end -:::zone target="docs" pivot="azure-openai" +## Add the app code -The application uses the [`Microsoft.SemanticKernel`](https://www.nuget.org/packages/Microsoft.SemanticKernel) package to send and receive requests to an Azure OpenAI service deployed in Azure. +1. Add a new class named **CloudService** to your project with the following properties: -The entire application is contained within the **Program.cs** file. The first several lines of code loads up secrets and configuration values that were set in the `dotnet user-secrets` for you during the application provisioning. + :::code language="csharp" source="snippets/chat-with-data/azure-openai/CloudService.cs" ::: -```csharp -// == Retrieve the local secrets saved during the Azure deployment ========== -var config = new ConfigurationBuilder().AddUserSecrets().Build(); -string endpoint = config["AZURE_OPENAI_ENDPOINT"]; -string deployment = config["AZURE_OPENAI_GPT_NAME"]; -``` + In the preceding code: + - The C# attributes provided by `Microsoft.Extensions.VectorData` influence how each property is handled when used in a vector store + - The **Vector** property stores a generated embedding that represents the semantic meaning of the **Name** and **Description** for vector searches -The `AzureOpenAIChatCompletionService` service facilitates the requests and responses. +1. In the **Program.cs** file, add the following code to create a data set that describes a collection of cloud services: -```csharp -// == Create the Azure OpenAI Chat Completion Service ========== -AzureOpenAIChatCompletionService service = new(deployment, endpoint, new DefaultAzureCredential()); -``` + :::code language="csharp" source="snippets/chat-with-data/azure-openai/program.cs" range="8-46"::: -Once the `OpenAIChatCompletionService` client is created, the app reads the content of the file `hikes.md` and uses it to provide more context to the model by adding a system prompt. This influences model behavior and the generated completions during the conversation. -:::zone-end +1. Create and configure an `IEmbeddingGenerator` implementation to send requests to an embedding AI model: -```csharp -// Provide context for the AI model -ChatHistory chatHistory = new($""" - You are upbeat and friendly. You introduce yourself when first saying hello. - Provide a short answer only based on the user hiking records below: + :::zone target="docs" pivot="azure-openai" - {File.ReadAllText("hikes.md")} - """); -Console.WriteLine($"{chatHistory.Last().Role} >>> {chatHistory.Last().Content}"); -``` + :::code language="csharp" source="snippets/chat-with-data/azure-openai/program.cs" range="48-58"::: -The following code adds a user prompt to the model using the `AddUserMessage` function. The `GetChatMessageContentAsync` function instructs the model to generate a response based off the system and user prompts. - -```csharp -// Start the conversation -chatHistory.AddUserMessage("Hi!"); -Console.WriteLine($"{chatHistory.Last().Role} >>> {chatHistory.Last().Content}"); - -chatHistory.Add( - await service.GetChatMessageContentAsync( - chatHistory, - new OpenAIPromptExecutionSettings() - { - MaxTokens = 400 - })); -Console.WriteLine($"{chatHistory.Last().Role} >>> {chatHistory.Last().Content}"); -``` + > [!NOTE] + > searches for authentication credentials from your local tooling. If you aren't using the `azd` template to provision the Azure OpenAI resource, you'll need to assign the `Azure AI Developer` role to the account you used to sign in to Visual Studio or the Azure CLI. For more information, see [Authenticate to Azure AI services with .NET](../azure-ai-services-authentication.md). -The app adds the response from the model to the `chatHistory` to maintain the chat history or context. + :::zone-end -```csharp -// Continue the conversation with a question. -chatHistory.AddUserMessage( - "I would like to know the ratio of the hikes I've done in Canada compared to other countries."); + :::zone target="docs" pivot="openai" -Console.WriteLine($"{chatHistory.Last().Role} >>> {chatHistory.Last().Content}"); + :::code language="csharp" source="snippets/chat-with-data/openai/program.cs" range="49-57"::: -chatHistory.Add(await service.GetChatMessageContentAsync( - chatHistory, - new OpenAIPromptExecutionSettings() - { - MaxTokens = 400 - })); + :::zone-end -Console.WriteLine($"{chatHistory.Last().Role} >>> {chatHistory.Last().Content}"); -``` +1. Create and populate a vector store with the cloud service data. Use the `IEmbeddingGenerator` implementation to create and assign an embedding vector for each record in the cloud service data: -Customize the system or user prompts to provide different questions and context: + :::code language="csharp" source="snippets/chat-with-data/azure-openai/program.cs" range="61-70"::: -- How many times did I hike when it was raining? -- How many times did I hike in 2021? + The embeddings are numerical representations of the semantic meaning for each data record, which makes them compatible with vector search features. -The model generates a relevant response to each prompt based on your inputs. +1. Create an embedding for a search query and use it to perform a vector search on the vector store: + + :::code language="csharp" source="snippets/chat-with-data/azure-openai/program.cs" range="72-88"::: + +1. Use the `dotnet run` command to run the app: + + ```dotnetcli + dotnet run + ``` + + The app prints out the top result of the vector search, which is the cloud service that is most relevant to the original query. You can modify the query to try different search scenarios. :::zone target="docs" pivot="azure-openai" @@ -221,11 +197,9 @@ When you no longer need the sample application or resources, remove the correspo azd down ``` -[!INCLUDE [troubleshoot](includes/troubleshoot.md)] - :::zone-end ## Next steps -- [Quickstart - Generate images using AI with .NET](quickstart-openai-generate-images.md) -- [Generate text and conversations with .NET and Azure OpenAI Completions](/training/modules/open-ai-dotnet-text-completions/) +- [Quickstart - Chat with a local AI model](quickstart-local-ai.md) +- [Generate images using AI with .NET](quickstart-openai-generate-images.md) diff --git a/docs/ai/quickstarts/snippets/chat-with-data/azure-openai/CloudService.cs b/docs/ai/quickstarts/snippets/chat-with-data/azure-openai/CloudService.cs new file mode 100644 index 0000000000000..281536280814a --- /dev/null +++ b/docs/ai/quickstarts/snippets/chat-with-data/azure-openai/CloudService.cs @@ -0,0 +1,24 @@ +using Microsoft.Extensions.VectorData; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace VectorDataAI +{ + internal class CloudService + { + [VectorStoreRecordKey] + public int Key { get; set; } + + [VectorStoreRecordData] + public string Name { get; set; } + + [VectorStoreRecordData] + public string Description { get; set; } + + [VectorStoreRecordVector(384, DistanceFunction.CosineSimilarity)] + public ReadOnlyMemory Vector { get; set; } + } +} diff --git a/docs/ai/quickstarts/snippets/chat-with-data/azure-openai/Program.cs b/docs/ai/quickstarts/snippets/chat-with-data/azure-openai/Program.cs new file mode 100644 index 0000000000000..3514b4d04e5f3 --- /dev/null +++ b/docs/ai/quickstarts/snippets/chat-with-data/azure-openai/Program.cs @@ -0,0 +1,88 @@ +using Azure.AI.OpenAI; +using Azure.Identity; +using Microsoft.Extensions.AI; +using Microsoft.Extensions.VectorData; +using Microsoft.Extensions.Configuration; +using Microsoft.SemanticKernel.Connectors.InMemory; +using VectorDataAI; + +var cloudServices = new List() +{ + new CloudService + { + Key=0, + Name="Azure App Service", + Description="Host .NET, Java, Node.js, and Python web applications and APIs in a fully managed Azure service. You only need to deploy your code to Azure. Azure takes care of all the infrastructure management like high availability, load balancing, and autoscaling." + }, + new CloudService + { + Key=1, + Name="Azure Service Bus", + Description="A fully managed enterprise message broker supporting both point to point and publish-subscribe integrations. It's ideal for building decoupled applications, queue-based load leveling, or facilitating communication between microservices." + }, + new CloudService + { + Key=2, + Name="Azure Blob Storage", + Description="Azure Blob Storage allows your applications to store and retrieve files in the cloud. Azure Storage is highly scalable to store massive amounts of data and data is stored redundantly to ensure high availability." + }, + new CloudService + { + Key=3, + Name="Microsoft Entra ID", + Description="Manage user identities and control access to your apps, data, and resources.." + }, + new CloudService + { + Key=4, + Name="Azure Key Vault", + Description="Store and access application secrets like connection strings and API keys in an encrypted vault with restricted access to make sure your secrets and your application aren't compromised." + }, + new CloudService + { + Key=5, + Name="Azure AI Search", + Description="Information retrieval at scale for traditional and conversational search applications, with security and options for AI enrichment and vectorization." + } +}; + +// Load the configuration values +var config = new ConfigurationBuilder().AddUserSecrets().Build(); +string endpoint = config["AZURE_OPENAI_ENDPOINT"]; +string model = config["AZURE_OPENAI_GPT_NAME"]; + +// Create the embedding generator +IEmbeddingGenerator> generator = + new AzureOpenAIClient( + new Uri(endpoint), + new DefaultAzureCredential()) + .AsEmbeddingGenerator(modelId: model); + +// Create and populate the vector store +var vectorStore = new InMemoryVectorStore(); +var cloudServicesStore = vectorStore.GetCollection("cloudServices"); +await cloudServicesStore.CreateCollectionIfNotExistsAsync(); + +foreach (var service in cloudServices) +{ + service.Vector = await generator.GenerateEmbeddingVectorAsync(service.Description); + await cloudServicesStore.UpsertAsync(service); +} + +// Convert a search query to a vector and search the vector store +var query = "Which Azure service should I use to store my Word documents?"; +var queryEmbedding = await generator.GenerateEmbeddingVectorAsync(query); + +var results = await cloudServicesStore.VectorizedSearchAsync(queryEmbedding, new VectorSearchOptions() +{ + Top = 1, + VectorPropertyName = "Vector" +}); + +await foreach (var result in results.Results) +{ + Console.WriteLine($"Name: {result.Record.Name}"); + Console.WriteLine($"Description: {result.Record.Description}"); + Console.WriteLine($"Vector match score: {result.Score}"); + Console.WriteLine(); +} diff --git a/docs/ai/quickstarts/snippets/chat-with-data/azure-openai/VectorDataAI.csproj b/docs/ai/quickstarts/snippets/chat-with-data/azure-openai/VectorDataAI.csproj new file mode 100644 index 0000000000000..ddceb5109f173 --- /dev/null +++ b/docs/ai/quickstarts/snippets/chat-with-data/azure-openai/VectorDataAI.csproj @@ -0,0 +1,20 @@ + + + + Exe + net8.0 + enable + enable + + + + + + + + + + + + + diff --git a/docs/ai/quickstarts/snippets/chat-with-data/openai/CloudService.cs b/docs/ai/quickstarts/snippets/chat-with-data/openai/CloudService.cs new file mode 100644 index 0000000000000..281536280814a --- /dev/null +++ b/docs/ai/quickstarts/snippets/chat-with-data/openai/CloudService.cs @@ -0,0 +1,24 @@ +using Microsoft.Extensions.VectorData; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace VectorDataAI +{ + internal class CloudService + { + [VectorStoreRecordKey] + public int Key { get; set; } + + [VectorStoreRecordData] + public string Name { get; set; } + + [VectorStoreRecordData] + public string Description { get; set; } + + [VectorStoreRecordVector(384, DistanceFunction.CosineSimilarity)] + public ReadOnlyMemory Vector { get; set; } + } +} diff --git a/docs/ai/quickstarts/snippets/chat-with-data/openai/Program.cs b/docs/ai/quickstarts/snippets/chat-with-data/openai/Program.cs new file mode 100644 index 0000000000000..49ede09c7c558 --- /dev/null +++ b/docs/ai/quickstarts/snippets/chat-with-data/openai/Program.cs @@ -0,0 +1,86 @@ +using Microsoft.Extensions.AI; +using OpenAI; +using Microsoft.Extensions.VectorData; +using Microsoft.SemanticKernel.Connectors.InMemory; +using VectorDataAI; +using System.ClientModel; +using Microsoft.Extensions.Configuration; + +var cloudServices = new List() +{ + new CloudService + { + Key=0, + Name="Azure App Service", + Description="Host .NET, Java, Node.js, and Python web applications and APIs in a fully managed Azure service. You only need to deploy your code to Azure. Azure takes care of all the infrastructure management like high availability, load balancing, and autoscaling." + }, + new CloudService + { + Key=1, + Name="Azure Service Bus", + Description="A fully managed enterprise message broker supporting both point to point and publish-subscribe integrations. It's ideal for building decoupled applications, queue-based load leveling, or facilitating communication between microservices." + }, + new CloudService + { + Key=2, + Name="Azure Blob Storage", + Description="Azure Blob Storage allows your applications to store and retrieve files in the cloud. Azure Storage is highly scalable to store massive amounts of data and data is stored redundantly to ensure high availability." + }, + new CloudService + { + Key=3, + Name="Microsoft Entra ID", + Description="Manage user identities and control access to your apps, data, and resources.." + }, + new CloudService + { + Key=4, + Name="Azure Key Vault", + Description="Store and access application secrets like connection strings and API keys in an encrypted vault with restricted access to make sure your secrets and your application aren't compromised." + }, + new CloudService + { + Key=5, + Name="Azure AI Search", + Description="Information retrieval at scale for traditional and conversational search applications, with security and options for AI enrichment and vectorization." + } +}; + +// Load the configuration values +var config = new ConfigurationBuilder().AddUserSecrets().Build(); +string model = config["ModelName"]; +string key = config["OpenAIKey"]; + +// Create the embedding generator +IEmbeddingGenerator> generator = + new OpenAIClient(new ApiKeyCredential(key)) + .AsEmbeddingGenerator(modelId: model); + +// Create and populate the vector store +var vectorStore = new InMemoryVectorStore(); +var cloudServicesStore = vectorStore.GetCollection("cloudServices"); +await cloudServicesStore.CreateCollectionIfNotExistsAsync(); + +foreach (var service in cloudServices) +{ + service.Vector = await generator.GenerateEmbeddingVectorAsync(service.Description); + await cloudServicesStore.UpsertAsync(service); +} + +// Convert a search query to a vector and search the vector store +var query = "Which Azure service should I use to store my Word documents?"; +var queryEmbedding = await generator.GenerateEmbeddingVectorAsync(query); + +var results = await cloudServicesStore.VectorizedSearchAsync(queryEmbedding, new VectorSearchOptions() +{ + Top = 1, + VectorPropertyName = "Vector" +}); + +await foreach (var result in results.Results) +{ + Console.WriteLine($"Name: {result.Record.Name}"); + Console.WriteLine($"Description: {result.Record.Description}"); + Console.WriteLine($"Vector match score: {result.Score}"); + Console.WriteLine(); +} diff --git a/docs/ai/quickstarts/snippets/chat-with-data/openai/VectorDataAI.csproj b/docs/ai/quickstarts/snippets/chat-with-data/openai/VectorDataAI.csproj new file mode 100644 index 0000000000000..856644990902a --- /dev/null +++ b/docs/ai/quickstarts/snippets/chat-with-data/openai/VectorDataAI.csproj @@ -0,0 +1,18 @@ + + + + Exe + net8.0 + enable + enable + + + + + + + + + + + diff --git a/docs/ai/toc.yml b/docs/ai/toc.yml index e212d2d65dfc2..0cf04d0f41f2d 100644 --- a/docs/ai/toc.yml +++ b/docs/ai/toc.yml @@ -19,7 +19,7 @@ items: href: quickstarts/quickstart-openai-summarize-text.md - name: Build a chat app href: quickstarts/get-started-openai.md - - name: Create an app to chat about your data + - name: Build a .NET AI vector search app href: quickstarts/quickstart-ai-chat-with-data.md - name: Execute a local .NET function href: quickstarts/quickstart-azure-openai-tool.md