diff --git a/docs/ai/quickstarts/evaluate-ai-response.md b/docs/ai/quickstarts/evaluate-ai-response.md index 387f80454714b..97630751d4e30 100644 --- a/docs/ai/quickstarts/evaluate-ai-response.md +++ b/docs/ai/quickstarts/evaluate-ai-response.md @@ -24,7 +24,7 @@ To provision an Azure OpenAI service and model using the Azure portal, complete ## Create the test app -Complete the following steps to create an MSTest project that connects to your local `phi3:mini` AI model. +Complete the following steps to create an MSTest project that connects to the `gpt-4o` AI model. 1. In a terminal window, navigate to the directory where you want to create your app, and create a new MSTest app with the `dotnet new` command: diff --git a/docs/ai/quickstarts/snippets/structured-output/Program.cs b/docs/ai/quickstarts/snippets/structured-output/Program.cs new file mode 100644 index 0000000000000..ae5f6a125a24f --- /dev/null +++ b/docs/ai/quickstarts/snippets/structured-output/Program.cs @@ -0,0 +1,66 @@ +using Azure.AI.OpenAI; +using Azure.Identity; +using Microsoft.Extensions.AI; +using Microsoft.Extensions.Configuration; + +// +IConfigurationRoot config = new ConfigurationBuilder() + .AddUserSecrets() + .Build(); + +string endpoint = config["AZURE_OPENAI_ENDPOINT"]; +string model = config["AZURE_OPENAI_GPT_NAME"]; +string tenantId = config["AZURE_TENANT_ID"]; + +// Get a chat client for the Azure OpenAI endpoint. +AzureOpenAIClient azureClient = + new( + new Uri(endpoint), + new DefaultAzureCredential(new DefaultAzureCredentialOptions() { TenantId = tenantId })); +IChatClient chatClient = azureClient + .GetChatClient(deploymentName: model) + .AsIChatClient(); +// + +// +string review = "I'm happy with the product!"; +var response = await chatClient.GetResponseAsync($"What's the sentiment of this review? {review}"); +Console.WriteLine($"Sentiment: {response.Result}"); +// + +// +string[] inputs = [ + "Best purchase ever!", + "Returned it immediately.", + "Hello", + "It works as advertised.", + "The packaging was damaged but otherwise okay." +]; + +foreach (var i in inputs) +{ + var response2 = await chatClient.GetResponseAsync($"What's the sentiment of this review? {i}"); + Console.WriteLine($"Review: {i} | Sentiment: {response2.Result}"); +} +// + +// +var review3 = "This product worked okay."; +var response3 = await chatClient.GetResponseAsync($"What's the sentiment of this review? {review3}"); + +Console.WriteLine($"Response text: {response3.Result.ResponseText}"); +Console.WriteLine($"Sentiment: {response3.Result.ReviewSentiment}"); +// + +// +record SentimentRecord(string ResponseText, Sentiment ReviewSentiment); +// + +// +public enum Sentiment +{ + Positive, + Negative, + Neutral +} +// diff --git a/docs/ai/quickstarts/snippets/structured-output/SOChat.csproj b/docs/ai/quickstarts/snippets/structured-output/SOChat.csproj new file mode 100644 index 0000000000000..ba893a63002a3 --- /dev/null +++ b/docs/ai/quickstarts/snippets/structured-output/SOChat.csproj @@ -0,0 +1,20 @@ + + + + Exe + net9.0 + enable + enable + f28ec9ea-e017-46d7-9865-73550c9ec06b + + + + + + + + + + + + diff --git a/docs/ai/quickstarts/structured-output.md b/docs/ai/quickstarts/structured-output.md new file mode 100644 index 0000000000000..dc9586121f8c4 --- /dev/null +++ b/docs/ai/quickstarts/structured-output.md @@ -0,0 +1,115 @@ +--- +title: Quickstart - Request a response with structured output +description: Learn how to create a chat app that responds with structured output, that is, output that conforms to a type that you specify. +ms.date: 04/30/2025 +ms.topic: quickstart +ms.custom: devx-track-dotnet, devx-track-dotnet-ai +--- + +# Request a response with structured output + +In this quickstart, you create a chat app that requests a response with *structured output*. A structured output response is a chat response that's of a type you specify instead of just plain text. The chat app you create in this quickstart analyzes sentiment of various product reviews, categorizing each review according to the values of a custom enumeration. + +## Prerequisites + +- [.NET 8 or a later version](https://dotnet.microsoft.com/download) +- [Visual Studio Code](https://code.visualstudio.com/) (optional) + +## Configure the AI service + +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. In the "Deploy a model" step, select the `gpt-4o` model. + +## Create the chat app + +Complete the following steps to create a console app that connects to the `gpt-4o` AI model. + +1. In a terminal window, navigate to the directory where you want to create your app, and create a new console app with the `dotnet new` command: + + ```dotnetcli + dotnet new console -o SOChat + ``` + +1. Navigate to the `SOChat` directory, and add the necessary packages to your app: + + ```dotnetcli + dotnet add package Azure.AI.OpenAI + dotnet add package Azure.Identity + dotnet add package Microsoft.Extensions.AI --prerelease + dotnet add package Microsoft.Extensions.AI.OpenAI --prerelease + dotnet add package Microsoft.Extensions.Configuration + dotnet add package Microsoft.Extensions.Configuration.UserSecrets + ``` + +1. Run the following commands to add [app secrets](/aspnet/core/security/app-secrets) for your Azure OpenAI endpoint, model name, and tenant ID: + + ```bash + dotnet user-secrets init + dotnet user-secrets set AZURE_OPENAI_ENDPOINT + dotnet user-secrets set AZURE_OPENAI_GPT_NAME gpt-4o + dotnet user-secrets set AZURE_TENANT_ID + ``` + + > [!NOTE] + > Depending on your environment, the tenant ID might not be needed. In that case, remove it from the code that instantiates the . + +1. Open the new app in your editor of choice. + +## Add the code + +1. Define the enumeration that describes the different sentiments. + + :::code language="csharp" source="./snippets/structured-output/Program.cs" id="SentimentEnum"::: + +1. Create the that will communicate with the model. + + :::code language="csharp" source="./snippets/structured-output/Program.cs" id="GetChatClient"::: + + > [!NOTE] + > searches for authentication credentials from your environment or local tooling. 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). + +1. Send a request to the model with a single product review, and then print the analyzed sentiment to the console. You declare the requested structured output type by passing it as the type argument to the extension method. + + :::code language="csharp" source="./snippets/structured-output/Program.cs" id="SimpleRequest"::: + + This code produces output similar to: + + ```output + Sentiment: Positive + ``` + +1. Instead of just analyzing a single review, you can analyze a collection of reviews. + + :::code language="csharp" source="./snippets/structured-output/Program.cs" id="MultipleReviews"::: + + This code produces output similar to: + + ```output + Review: Best purchase ever! | Sentiment: Positive + Review: Returned it immediately. | Sentiment: Negative + Review: Hello | Sentiment: Neutral + Review: It works as advertised. | Sentiment: Neutral + Review: The packaging was damaged but otherwise okay. | Sentiment: Neutral + ``` + +1. And instead of requesting just the analyzed enumeration value, you can request the text response along with the analyzed value. + + Define a record type to contain the text response and analyzed sentiment: + + :::code language="csharp" source="./snippets/structured-output/Program.cs" id="InputOutputRecord"::: + + Send the request using the record type as the type argument to `GetResponseAsync`: + + :::code language="csharp" source="./snippets/structured-output/Program.cs" id="RecordRequest"::: + + This code produces output similar to: + + ```output + Response text: Certainly, I have analyzed the sentiment of the review you provided. + Sentiment: Neutral + ``` + +## See also + +- [Structured outputs (Azure OpenAI Service)](/azure/ai-services/openai/how-to/structured-outputs) +- [Using JSON schema for structured output in .NET for OpenAI models](https://devblogs.microsoft.com/semantic-kernel/using-json-schema-for-structured-output-in-net-for-openai-models) +- [Introducing Structured Outputs in the API (OpenAI)](https://openai.com/index/introducing-structured-outputs-in-the-api/) diff --git a/docs/ai/toc.yml b/docs/ai/toc.yml index e070935f5a93a..38f0f85ebc09e 100644 --- a/docs/ai/toc.yml +++ b/docs/ai/toc.yml @@ -17,6 +17,8 @@ items: items: - name: Build a chat app href: quickstarts/build-chat-app.md + - name: Request structured output + href: quickstarts/structured-output.md - name: Build a .NET AI vector search app href: quickstarts/build-vector-search-app.md - name: Execute a local .NET function