diff --git a/.openpublishing.redirection.ai.json b/.openpublishing.redirection.ai.json index ef52176e5e7d0..8c73dbebb51da 100644 --- a/.openpublishing.redirection.ai.json +++ b/.openpublishing.redirection.ai.json @@ -1,3 +1,8 @@ { - "redirections": [] + "redirections": [ + { + "source_path_from_root": "/docs/ai/quickstarts/get-started-azure-openai.md", + "redirect_url": "/dotnet/ai/quickstarts/get-started-openai" + } + ] } \ No newline at end of file diff --git a/docs/ai/get-started/dotnet-ai-overview.md b/docs/ai/get-started/dotnet-ai-overview.md index 3a52c6f3c4194..a8c3c804d440e 100644 --- a/docs/ai/get-started/dotnet-ai-overview.md +++ b/docs/ai/get-started/dotnet-ai-overview.md @@ -1,7 +1,7 @@ --- title: Develop .NET applications with AI features description: Learn how you can build .NET applications that include AI features. -ms.date: 05/17/2024 +ms.date: 07/30/2024 ms.topic: overview ms.custom: devx-track-dotnet, devx-track-dotnet-ai --- @@ -36,7 +36,7 @@ We recommend the following sequence of tutorials and articles for an introductio |Scenario |Tutorial | |----------|----------| -| Create a chat application | [Build an Azure AI chat app with .NET](../quickstarts/get-started-azure-openai.md)| +| Create a chat application | [Build an Azure AI chat app with .NET](../quickstarts/get-started-openai.md)| | Summarize text | [Summarize text using Azure AI chat app with .NET](../quickstarts/quickstart-openai-summarize-text.md) | | Chat with your data | [Get insight about your data from an .NET Azure AI chat app](../quickstarts/quickstart-ai-chat-with-data.md) | | Call .NET functions with AI | [Extend Azure AI using tools and execute a local function with .NET](../quickstarts/quickstart-azure-openai-tool.md) | @@ -47,5 +47,5 @@ Browse the table of contents to learn more about the core concepts, starting wit ## Next steps -- [Quickstart: Build an Azure AI chat app with .NET](../quickstarts/get-started-azure-openai.md) +- [Quickstart: Build an Azure AI chat app with .NET](../quickstarts/get-started-openai.md) - [Video series: Machine Learning and AI with .NET](/shows/machine-learning-and-ai-with-dotnet-for-beginners) diff --git a/docs/ai/index.yml b/docs/ai/index.yml index 611f4f4c8a702..af00f5e0e6880 100644 --- a/docs/ai/index.yml +++ b/docs/ai/index.yml @@ -28,7 +28,7 @@ landingContent: - text: Learning resources and samples url: azure-ai-for-dotnet-developers.md - text: Build an Azure AI chat app with .NET - url: quickstarts/get-started-azure-openai.md + url: quickstarts/get-started-openai.md - text: Summarize text using an Azure OpenAI chat app url: quickstarts/quickstart-openai-summarize-text.md - text: Generate images using Azure AI with .NET diff --git a/docs/ai/quickstarts/get-started-azure-openai.md b/docs/ai/quickstarts/get-started-azure-openai.md deleted file mode 100644 index ce5cc451e6b59..0000000000000 --- a/docs/ai/quickstarts/get-started-azure-openai.md +++ /dev/null @@ -1,222 +0,0 @@ ---- -title: Quickstart - Build an Azure AI chat app with .NET -description: Create a simple chat app using Semantic Kernel or the .NET Azure OpenAI SDK. -ms.date: 03/04/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 Azure OpenAI, I want deploy and use sample code to interact to learn from the sample code. ---- - -# Build an Azure AI chat app with .NET - - -:::zone target="docs" pivot="semantic-kernel" - - -Get started with Semantic Kernel by creating a simple .NET 8 console chat application. The application will run locally and use the OpenAI `gpt-35-turbo` model deployed into an Azure OpenAI account. Follow these steps to provision Azure OpenAI and learn how to use Semantic Kernel. - -:::zone-end - - -:::zone target="docs" pivot="azure-openai-sdk" - - -Get started with the .NET Azure OpenAI SDK by creating a simple .NET 8 console chat application. The application will run locally and use the OpenAI `gpt-35-turbo` model deployed into an Azure OpenAI account. Follow these steps to provision Azure OpenAI and learn how to use the .NET Azure OpenAI SDK. - -:::zone-end - -[!INCLUDE [download-alert](includes/prerequisites-and-azure-deploy.md)] - -## Trying HikerAI sample - - -:::zone target="docs" pivot="semantic-kernel" - -1. From a terminal or command prompt, navigate to the `semantic-kernel\02-HikerAI` directory. - -:::zone-end - -:::zone target="docs" pivot="azure-openai-sdk" - -1. From a terminal or command prompt, navigate to the `azure-openai-sdk\02-HikerAI` directory. - -:::zone-end - -2. It's now time to try the console application. Type in the following to run the app: - - ```dotnetcli - dotnet run - ``` - - If you get an error message the Azure OpenAI resources may not have finished deploying. Wait a couple of minutes and try again. - - - -:::zone target="docs" pivot="semantic-kernel" - - -## Understanding the code - -Our application uses the `Microsoft.SemanticKernel` package, which is available on [NuGet](https://www.nuget.org/packages/Microsoft.SemanticKernel), to send and receive requests to an Azure OpenAI service deployed in Azure. - -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. - -```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"]; -string key = config["AZURE_OPENAI_KEY"]; -``` - -The `AzureOpenAIChatCompletionService` service facilitates the requests and responses. - -```csharp -// == Create the Azure OpenAI Chat Completion Service ========== -AzureOpenAIChatCompletionService service = new(deployment, endpoint, key); -``` - -Once the `AzureOpenAIChatCompletionService` service is created, we provide more context to the model by adding a system prompt. This instructs the model how you'd like it to act during the conversation. - -```csharp -// Start the conversation with context for the AI model -ChatHistory chatHistory = new(""" - You are a hiking enthusiast who helps people discover fun hikes in their area. You are upbeat and friendly. - You introduce yourself when first saying hello. When helping people out, you always ask them - for this information to inform the hiking recommendation you provide: - - 1. Where they are located - 2. What hiking intensity they are looking for - - You will then provide three suggestions for nearby hikes that vary in length after you get that information. - You will also share an interesting fact about the local nature on the hikes when making a recommendation. - """); -``` - -Then you can add a user message to the model by using the `AddUserMessage` function. - -To have the model generate a response based off the system prompt and the user request, use the `GetChatMessageContentAsync` function. - -```csharp - -// Add user message to chat history -chatHistory.AddUserMessage("Hi! Apparently you can help me find a hike that I will like?"); - -// Print User Message to console -Console.WriteLine($"{chatHistory.Last().Role} >>> {chatHistory.Last().Content}"); - -// Get response -var response = await service.GetChatMessageContentAsync(chatHistory, new OpenAIPromptExecutionSettings() { MaxTokens = 400 }); -``` - -To maintain the chat history, make sure you add the response from the model. - -```csharp -// Add response to chat history -chatHistory.Add(response); - -// Print Response to console -Console.WriteLine($"{chatHistory.Last().Role} >>> {chatHistory.Last().Content}"); -``` - -Customize the system prompt and user message to see how the model responds to help you find a hike that you'll like. - -:::zone-end - - -:::zone target="docs" pivot="azure-openai-sdk" - - -## Understanding the code - -Our application uses the `Azure.AI.OpenAI` client SDK, which is available on [NuGet](https://www.nuget.org/packages/Azure.AI.OpenAI), to send and receive requests to an Azure OpenAI service deployed in Azure. - -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. - -```csharp -// == Retrieve the local secrets saved during the Azure deployment ========== -var config = new ConfigurationBuilder().AddUserSecrets().Build(); -string openAIEndpoint = config["AZURE_OPENAI_ENDPOINT"]; -string openAIDeploymentName = config["AZURE_OPENAI_GPT_NAME"]; -string openAiKey = config["AZURE_OPENAI_KEY"]; - -// == Creating the AIClient ========== -var endpoint = new Uri(openAIEndpoint); -var credentials = new AzureKeyCredential(openAiKey); -``` - -The `OpenAIClient` class facilitates the requests and responses. `ChatCompletionOptions` specifies parameters of how the model will respond. - -```csharp -var openAIClient = new OpenAIClient(endpoint, credentials); - -var completionOptions = new ChatCompletionsOptions -{ - MaxTokens = 400, - Temperature = 1f, - FrequencyPenalty = 0.0f, - PresencePenalty = 0.0f, - NucleusSamplingFactor = 0.95f, // Top P - DeploymentName = openAIDeploymentName -}; -``` - -Once the `OpenAIClient` client is created, we provide more context to the model by adding a system prompt. This instructs the model how you'd like it to act during the conversation. - -```csharp -var systemPrompt = -""" -You are a hiking enthusiast who helps people discover fun hikes in their area. You are upbeat and friendly. -You introduce yourself when first saying hello. When helping people out, you always ask them -for this information to inform the hiking recommendation you provide: - -1. Where they are located -2. What hiking intensity they are looking for - -You will then provide three suggestions for nearby hikes that vary in length after you get that information. -You will also share an interesting fact about the local nature on the hikes when making a recommendation. -"""; - -completionOptions.Messages.Add(new ChatRequestSystemMessage(systemPrompt)); -``` - -Then you can add a user message to the model by using the `ChatRequestUserMessage` class. - -To have the model generate a response based off the system prompt and the user request, use the `GetChatCompletionsAsync` function. - -```csharp -string userGreeting = """ -Hi! -Apparently you can help me find a hike that I will like? -"""; - -completionOptions.Messages.Add(new ChatRequestUserMessage(userGreeting)); -Console.WriteLine($"\n\nUser >>> {userGreeting}"); - -ChatCompletions response = await openAIClient.GetChatCompletionsAsync(completionOptions); -ChatResponseMessage assistantResponse = response.Choices[0].Message; -Console.WriteLine($"\n\nAI >>> {assistantResponse.Content}"); -completionOptions.Messages.Add(new ChatRequestAssisstantMessage(assistantResponse.Content)); -``` - -To maintain the chat history or context, make sure you add the response from the model as a `ChatRequestAssistantMessage`. - -Customize the system prompt and user message to see how the model responds to help you find a hike that you'll like. - -:::zone-end - -## Clean up resources - -When you no longer need the sample application or resources, remove the corresponding deployment and all resources. - -```azdeveloper -azd down -``` - -## Next steps - -- [Quickstart - Get insight about your data from an .NET Azure AI chat app](quickstart-ai-chat-with-data.md) -- [Generate text and conversations with .NET and Azure OpenAI Completions](/training/modules/open-ai-dotnet-text-completions/) diff --git a/docs/ai/quickstarts/get-started-openai.md b/docs/ai/quickstarts/get-started-openai.md new file mode 100644 index 0000000000000..2ca135c396b69 --- /dev/null +++ b/docs/ai/quickstarts/get-started-openai.md @@ -0,0 +1,196 @@ +--- +title: Quickstart - Build an AI chat app with .NET +description: Create a simple AI powered chat app using Semantic Kernel SDK for .NET and the OpenAI or Azure OpenAI SDKs +ms.date: 07/17/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, I want deploy and use sample code to interact to learn from the sample code. +--- + +# Build an AI chat app with .NET + + +:::zone target="docs" pivot="openai" + + +Get started with OpenAI and [Semantic Kernel](../semantic-kernel-dotnet-overview.md) by creating a simple .NET 8 console chat application. The application will run locally and use the OpenAI `gpt-3.5-turbo` model. Follow these steps to get access to OpenAI and learn how to use Semantic Kernel. + +[!INCLUDE [download-alert](includes/prerequisites-openai.md)] + +:::zone-end + + +:::zone target="docs" pivot="azure-openai" + + +Get started with OpenAI and [Semantic Kernel](../semantic-kernel-dotnet-overview.md) by creating a simple .NET 8 console chat application. The application will run locally and connect to the OpenAI `gpt-35-turbo` model deployed into Azure OpenAI. Follow these steps to provision Azure OpenAI and learn how to use Semantic Kernel. + +[!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" + +[!INCLUDE [deploy-azd](includes/deploy-azd.md)] + +:::zone-end + +## Try the HikerAI sample + + +:::zone target="docs" pivot="openai" + +1. From a terminal or command prompt, navigate to the `openai\02-HikerAI` directory. + +1. Run the following commands to configure your OpenAI API key as a secret for the sample app: + + ```bash + dotnet user-secrets init + dotnet user-secrets set OpenAIKey + ``` + +1. Use the `dotnet run` command to run the app: + + ```dotnetcli + dotnet run + ``` + +:::zone-end + +:::zone target="docs" pivot="azure-openai" + +1. From a terminal or command prompt, navigate to the `azure-openai\02-HikerAI` directory. + +2. Use the `dotnet run` command to run the app: + + ```dotnetcli + dotnet run + ``` + + > [!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="openai" + +## Explore the code + +The app uses the [`Microsoft.SemanticKernel`](https://www.nuget.org/packages/Microsoft.SemanticKernel) package to send and receive requests to the OpenAI service. + +The app code is contained within the **Program.cs** file. The first several lines of code set configuration values and get the OpenAI Key that was previously set using the `dotnet user-secrets` command. + +```csharp +var config = new ConfigurationBuilder().AddUserSecrets().Build(); +string model = "gpt-3.5-turbo"; +string key = config["OpenAIKey"]; +``` + +The `OpenAIChatCompletionService` service facilitates the requests and responses. + +```csharp +// Create the OpenAI Chat Completion Service +OpenAIChatCompletionService service = new(model, key); +``` + +:::zone-end + + +:::zone target="docs" pivot="azure-openai" + + +## Explore the 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. + +The entire application is contained within the **Program.cs** file. The first several lines of code retrieve the secrets and configuration values that were set in the `dotnet user-secrets` for you during the application provisioning. + +```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"]; +string key = config["AZURE_OPENAI_KEY"]; +``` + +The `AzureOpenAIChatCompletionService` service facilitates the requests and responses. + +```csharp +// Create the Azure OpenAI Chat Completion Service +AzureOpenAIChatCompletionService service = new(deployment, endpoint, key); +``` + +:::zone-end + +Add a system prompt to provide more context to the model, which influences model behavior and the generated completions during the conversation. + +```csharp +// Start the conversation with context for the AI model +ChatHistory chatHistory = new(""" + You are a hiking enthusiast who helps people discover fun hikes in their area. + You are upbeat and friendly. You introduce yourself when first saying hello. + When helping people out, you always ask them for this information + to inform the hiking recommendation you provide: + + 1. Where they are located + 2. What hiking intensity they are looking for + + You will then provide three suggestions for nearby hikes that vary in length + after you get that information. You will also share an interesting fact about + the local nature on the hikes when making a recommendation. + """); +``` + +Add a user message to the chat history using the `AddUserMessage` function. Use the `GetChatMessageContentAsync` function to instruct the model to generate a response based off the system prompt and the user request. + +```csharp + +// Add user message to chat history +chatHistory.AddUserMessage("Hi! Apparently you can help me find a hike that I will like?"); + +// Print User Message to console +Console.WriteLine($"{chatHistory.Last().Role} >>> {chatHistory.Last().Content}"); + +// Get response +var response = await service.GetChatMessageContentAsync( + chatHistory, new OpenAIPromptExecutionSettings() { MaxTokens = 400 }); +``` + +Add the response from the mode to maintain the chat history. + +```csharp +// Add response to chat history +chatHistory.Add(response); + +// Print Response to console +Console.WriteLine($"{chatHistory.Last().Role} >>> {chatHistory.Last().Content}"); +``` + +Customize the system prompt and user message to see how the model responds to help you find a hike that you'll like. + + +:::zone target="docs" pivot="azure-openai" + +## Clean up resources + +Remove the corresponding deployment and all resources when you no longer need the sample application or resources. + +```azdeveloper +azd down +``` + +[!INCLUDE [troubleshoot](includes/troubleshoot.md)] + +:::zone-end + +## Next steps + +- [Quickstart - Get insight about your data from .NET AI chat app](quickstart-ai-chat-with-data.md) +- [Generate text and conversations with .NET and OpenAI Completions](/training/modules/open-ai-dotnet-text-completions/) diff --git a/docs/ai/quickstarts/includes/clone-sample-repo.md b/docs/ai/quickstarts/includes/clone-sample-repo.md new file mode 100644 index 0000000000000..33e028ab1342f --- /dev/null +++ b/docs/ai/quickstarts/includes/clone-sample-repo.md @@ -0,0 +1,12 @@ +--- +author: jmatthiesen +ms.author: jomatthi +ms.date: 07/03/2024 +ms.topic: include +--- + +A GitHub repository is available that contains the sample apps for all of the quickstarts. Clone the repository using the following command: + +```bash +git clone https://github.com/dotnet/ai-samples.git +``` diff --git a/docs/ai/quickstarts/includes/deploy-azd.md b/docs/ai/quickstarts/includes/deploy-azd.md new file mode 100644 index 0000000000000..f5877c1119422 --- /dev/null +++ b/docs/ai/quickstarts/includes/deploy-azd.md @@ -0,0 +1,21 @@ +--- +author: jmatthiesen +ms.author: jomatthi +ms.date: 07/03/2024 +ms.topic: include +--- + +## Deploy the Azure resources + +Ensure that you follow the [Prerequisites](#prerequisites) to have access to Azure OpenAI Service as well as the Azure Developer CLI, and then use the following guide to get started with the sample application. + +1. Clone the repository: [dotnet/ai-samples](https://github.com/dotnet/ai-samples) +1. From a terminal or command prompt, navigate to the _src\quickstarts\azure-openai_ directory (on macOS or Linux, replace the '\\' character with a '/'). +1. The following command provisions the Azure OpenAI resources. It might take several minutes to create the Azure OpenAI service and deploy the model. + + ```azdeveloper + azd up + ``` + + > [!NOTE] + > If you encounter an error during the `azd up` deployment, visit the [troubleshooting](#troubleshoot) section. diff --git a/docs/ai/quickstarts/includes/prerequisites-and-azure-deploy.md b/docs/ai/quickstarts/includes/prerequisites-and-azure-deploy.md deleted file mode 100644 index 55f922839195a..0000000000000 --- a/docs/ai/quickstarts/includes/prerequisites-and-azure-deploy.md +++ /dev/null @@ -1,58 +0,0 @@ ---- -author: fboucher -ms.author: frbouche -ms.date: 05/22/2024 -ms.topic: include ---- - -## Prerequisites - -- .NET 8.0 SDK - [Install the .NET 8.0 SDK](https://dotnet.microsoft.com/download/dotnet/8.0) -- An Azure subscription - [Create one for free](https://azure.microsoft.com/free) -- Azure Developer CLI - [Install or update the Azure Developer CLI](/azure/developer/azure-developer-cli/install-azd) -- Access to [Azure OpenAI service](/azure/ai-services/openai/overview#how-do-i-get-access-to-azure-openai). -- On Windows, PowerShell `v7+` is required. To validate your version, run `pwsh` in a terminal. It should returns the current version. If it returns an error, execute the following command: `dotnet tool update --global PowerShell`. - -## Deploy the Azure resources - -Ensure that you follow the [Prerequisites](#prerequisites) to have access to Azure OpenAI Service as well as the Azure Developer CLI, and then follow the following guide to set started with the sample application. - -1. Clone the repository: [dotnet/ai-samples](https://github.com/dotnet/ai-samples) -1. From a terminal or command prompt, navigate to the _quickstarts_ directory. -1. This provisions the Azure OpenAI resources. It may take several minutes to create the Azure OpenAI service and deploy the model. - - ```azdeveloper - azd up - ``` - -> [!NOTE] -> If you already have an Azure OpenAI service available, you can skip the deployment and use that value in the _Program.cs_, preferably from an `IConfiguration`. - -## Troubleshoot - -On Windows, you might get the following error messages after running `azd up`: - -> *postprovision.ps1 is not digitally signed. The script will not execute on the system* - -The script **postprovision.ps1** is executed to set the .NET user secrets used in the application. To avoid this error, run the following PowerShell command: - -```powershell -Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass -``` - -Then re-run the `azd up` command. - -Another possible error: - -> 'pwsh' is not recognized as an internal or external command, -> operable program or batch file. -> WARNING: 'postprovision' hook failed with exit code: '1', Path: '.\infra\post-script\postprovision.ps1'. : exit code: 1 -> Execution will continue since ContinueOnError has been set to true. - -The script **postprovision.ps1** is executed to set the .NET user secrets used in the application. To avoid this error, manually run the script using the following PowerShell command: - -```powershell -.\infra\post-script\postprovision.ps1 -``` - -The .NET AI apps now have the user-secrets configured and they can be tested. diff --git a/docs/ai/quickstarts/includes/prerequisites-azure-openai.md b/docs/ai/quickstarts/includes/prerequisites-azure-openai.md new file mode 100644 index 0000000000000..388d5b7d77926 --- /dev/null +++ b/docs/ai/quickstarts/includes/prerequisites-azure-openai.md @@ -0,0 +1,14 @@ +--- +author: fboucher +ms.author: frbouche +ms.date: 05/22/2024 +ms.topic: include +--- + +## Prerequisites + +- .NET 8 SDK - [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). +- Azure Developer CLI - [Install or update the Azure Developer CLI](/azure/developer/azure-developer-cli/install-azd). +- Access to [Azure OpenAI service](/azure/ai-services/openai/overview#how-do-i-get-access-to-azure-openai). +- 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/includes/prerequisites-openai.md b/docs/ai/quickstarts/includes/prerequisites-openai.md new file mode 100644 index 0000000000000..d3f9d5c0a1160 --- /dev/null +++ b/docs/ai/quickstarts/includes/prerequisites-openai.md @@ -0,0 +1,12 @@ +--- +author: jmatthiesen +ms.author: jomatthi +ms.date: 07/03/2024 +ms.topic: include +--- + +## Prerequisites + +- .NET 8.0 SDK - [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/includes/set-openai-secrets.md b/docs/ai/quickstarts/includes/set-openai-secrets.md new file mode 100644 index 0000000000000..9f4348ed8f339 --- /dev/null +++ b/docs/ai/quickstarts/includes/set-openai-secrets.md @@ -0,0 +1,13 @@ +--- +author: jmatthiesen +ms.author: jomatthi +ms.date: 07/03/2024 +ms.topic: include +--- + +Run the following commands to configure your OpenAI API key as a secret for the sample app: + +```bash +dotnet user-secrets init +dotnet user-secrets set OpenAIKey +``` diff --git a/docs/ai/quickstarts/includes/troubleshoot.md b/docs/ai/quickstarts/includes/troubleshoot.md new file mode 100644 index 0000000000000..e0c2f7c0119ec --- /dev/null +++ b/docs/ai/quickstarts/includes/troubleshoot.md @@ -0,0 +1,35 @@ +--- +author: jmatthiesen +ms.author: jomatthi +ms.date: 07/03/2024 +ms.topic: include +--- + +## Troubleshoot + +On Windows, you might get the following error messages after running `azd up`: + +> *postprovision.ps1 is not digitally signed. The script will not execute on the system* + +The script **postprovision.ps1** is executed to set the .NET user secrets used in the application. To avoid this error, run the following PowerShell command: + +```powershell +Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass +``` + +Then re-run the `azd up` command. + +Another possible error: + +> 'pwsh' is not recognized as an internal or external command, +> operable program or batch file. +> WARNING: 'postprovision' hook failed with exit code: '1', Path: '.\infra\post-script\postprovision.ps1'. : exit code: 1 +> Execution will continue since ContinueOnError has been set to true. + +The script **postprovision.ps1** is executed to set the .NET user secrets used in the application. To avoid this error, manually run the script using the following PowerShell command: + +```powershell +.\infra\post-script\postprovision.ps1 +``` + +The .NET AI apps now have the user secrets configured and they can be tested. diff --git a/docs/ai/quickstarts/quickstart-ai-chat-with-data.md b/docs/ai/quickstarts/quickstart-ai-chat-with-data.md index 3a38685e80b13..51a272c98ba91 100644 --- a/docs/ai/quickstarts/quickstart-ai-chat-with-data.md +++ b/docs/ai/quickstarts/quickstart-ai-chat-with-data.md @@ -1,65 +1,112 @@ --- -title: Quickstart - Get insight about your data from an .NET Azure AI chat app -description: Create a simple chat app using your data and Semantic Kernel or the .NET Azure OpenAI SDK. -ms.date: 03/04/2024 +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 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 Azure 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 development with OpenAI, I want deploy and use sample code and data to interact to learn from the sample code. --- -# Get insight about your data from an .NET Azure AI chat app +# Get insight about your data from a .NET AI chat app -:::zone target="docs" pivot="semantic-kernel" +:::zone target="docs" pivot="openai" -Get started with Semantic Kernel and the `gpt-35-turbo` model, from a simple .NET 8.0 console application. Use the AI model to get analytics and information about your previous hikes. It consists of a simple console application, running locally, that will read the file `hikes.md` and send request to an Azure OpenAI service deployed in your Azure subscription and provide the result in the console. Follow these steps to provision Azure OpenAI and learn how to use Semantic Kernel. +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 [download-alert](includes/prerequisites-openai.md)] :::zone-end -:::zone target="docs" pivot="azure-openai-sdk" +:::zone target="docs" pivot="azure-openai" -Get started with the .NET Azure OpenAI with a `gpt-35-turbo` model, from a simple .NET 8.0 console application. Use the AI model to get analytics and information about your previous hikes. It consists of a simple console application, running locally, that will read the file `hikes.md` and send request to an Azure OpenAI service deployed in your Azure subscription and provide the result in the console. Follow these steps to provision Azure OpenAI and learn how to use the .NET Azure OpenAI SDK. +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 [download-alert](includes/prerequisites-azure-openai.md)] :::zone-end -[!INCLUDE [download-alert](includes/prerequisites-and-azure-deploy.md)] +## Get the sample project -## Try "Chatting About My Previous Hikes" sample +[!INCLUDE [clone-sample-repo](includes/clone-sample-repo.md)] - -:::zone target="docs" pivot="semantic-kernel" +:::zone target="docs" pivot="azure-openai" -1. From a terminal or command prompt, navigate to the `semantic-kernel\03-ChattingAboutMyHikes` directory. +[!INCLUDE [deploy-azd](includes/deploy-azd.md)] :::zone-end -:::zone target="docs" pivot="azure-openai-sdk" +## Try the hiking chat sample + + +:::zone target="docs" pivot="openai" + +1. From a terminal or command prompt, navigate to the `openai\03-ChattingAboutMyHikes` directory. -1. From a terminal or command prompt, navigate to the `azure-openai-sdk\03-ChattingAboutMyHikes` directory. +1. Run the following commands to configure your OpenAI API key as a secret for the sample app: + + ```bash + dotnet user-secrets init + dotnet user-secrets set OpenAIKey + ``` + +1. Use the `dotnet run` command to run the app: + + ```dotnetcli + dotnet run + ``` :::zone-end -2. It's now time to try the console application. Type in the following to run the app: +:::zone target="docs" pivot="azure-openai" + +1. From a terminal or command prompt, navigate to the `azure-openai\02-HikerAI` directory. + +2. Use the `dotnet run` command to run the app: ```dotnetcli dotnet run ``` - If you get an error message the Azure OpenAI resources may not have finished deploying. Wait a couple of minutes and try again. + > [!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 + +## Explore the code + -:::zone target="docs" pivot="semantic-kernel" +:::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. -## Explore the code +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. + +```csharp +var config = new ConfigurationBuilder().AddUserSecrets().Build(); +string model = "gpt-3.5-turbo"; +string key = config["OpenAIKey"]; +``` + +The `OpenAIChatCompletionService` service facilitates the requests and responses. + +```csharp +// Create the OpenAI Chat Completion Service +OpenAIChatCompletionService service = new(model, key); +``` -Our application uses the `Microsoft.SemanticKernel` package, which is available on [NuGet](https://www.nuget.org/packages/Microsoft.SemanticKernel), to send and receive requests to an Azure OpenAI service deployed in Azure. +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" + +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. 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. @@ -78,7 +125,8 @@ The `AzureOpenAIChatCompletionService` service facilitates the requests and resp AzureOpenAIChatCompletionService service = new(deployment, endpoint, key); ``` -Once the `AzureOpenAIChatCompletionService` client is created, we read the content of the file `hikes.md` and use it to provide more context to the model by adding a system prompt. This instructs the model how you'd like it to act during the conversation. +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 ```csharp // Provide context for the AI model @@ -91,122 +139,50 @@ ChatHistory chatHistory = new($""" Console.WriteLine($"{chatHistory.Last().Role} >>> {chatHistory.Last().Content}"); ``` -Then you can add a user message to the model by using the `AddUserMessage` function. - -To have the model generate a response based off the system prompt and the user request, use the `GetChatMessageContentAsync` function. +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 })); +chatHistory.Add( + await service.GetChatMessageContentAsync( + chatHistory, + new OpenAIPromptExecutionSettings() + { + MaxTokens = 400 + })); Console.WriteLine($"{chatHistory.Last().Role} >>> {chatHistory.Last().Content}"); ``` -To maintain the chat history or context, make sure you add the response from the model to the `chatHistory`. It's time to make our user request about our data again using the `AddUserMessage` and `GetChatMessageContentAsync` function. +The app adds the response from the model to the `chatHistory` to maintain the chat history or context. ```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."); -Console.WriteLine($"{chatHistory.Last().Role} >>> {chatHistory.Last().Content}"); +chatHistory.AddUserMessage( + "I would like to know the ratio of the hikes I've done in Canada compared to other countries."); -chatHistory.Add(await service.GetChatMessageContentAsync(chatHistory, new OpenAIPromptExecutionSettings() { MaxTokens = 400 })); Console.WriteLine($"{chatHistory.Last().Role} >>> {chatHistory.Last().Content}"); -``` -Customize the system prompt and change the request, asking for different questions (ex: How many times did you hiked when it was raining? How many times did you hiked in 2021? etc.) to see how the model responds. - -:::zone-end +chatHistory.Add(await service.GetChatMessageContentAsync( + chatHistory, + new OpenAIPromptExecutionSettings() + { + MaxTokens = 400 + })); - -:::zone target="docs" pivot="azure-openai-sdk" - - -## Explore the code - -Our application uses the `Azure.AI.OpenAI` client SDK, which is available on [NuGet](https://www.nuget.org/packages/Azure.AI.OpenAI), to send and receive requests to an Azure OpenAI service deployed in Azure. - -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. - -```csharp -// == Retrieve the local secrets saved during the Azure deployment ========== -var config = new ConfigurationBuilder() - .AddUserSecrets() - .Build(); - -string openAIEndpoint = config["AZURE_OPENAI_ENDPOINT"]; -string openAIDeploymentName = config["AZURE_OPENAI_GPT_NAME"]; -string openAiKey = config["AZURE_OPENAI_KEY"]; - -// == Creating the AIClient ========== -var endpoint = new Uri(openAIEndpoint); -var credentials = new AzureKeyCredential(openAiKey); -``` - -The `OpenAIClient` class facilitates the requests and responses. `ChatCompletionOptions` specifies parameters of how the model will respond. - -```csharp -var openAIClient = new OpenAIClient(endpoint, credentials); - -var completionOptions = new ChatCompletionsOptions -{ - MaxTokens = 400, - Temperature = 1f, - FrequencyPenalty = 0.0f, - PresencePenalty = 0.0f, - NucleusSamplingFactor = 0.95f, // Top P - DeploymentName = openAIDeploymentName -}; -``` - -Once the `OpenAIClient` client is created, we read the content of the file `hikes.md` and use it to provide more context to the model by adding a system prompt. This instructs the model how you'd like it to act during the conversation. - -```csharp -var systemPrompt = -""" -You are upbeat and friendly. You introduce yourself when first saying hello. -Provide a short answer only based on the user hiking records below: - -""" + markdown; - -completionOptions.Messages.Add(new ChatRequestSystemMessage(systemPrompt)); -``` - -Then you can add a user message to the model by using the `ChatRequestUserMessage` class. - -To have the model generate a response based off the system prompt and the user request, use the `GetChatCompletionsAsync` function. - -```csharp -string userGreeting = """ -Hi! -"""; - -completionOptions.Messages.Add(new ChatRequestUserMessage(userGreeting)); -Console.WriteLine($"\n\nUser >>> {userGreeting}"); - -ChatCompletions response = await openAIClient.GetChatCompletionsAsync(completionOptions); -ChatResponseMessage assistantResponse = response.Choices[0].Message; -Console.WriteLine($"\n\nAI >>> {assistantResponse.Content}"); -completionOptions.Messages.Add(new ChatRequestAssisstantMessage(assistantResponse.Content)); +Console.WriteLine($"{chatHistory.Last().Role} >>> {chatHistory.Last().Content}"); ``` -To maintain the chat history or context, make sure you add the response from the model as a `ChatRequestAssistantMessage`. It's time to make our user request about our data again using the `ChatRequestUserMessage` and `GetChatCompletionsAsync` function. +Customize the system or user prompts to provide different questions and context: -```csharp -var hikeRequest = -""" -I would like to know the ration of hike I did in Canada compare to hikes done in other countries. -"""; - -Console.WriteLine($"\n\nUser >>> {hikeRequest}"); -completionOptions.Messages.Add(new ChatRequestUserMessage(hikeRequest)); -response = await openAIClient.GetChatCompletionsAsync(completionOptions); -``` +- How many times did I hike when it was raining? +- How many times did I hike in 2021? -Customize the system prompt and change the request, asking for different questions (ex: How many times did you hiked when it was raining? How many times did you hiked in 2021? etc.) to see how the model responds. +The model generates a relevant response to each prompt based on your inputs. -:::zone-end +:::zone target="docs" pivot="azure-openai" ## Clean up resources @@ -216,7 +192,11 @@ 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 Azure AI with .NET](quickstart-openai-generate-images.md) +- [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/) diff --git a/docs/ai/quickstarts/quickstart-azure-openai-tool.md b/docs/ai/quickstarts/quickstart-azure-openai-tool.md index 6baf877ff8ca0..ed2e71ac13fa2 100644 --- a/docs/ai/quickstarts/quickstart-azure-openai-tool.md +++ b/docs/ai/quickstarts/quickstart-azure-openai-tool.md @@ -1,66 +1,117 @@ --- -title: Quickstart - Extend Azure AI using Tools and execute a local Function with .NET -description: Create a simple chat app using Semantic Kernel or the .NET Azure OpenAI SDK and extend the model to execute a local function. -ms.date: 03/04/2024 +title: Quickstart - Extend OpenAI using Tools and execute a local Function with .NET +description: Create a simple chat app using OpenAI and extend the model to execute a local function. +ms.date: 07/14/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 Azure OpenAI, I want deploy and use sample code to interact to learn from the sample code how to extend the model using Tools. +# CustomerIntent: As a .NET developer new to OpenAI, I want deploy and use sample code to interact to learn from the sample code how to extend the model using Tools. --- -# Extend Azure AI using Tools and execute a local Function with .NET +# Extend OpenAI using Tools and execute a local Function with .NET -:::zone target="docs" pivot="semantic-kernel" +:::zone target="docs" pivot="openai" -Get started with Semantic Kernel by creating a simple .NET 8 console chat application. The application will run locally and use the OpenAI `gpt-35-turbo` model deployed into an Azure OpenAI account, however using Tool to extend the model capabilities it will call a local function. Follow these steps to provision Azure OpenAI and learn how to use Semantic Kernel. +Get started with AI by creating a simple .NET 8 console chat application. The application will run locally and use the OpenAI `gpt-3.5-turbo` model, using Tools to extend the model's capabilities by calling a local .NET method. Follow these steps to get access to OpenAI and learn how to use Semantic Kernel. + +[!INCLUDE [download-alert](includes/prerequisites-openai.md)] :::zone-end -:::zone target="docs" pivot="azure-openai-sdk" +:::zone target="docs" pivot="azure-openai" -Get started with the .NET Azure OpenAI SDK by creating a simple .NET 8 console chat application. The application will run locally and use the OpenAI `gpt-35-turbo` model deployed into an Azure OpenAI account, however using Tool to extend the model capabilities it will call a local function. Follow these steps to provision Azure OpenAI and learn how to use the .NET Azure OpenAI SDK. +Get started with AI by creating a simple .NET 8 console chat application. The application will run locally and use the OpenAI `gpt-35-turbo` model deployed into an Azure OpenAI account. It uses Tools to extend the model's capabilities by calling a local .NET method. Follow these steps to provision Azure OpenAI and learn how to use Semantic Kernel. + +[!INCLUDE [download-alert](includes/prerequisites-azure-openai.md)] :::zone-end -[!INCLUDE [download-alert](includes/prerequisites-and-azure-deploy.md)] +## Get the sample project -## Try HikerAI Pro sample +[!INCLUDE [clone-sample-repo](includes/clone-sample-repo.md)] - -:::zone target="docs" pivot="semantic-kernel" +:::zone target="docs" pivot="azure-openai" -1. From a terminal or command prompt, navigate to the `semantic-kernel\04-HikerAIPro` directory. +[!INCLUDE [deploy-azd](includes/deploy-azd.md)] :::zone-end -:::zone target="docs" pivot="azure-openai-sdk" +## Try the the hiker pro sample + + +:::zone target="docs" pivot="openai" + +1. From a terminal or command prompt, navigate to the `azure-openai\04-HikerAIPro` directory. + +1. Run the following commands to configure your OpenAI API key as a secret for the sample app: -1. From a terminal or command prompt, navigate to the `azure-openai-sdk\04-HikerAIPro` directory. + ```bash + dotnet user-secrets init + dotnet user-secrets set OpenAIKey + ``` + +1. Use the `dotnet run` command to run the app: + + ```dotnetcli + dotnet run + ``` :::zone-end -2. It's now time to try the console application. Type in the following to run the app: +:::zone target="docs" pivot="azure-openai" + +1. From a terminal or command prompt, navigate to the `azure-openai\04-HikerAIPro` directory. + +2. Use the `dotnet run` command to run the app: ```dotnetcli dotnet run ``` - If you get an error message the Azure OpenAI resources may not have finished deploying. Wait a couple of minutes and try again. + > [!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 +## Understand the code + -:::zone target="docs" pivot="semantic-kernel" - +:::zone target="docs" pivot="openai" -## Understand the code +The application uses the [`Microsoft.SemanticKernel`](https://www.nuget.org/packages/Microsoft.SemanticKernel) package to send and receive requests to the OpenAI service. + +The entire application is contained within the **Program.cs** file. The first several lines of code set configuration values and get the OpenAI Key that was previously set using the `dotnet user-secrets` command. + +```csharp +var config = new ConfigurationBuilder().AddUserSecrets().Build(); +string model = "gpt-3.5-turbo"; +string key = config["OpenAIKey"]; +``` + +The `Kernel` class facilitates the requests and responses with the help of `AddOpenAIChatCompletion` service. + +```csharp +// Create a Kernel containing the OpenAI Chat Completion Service +IKernelBuilder b = Kernel.CreateBuilder(); + +Kernel kernel = b + .AddOpenAIChatCompletion(model, key) + .Build(); +``` + +:::zone-end + +:::zone target="docs" pivot="azure-openai" + -Our application uses the `Microsoft.SemanticKernel` package, which is available on [NuGet](https://www.nuget.org/packages/Microsoft.SemanticKernel), to send and receive requests to an Azure OpenAI service deployed in Azure. +The application uses the [`Microsoft.SemanticKernel`](https://www.nuget.org/packages/Microsoft.SemanticKernel) package to send and receive requests to the OpenAI service. 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. @@ -71,7 +122,7 @@ string deployment = config["AZURE_OPENAI_GPT_NAME"]; string key = config["AZURE_OPENAI_KEY"]; ``` -The `Kernel` class facilitates the requests and responses with the help of `AddAzureOpenAIChatCompletion` service. +The `Kernel` class facilitates the requests and responses with the help of `AzureOpenAIChatCompletion` service. ```csharp // Create a Kernel containing the Azure OpenAI Chat Completion Service @@ -82,14 +133,17 @@ Kernel kernel = b .Build(); ``` -The function's `ImportPluginFromFunctions` and `CreateFromMethod` are used to define the local function that will be called by the model. +:::zone-end + +The functions `ImportPluginFromFunctions` and `CreateFromMethod` define the local function that will be called by the model. ```csharp // Add a new plugin with a local .NET function that should be available to the AI model // For convenience and clarity of into the code, this standalone local method handles tool call responses. It will fake a call to a weather API and return the current weather for the specified location. kernel.ImportPluginFromFunctions("WeatherPlugin", [ - KernelFunctionFactory.CreateFromMethod(([Description("The city, e.g. Montreal, Sidney")] string location, string unit = null) => + KernelFunctionFactory.CreateFromMethod( + ([Description("The city, e.g. Montreal, Sidney")] string location, string unit = null) => { // Here you would call a weather API to get the weather for the location return "Periods of rain or drizzle, 15 C"; @@ -97,204 +151,52 @@ kernel.ImportPluginFromFunctions("WeatherPlugin", ]); ``` -Once the `kernel` client is created, we provide more context to the model by adding a system prompt. This instructs the model how you'd like it to act during the conversation. Note how the weather is emphasized in the system prompt. +Once the `kernel` client is created, the code uses a system prompt to provide context and influence the completion tone and content. Note how the weather is emphasized in the system prompt. ```csharp ChatHistory chatHistory = new(""" - You are a hiking enthusiast who helps people discover fun hikes in their area. You are upbeat and friendly. - A good weather is important for a good hike. Only make recommendations if the weather is good or if people insist. - You introduce yourself when first saying hello. When helping people out, you always ask them - for this information to inform the hiking recommendation you provide: + You are a hiking enthusiast who helps people discover fun hikes in their area. + You are upbeat and friendly. Good weather is important for a good hike. + Only make recommendations if the weather is good or if people insist. + You introduce yourself when first saying hello. When helping people out, + you always ask them for this information to inform the hiking recommendation you provide: 1. Where they are located 2. What hiking intensity they are looking for - You will then provide three suggestions for nearby hikes that vary in length after you get that information. - You will also share an interesting fact about the local nature on the hikes when making a recommendation. + You will then provide three suggestions for nearby hikes that vary in length + after you get that information. You will also share an interesting fact about the local + nature on the hikes when making a recommendation. """); ``` -Then you can add a user message to the model by using the `AddUserMessage` functon. - -To have the model generate a response based off the system prompt and the user request, use the `GetChatMessageContentAsync` function. +The app also adds a user message to the model using the `AddUserMessage` function. The `GetChatMessageContentAsync` function sends the chat history to the model to generate a response based off the system and user prompts. ```csharp chatHistory.AddUserMessage(""" Is the weather is good today for a hike? - If yes, I live in the greater Montreal area and would like an easy hike. I don't mind driving a bit to get there. - I don't want the hike to be over 10 miles round trip. I'd consider a point-to-point hike. + If yes, I live in the greater Montreal area and would like an easy hike. + I don't mind driving a bit to get there. I don't want the hike to be over 10 miles round trip. + I'd consider a point-to-point hike. I want the hike to be as isolated as possible. I don't want to see many people. I would like it to be as bug free as possible. """); 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}"); -``` - -Customize the system prompt and user message to see how the model responds to help you find a hike that you'll like. - -:::zone-end - - -:::zone target="docs" pivot="azure-openai-sdk" - +chatHistory.Add(await service.GetChatMessageContentAsync( + chatHistory, + new OpenAIPromptExecutionSettings() + { + MaxTokens = 400 + })); -## Understand the code - -Our application uses the `Azure.AI.OpenAI` client SDK, which is available on [NuGet](https://www.nuget.org/packages/Azure.AI.OpenAI), to send and receive requests to an Azure OpenAI service deployed in Azure. - -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. - -```csharp -// == Retrieve the local secrets saved during the Azure deployment ========== -var config = new ConfigurationBuilder().AddUserSecrets().Build(); -string openAIEndpoint = config["AZURE_OPENAI_ENDPOINT"]; -string openAIDeploymentName = config["AZURE_OPENAI_GPT_NAME"]; -string openAiKey = config["AZURE_OPENAI_KEY"]; - -// == Creating the AIClient ========== -var endpoint = new Uri(openAIEndpoint); -var credentials = new AzureKeyCredential(openAiKey); -``` - -The `OpenAIClient` class facilitates the requests and responses. `ChatCompletionOptions` specifies parameters of how the model will respond. Note how the **Tools** property is used to add the definition. - -```csharp -var openAIClient = new OpenAIClient(endpoint, credentials); - -var completionOptions = new ChatCompletionsOptions -{ - MaxTokens = 400, - Temperature = 1f, - FrequencyPenalty = 0.0f, - PresencePenalty = 0.0f, - NucleusSamplingFactor = 0.95f, // Top P - DeploymentName = openAIDeploymentName, - Tools = { getWeather } -}; -``` - -The class `ChatCompletionsFunctionToolDefinition` is used to define the local function that will be called by the model. - -```csharp -var getWeather = new ChatCompletionsFunctionToolDefinition() -{ - Name = "get_current_weather", - Description = "Get the current weather in a given location", - Parameters = BinaryData.FromObjectAsJson( - new - { - Type = "object", - Properties = new - { - Location = new - { - Type = "string", - Description = "The city, e.g. Montreal, Sidney", - }, - Unit = new - { - Type = "string", - Enum = new[] { "celsius", "fahrenheit" }, - } - }, - Required = new[] { "location" }, - }, - new JsonSerializerOptions() { PropertyNamingPolicy = JsonNamingPolicy.CamelCase }), -}; -``` - -Once the `OpenAIClient` client is created, we provide more context to the model by adding a system prompt. This instructs the model how you'd like it to act during the conversation. Note how the weather is emphasized in the system prompt. - -```csharp -var systemPrompt = -""" -You are a hiking enthusiast who helps people discover fun hikes in their area. You are upbeat and friendly. -A good weather is important for a good hike. Only make recommendations if the weather is good or if people insist. -You introduce yourself when first saying hello. When helping people out, you always ask them -for this information to inform the hiking recommendation you provide: - -1. Where they are located -2. What hiking intensity they are looking for - -You will then provide three suggestions for nearby hikes that vary in length after you get that information. -You will also share an interesting fact about the local nature on the hikes when making a recommendation. -"""; - -completionOptions.Messages.Add(new ChatRequestSystemMessage(systemPrompt)); -``` - -Then you can add a user message to the model by using the `ChatRequestUserMessage` class. - -For convenience and clarity of into the code, this standalone local method handles tool call responses. It will fake a call to a weather API and return the current weather for the specified location. - -```csharp -ChatRequestToolMessage GetToolCallResponseMessage(ChatCompletionsToolCall toolCall) -{ - var functionToolCall = toolCall as ChatCompletionsFunctionToolCall; - if (functionToolCall?.Name == getWeather.Name) - { - string unvalidatedArguments = functionToolCall.Arguments; - var functionResultData = (object)null; - - // == Here call a weather API to get the weather for specified the location ========== - functionResultData = "Periods of rain or drizzle, 15 C"; - - return new ChatRequestToolMessage(functionResultData.ToString(), toolCall.Id); - } - else - { - throw new NotImplementedException(); - } -} -``` - -To have the model generate a response based off the system prompt and the user request, use the `GetChatCompletionsAsync` function. - -```csharp -string hikeRequest = """ -Is the weather is good today for a hike? -If yes, I live in the greater Montreal area and would like an easy hike. I don't mind driving a bit to get there. -I don't want the hike to be over 10 miles round trip. I'd consider a point-to-point hike. -I want the hike to be as isolated as possible. I don't want to see many people. -I would like it to be as bug free as possible. -"""; - -Console.WriteLine($"\n\nUser >>> {hikeRequest}"); -completionOptions.Messages.Add(new ChatRequestUserMessage(hikeRequest)); - -response = await openAIClient.GetChatCompletionsAsync(completionOptions); -``` - -Now, the response need to be examined. If the response includes `ToolCalls`, the method declare previously handle it and continue the conversation. It's important to note that each messages `ChatRequestAssistantMessage` are added to the conversation history. This is important to maintain the context of the conversation. - -```csharp -ChatChoice responseChoice = response.Choices[0]; -if (responseChoice.FinishReason == CompletionsFinishReason.ToolCalls) -{ - // == Include the FunctionCall message in the conversation history ========== - completionOptions.Messages.Add(new ChatRequestAssistantMessage(responseChoice.Message)); - - // == Add a new tool message for each tool call that is resolved ========== - foreach (ChatCompletionsToolCall toolCall in responseChoice.Message.ToolCalls) - { - var ToolCallMsg = GetToolCallResponseMessage(toolCall); - completionOptions.Messages.Add(ToolCallMsg); - } - - // == Retrieve the answer from HikeAI Pro ========== - response = await openAIClient.GetChatCompletionsAsync(completionOptions); -} - -assistantResponse = response.Choices[0].Message; -Console.WriteLine($"\n\nAssistant >>> {assistantResponse.Content}"); +Console.WriteLine($"{chatHistory.Last().Role} >>> {chatHistory.Last().Content}"); ``` Customize the system prompt and user message to see how the model responds to help you find a hike that you'll like. -:::zone-end +:::zone target="docs" pivot="azure-openai" ## Clean up resources @@ -304,7 +206,11 @@ 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 - Get insight about your data from an .NET Azure AI chat app](quickstart-ai-chat-with-data.md) +- [Quickstart - Get insight about your data from a .NET AI chat app](quickstart-ai-chat-with-data.md) - [Generate text and conversations with .NET and Azure OpenAI Completions](/training/modules/open-ai-dotnet-text-completions/) diff --git a/docs/ai/quickstarts/quickstart-openai-generate-images.md b/docs/ai/quickstarts/quickstart-openai-generate-images.md index 9beb85172068e..99ad604af92a6 100644 --- a/docs/ai/quickstarts/quickstart-openai-generate-images.md +++ b/docs/ai/quickstarts/quickstart-openai-generate-images.md @@ -1,7 +1,7 @@ --- -title: Quickstart - Generate images using Azure AI with .NET -description: Create a simple app using Semantic Kernel or the .NET Azure OpenAI SDK to generate postal card images. -ms.date: 03/04/2024 +title: Quickstart - Generate images using AI with .NET +description: Create a simple app using OpenAI to generate postal card images. +ms.date: 07/17/2024 ms.topic: quickstart ms.custom: devx-track-dotnet, devx-track-dotnet-ai author: fboucher @@ -10,168 +10,131 @@ zone_pivot_groups: openai-library # CustomerIntent: As a .NET developer new to Azure OpenAI, I want deploy and use sample code to interact to learn how to generate images from the sample code. --- -# Generate images using Azure AI with .NET +# Generate images using AI with .NET - -:::zone target="docs" pivot="semantic-kernel" - +:::zone target="docs" pivot="openai" -Get started with Semantic Kernel by creating a simple .NET 8 console chat application. The application will run locally and use the OpenAI `dell-e-3` model to generate postal card and invite your friends for a hike! Follow these steps to provision Azure OpenAI and learn how to use Semantic Kernel. +Get started with AI by creating a simple .NET 8 console chat application. The application will run locally and use the OpenAI `dall-e-3` model to generate postal card images so you can invite your friends for a hike! Follow these steps to get access to OpenAI and learn how to use Semantic Kernel. + +[!INCLUDE [download-alert](includes/prerequisites-openai.md)] :::zone-end - -:::zone target="docs" pivot="azure-openai-sdk" - +:::zone target="docs" pivot="azure-openai" + +Get started with AI by creating a simple .NET 8 console chat application. The application will run locally and use the OpenAI `dall-e-3` model to generate postal card images so you can invite your friends for a hike! Follow these steps to provision Azure OpenAI and learn how to use the .NET Azure OpenAI SDK. -Get started with the .NET Azure OpenAI SDK by creating a simple .NET 8 console chat application. The application will run locally and use the OpenAI `dell-e-3` model to generate postal card and invite your friends for a hike! Follow these steps to provision Azure OpenAI and learn how to use the .NET Azure OpenAI SDK. +[!INCLUDE [download-alert](includes/prerequisites-azure-openai.md)] :::zone-end -[!INCLUDE [download-alert](includes/prerequisites-and-azure-deploy.md)] +## Get the sample project -## Trying Generate Hiking Images sample +[!INCLUDE [clone-sample-repo](includes/clone-sample-repo.md)] - -:::zone target="docs" pivot="semantic-kernel" +:::zone target="docs" pivot="azure-openai" -1. From a terminal or command prompt, navigate to the `semantic-kernel\05-HikeImages` directory. +[!INCLUDE [deploy-azd](includes/deploy-azd.md)] :::zone-end -:::zone target="docs" pivot="azure-openai-sdk" +## Try the the hiking images sample -1. From a terminal or command prompt, navigate to the `azure-openai-sdk\05-HikeImages` directory. +:::zone target="docs" pivot="openai" -:::zone-end +1. Clone the repository: [dotnet/ai-samples](https://github.com/dotnet/ai-samples) -2. It's now time to try the console application. Type in the following to run the app: +1. Run the following commands to configure your OpenAI API key as a secret for the sample app: + + ```bash + dotnet user-secrets init + dotnet user-secrets set OpenAIKey + ``` + +1. Use the `dotnet run` command to run the app: ```dotnetcli dotnet run ``` - If you get an error message the Azure OpenAI resources may not have finished deploying. Wait a couple of minutes and try again. - +:::zone-end - -:::zone target="docs" pivot="semantic-kernel" - +:::zone target="docs" pivot="azure-openai" -## Understanding the code +1. From a terminal or command prompt, navigate to the `azure-openai\05-HikeImages` directory. -Our application uses the `Microsoft.SemanticKernel` package, which is available on [NuGet](https://www.nuget.org/packages/Microsoft.SemanticKernel), to send and receive requests to an Azure OpenAI service deployed in Azure. +2. Use the `dotnet run` command to run the app: -The entire application is contained within the _Program.cs_ file. The first several lines of code load secrets and configuration values that were set in the `dotnet user-secrets` for you during the application provisioning. + ```dotnetcli + dotnet run + ``` -```csharp -// == Retrieve the local secrets saved during the Azure deployment ========== -var config = new ConfigurationBuilder() - .AddUserSecrets() - .Build(); + > [!TIP] + > If you get an error message, the Azure OpenAI resources might not have finished deploying. Wait a couple of minutes and try again. -var config = new ConfigurationBuilder().AddUserSecrets().Build(); -string endpoint = config["AZURE_OPENAI_ENDPOINT"]; -string deployment = config["AZURE_OPENAI_GPT_NAME"]; -string key = config["AZURE_OPENAI_KEY"]; -``` +:::zone-end -The `AzureOpenAITextToImageService` service facilitates the requests and responses. +## Explore the code + +:::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 the OpenAI service. + +The _Program.cs_ file contains all of the app code. The first several lines of code set configuration values and get the OpenAI Key that was previously set using the `dotnet user-secrets` command. ```csharp -AzureOpenAITextToImageService textToImageService = new(deployment, endpoint, key, null); +var config = new ConfigurationBuilder().AddUserSecrets().Build(); +string key = config["OpenAIKey"]; ``` -Once the `textToImageService` service is created, we we provide more context to the model by adding a system prompt. A good prompt to generate images requires a clear description: what is in the images, specific color to use, style (drawing, painting, realistic or cartoony). The model will use this prompt to generate the image. To have the model generate a response based off the user request, use the `GenerateImageAsync` function, and specify the size and quality. +The `OpenAITextToImageService` service facilitates the requests and responses. ```csharp -// Generate the image -string imageUrl = await textToImageService.GenerateImageAsync(""" - A postal card with an happy hiker waving and a beautiful mountain in the background. - There is a trail visible in the foreground. - The postal card has text in red saying: 'You are invited for a hike!' - """, 1024, 1024); -Console.WriteLine($"The generated image is ready at:\n{imageUrl}"); +OpenAITextToImageService textToImageService = new(key, null); ``` -Customize the prompt to personalize the images generated by the model. - :::zone-end - -:::zone target="docs" pivot="azure-openai-sdk" - - -## Understanding the code +:::zone target="docs" pivot="azure-openai" -Our application uses the `Azure.AI.OpenAI` client SDK, which is available on [NuGet](https://www.nuget.org/packages/Azure.AI.OpenAI), to send and receive requests to an Azure OpenAI service deployed in Azure. +The application uses the [`Microsoft.SemanticKernel`](https://www.nuget.org/packages/Microsoft.SemanticKernel) package to send and receive requests to the Azure OpenAI service. -The entire application is contained within the _Program.cs_ file. The first several lines of code load secrets and configuration values that were set in the `dotnet user-secrets` for you during the application provisioning. +The _Program.cs_ file contains all of the app code. The first several lines of code load secrets and configuration values that were set in the `dotnet user-secrets` for you during the application provisioning. ```csharp -// == Retrieve the local secrets saved during the Azure deployment ========== -var config = new ConfigurationBuilder() - .AddUserSecrets() - .Build(); - -string openAIEndpoint = config["AZURE_OPENAI_ENDPOINT"]; -string openAIDeploymentName = config["AZURE_OPENAI_GPT_NAME"]; -string openAiKey = config["AZURE_OPENAI_KEY"]; - -// == Creating the AIClient ========== -var endpoint = new Uri(openAIEndpoint); -var credentials = new AzureKeyCredential(openAiKey); +// 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"]; +string key = config["AZURE_OPENAI_KEY"]; ``` -The `OpenAIClient` class facilitates the requests and responses. `ChatCompletionOptions` specifies parameters of how the model will respond. +The `AzureOpenAITextToImageService` service facilitates the requests and responses. ```csharp -var openAIClient = new OpenAIClient(endpoint, credentials); - -var completionOptions = new ChatCompletionsOptions -{ - MaxTokens = 400, - Temperature = 1f, - FrequencyPenalty = 0.0f, - PresencePenalty = 0.0f, - NucleusSamplingFactor = 0.95f, // Top P - DeploymentName = openAIDeploymentName -}; +AzureOpenAITextToImageService textToImageService = new(deployment, endpoint, key, null); ``` -Once the `OpenAIClient` client is created, we we provide more context to the model by adding a system prompt. A good prompt to generate images requires a clear description: what is in the images, specific color to use, style (drawing, painting, realistic or cartoony). The model will use this prompt to generate the image. +:::zone-end -```csharp -string imagePrompt = """ -A postal card with an happy hiker waving, there a beautiful mountain in the background. -There is a trail visible in the foreground. -The postal card has text in red saying: 'You are invited for a hike!' -"""; -``` +Provide context and instructions to the model by adding a system prompt. A good image generation prompt requires a clear description of what the image is, which colors to use, the intended style, and other descriptors. -To have the model generate a response based off the user request, use the `GetImageGenerationsAsync` function, and specify the size and quality. +The `GenerateImageAsync` function instructs the model to generate a response based on the user prompt and image size and quality configurations. ```csharp -Response response = await openAIClient.GetImageGenerationsAsync( - new ImageGenerationOptions() - { - DeploymentName = openAIDalleName, - Prompt = imagePrompt, - Size = ImageSize.Size1024x1024, - Quality = ImageGenerationQuality.Standard - }); - -ImageGenerationData generatedImage = response.Value.Data[0]; -if (!string.IsNullOrEmpty(generatedImage.RevisedPrompt)) -{ - Console.WriteLine($"\n\nInput prompt automatically revised to:\n {generatedImage.RevisedPrompt}"); -} -Console.WriteLine($"\n\nThe generated image is ready at:\n {generatedImage.Url.AbsoluteUri}"); +// Generate the image +string imageUrl = await textToImageService.GenerateImageAsync(""" + A postal card with a happy hiker waving and a beautiful mountain in the background. + There is a trail visible in the foreground. + The postal card has text in red saying: 'You are invited for a hike!' + """, 1024, 1024); + +Console.WriteLine($"The generated image is ready at:\n{imageUrl}"); ``` Customize the prompt to personalize the images generated by the model. -:::zone-end +:::zone target="docs" pivot="azure-openai" ## Clean up resources @@ -181,7 +144,11 @@ 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 - Summarize text using Azure AI chat app with .NET](quickstart-openai-summarize-text.md) +- [Quickstart - Summarize text using an AI chat app with .NET](quickstart-openai-summarize-text.md) - [Generate text and conversations with .NET and Azure OpenAI Completions](/training/modules/open-ai-dotnet-text-completions/) diff --git a/docs/ai/quickstarts/quickstart-openai-summarize-text.md b/docs/ai/quickstarts/quickstart-openai-summarize-text.md index c5ae5ed47117e..7bf23b7c76839 100644 --- a/docs/ai/quickstarts/quickstart-openai-summarize-text.md +++ b/docs/ai/quickstarts/quickstart-openai-summarize-text.md @@ -1,178 +1,156 @@ --- -title: Quickstart - Summarize text using Azure AI chat app with .NET -description: Create a simple chat app using Semantic Kernel or the .NET Azure OpenAI SDK to summarize a text. -ms.date: 03/04/2024 +title: Quickstart - Summarize text using an AI chat app with .NET +description: Create a simple chat app using OpenAI and the Semantic Kernel SDK to summarize a text. +ms.date: 07/17/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 Azure OpenAI, I want deploy and use sample code to interact to learn from the sample code to summarize text. +# CustomerIntent: As a .NET developer new to OpenAI, I want deploy and use sample code to interact to learn from the sample code to summarize text. --- -# Summarize text using Azure AI chat app with .NET +# Summarize text using AI chat app with .NET - -:::zone target="docs" pivot="semantic-kernel" - +:::zone target="docs" pivot="openai" -Get started with Semantic Kernel by creating a simple .NET 8 console chat application. The application will run locally and use the OpenAI `gpt-35-turbo` model deployed into an Azure OpenAI account. Follow these steps to provision Azure OpenAI and learn how to use Semantic Kernel. +Get started with AI by creating a simple .NET 8.0 console chat application to summarize text. The application runs locally and uses the OpenAI `gpt-3.5-turbo` model. Follow these steps to get access to OpenAI and learn how to use Semantic Kernel. + +[!INCLUDE [download-alert](includes/prerequisites-openai.md)] :::zone-end - -:::zone target="docs" pivot="azure-openai-sdk" - +:::zone target="docs" pivot="azure-openai" + +Get started with AI by creating a simple .NET 8.0 console chat application to summarize text. The app runs locally and connects to the OpenAI `gpt-35-turbo` model deployed into Azure OpenAI. Follow these steps to provision the Azure OpenAI service and learn how to use Semantic Kernel. -Get started with the .NET Azure OpenAI SDK by creating a simple .NET 8 console chat application. The application will run locally and use the OpenAI `gpt-35-turbo` model deployed into an Azure OpenAI account. Follow these steps to provision Azure OpenAI and learn how to use the .NET Azure OpenAI SDK. +[!INCLUDE [download-alert](includes/prerequisites-azure-openai.md)] :::zone-end -[!INCLUDE [download-alert](includes/prerequisites-and-azure-deploy.md)] +## Get the sample project -## Trying Hiking Benefits Summary sample +[!INCLUDE [clone-sample-repo](includes/clone-sample-repo.md)] - -:::zone target="docs" pivot="semantic-kernel" +:::zone target="docs" pivot="azure-openai" -1. From a terminal or command prompt, navigate to the `semantic-kernel\01-HikeBenefitsSummary` directory. +[!INCLUDE [deploy-azd](includes/deploy-azd.md)] :::zone-end -:::zone target="docs" pivot="azure-openai-sdk" +## Try the hiking benefits sample -1. From a terminal or command prompt, navigate to the `azure-openai-sdk\01-HikeBenefitsSummary` directory. +:::zone target="docs" pivot="openai" -:::zone-end +1. From a terminal or command prompt, navigate to the `openai\01-HikeBenefitsSummary` directory. -2. It's now time to try the console application. Type in the following to run the app: +1. Run the following commands to configure your OpenAI API key as a secret for the sample app: + + ```bash + dotnet user-secrets init + dotnet user-secrets set OpenAIKey + ``` + +1. Use the `dotnet run` command to run the app: ```dotnetcli dotnet run ``` - If you get an error message the Azure OpenAI resources may not have finished deploying. Wait a couple of minutes and try again. - +:::zone-end - -:::zone target="docs" pivot="semantic-kernel" - +:::zone target="docs" pivot="azure-openai" -## Understanding the code +1. From a terminal or command prompt, navigate to the `azure-openai\01-HikeBenefitsSummary` directory. -Our application uses the `Microsoft.SemanticKernel` package, which is available on [NuGet](https://www.nuget.org/packages/Microsoft.SemanticKernel), to send and receive requests to an Azure OpenAI service deployed in Azure. +2. Use the `dotnet run` command to run the app: -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. + ```dotnetcli + dotnet run + ``` -```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"]; -string key = config["AZURE_OPENAI_KEY"]; + > [!TIP] + > If you get an error message, the Azure OpenAI resources may not have finished deploying. Wait a couple of minutes and try again. -// Create a Kernel containing the Azure OpenAI Chat Completion Service -Kernel kernel = Kernel.CreateBuilder() - .AddAzureOpenAIChatCompletion(deployment, endpoint, key) - .Build(); -``` +:::zone-end -The `Kernel` class facilitates the requests and responses with the help of `AddAzureOpenAIChatCompletion` service. +## Explore the code -```csharp -Kernel kernel = Kernel.CreateBuilder() - .AddAzureOpenAIChatCompletion(deployment, endpoint, key) - .Build(); -``` +:::zone target="docs" pivot="openai" + +The app uses the [`Microsoft.SemanticKernel`](https://www.nuget.org/packages/Microsoft.SemanticKernel) package to send and receive requests to the OpenAI service. -Once the `Kernel` is created, we read the contents of the file `benefits.md` and create a `prompt` to ask the the model to summarize that text. +The **Program.cs** file contains all of the app code. The first several lines of code set configuration values and get the OpenAI Key that was previously set using the `dotnet user-secrets` command. ```csharp -// Create and print out the prompt -string prompt = $""" - Please summarize the the following text in 20 words or less: - {File.ReadAllText("benefits.md")} - """; -Console.WriteLine($"user >>> {prompt}"); +var config = new ConfigurationBuilder().AddUserSecrets().Build(); +string model = "gpt-3.5-turbo"; +string key = config["OpenAIKey"]; ``` -To have the model generate a response based off `prompt`, use the `InvokePromptAsync` function. +The `Kernel` class facilitates the requests and responses and registers an `OpenAIChatCompletion` service. ```csharp -// Submit the prompt and print out the response -string response = await kernel.InvokePromptAsync(prompt, new(new OpenAIPromptExecutionSettings() { MaxTokens = 400 })); -Console.WriteLine($"assistant >>> {response}"); +// Create a Kernel containing the OpenAI Chat Completion Service +Kernel kernel = Kernel.CreateBuilder() + .AddOpenAIChatCompletion(model, key) + .Build(); ``` -Customize the text content of the file or the length of the summary to see the differences in the responses. - :::zone-end - -:::zone target="docs" pivot="azure-openai-sdk" - - -## Understanding the code +:::zone target="docs" pivot="azure-openai" +The application uses the [`Microsoft.SemanticKernel`](https://www.nuget.org/packages/Microsoft.SemanticKernel) package to send and receive requests to the Azure OpenAI service. -Our application uses the `Azure.AI.OpenAI` client SDK, which is available on [NuGet](https://www.nuget.org/packages/Azure.AI.OpenAI), to send and receive requests to an Azure OpenAI service deployed in Azure. - -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. +The **Program.cs** file contains all of the app code. The first several lines of code load secrets and configuration values that were set in the `dotnet user-secrets` for you during the application provisioning. ```csharp -// == Retrieve the local secrets saved during the Azure deployment ========== -var config = new ConfigurationBuilder() - .AddUserSecrets() - .Build(); - -string openAIEndpoint = config["AZURE_OPENAI_ENDPOINT"]; -string openAIDeploymentName = config["AZURE_OPENAI_GPT_NAME"]; -string openAiKey = config["AZURE_OPENAI_KEY"]; - -// == Creating the AIClient ========== -var endpoint = new Uri(openAIEndpoint); -var credentials = new AzureKeyCredential(openAiKey); +// 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"]; +string key = config["AZURE_OPENAI_KEY"]; ``` -The `OpenAIClient` class facilitates the requests and responses. `ChatCompletionOptions` specifies parameters of how the model will respond. +The `Kernel` class facilitates the requests and responses and registers an `OpenAIChatCompletion` service. ```csharp -var openAIClient = new OpenAIClient(endpoint, credentials); - -var completionOptions = new ChatCompletionsOptions -{ - MaxTokens = 400, - Temperature = 1f, - FrequencyPenalty = 0.0f, - PresencePenalty = 0.0f, - NucleusSamplingFactor = 0.95f, // Top P - DeploymentName = openAIDeploymentName -}; +// Create a Kernel containing the Azure OpenAI Chat Completion Service +Kernel kernel = Kernel.CreateBuilder() + .AddAzureOpenAIChatCompletion(deployment, endpoint, key) + .Build(); ``` -Once the `OpenAIClient` client is created, we read the content of the file `benefits.md`. Then using the `ChatRequestUserMessage` class we can add to the model the request to summarize that text. +:::zone-end + +Once the `Kernel` is created, the app code reads the `benefits.md` file content and uses it to create a `prompt` for model. The prompt instructs the model to summarize the file text content. ```csharp -string userRequest = """ -Please summarize the the following text in 20 words or less: -""" + markdown; - -completionOptions.Messages.Add(new ChatRequestUserMessage(userRequest)); -Console.WriteLine($"\n\nUser >>> {userRequest}"); +// Create and print out the prompt +string prompt = $""" + Please summarize the the following text in 20 words or less: + {File.ReadAllText("benefits.md")} + """; +Console.WriteLine($"user >>> {prompt}"); ``` -To have the model generate a response based off the user request, use the `GetChatCompletionsAsync` function. +The `InvokePromptAsync` function sends the `prompt` to the model to generate a response. ```csharp -ChatCompletions response = await openAIClient.GetChatCompletionsAsync(completionOptions); -ChatResponseMessage assistantResponse = response.Choices[0].Message; -Console.WriteLine($"\n\nAssistant >>> {assistantResponse.Content}"); +// Submit the prompt and print out the response +string response = await kernel.InvokePromptAsync( + prompt, + new(new OpenAIPromptExecutionSettings() + { + MaxTokens = 400 + }) + ); +Console.WriteLine($"assistant >>> {response}"); ``` Customize the text content of the file or the length of the summary to see the differences in the responses. -:::zone-end +:::zone target="docs" pivot="azure-openai" ## Clean up resources @@ -182,7 +160,11 @@ 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 - Build an Azure AI chat app with .NET](get-started-azure-openai.md) +- [Quickstart - Build an AI chat app with .NET](get-started-openai.md) - [Generate text and conversations with .NET and Azure OpenAI Completions](/training/modules/open-ai-dotnet-text-completions/) diff --git a/docs/ai/toc.yml b/docs/ai/toc.yml index 3716479974d6a..97d537f320ef9 100644 --- a/docs/ai/toc.yml +++ b/docs/ai/toc.yml @@ -14,7 +14,7 @@ items: - name: Summarize text href: quickstarts/quickstart-openai-summarize-text.md - name: Build a chat app - href: quickstarts/get-started-azure-openai.md + href: quickstarts/get-started-openai.md - name: Create an app to chat about your data href: quickstarts/quickstart-ai-chat-with-data.md - name: Execute a local .NET function diff --git a/docs/azure/index.yml b/docs/azure/index.yml index 5a9c4be3a605d..0c7c521048a1a 100644 --- a/docs/azure/index.yml +++ b/docs/azure/index.yml @@ -99,7 +99,7 @@ conceptualContent: url: ../ai/get-started/dotnet-ai-overview.md text: AI for .NET overview - itemType: quickstart - url: ../ai/quickstarts/get-started-azure-openai.md + url: ../ai/quickstarts/get-started-openai.md text: Build a chat app - itemType: quickstart text: Generate images diff --git a/docs/index.yml b/docs/index.yml index f6bfe477a8b0c..06c62445fbfef 100644 --- a/docs/index.yml +++ b/docs/index.yml @@ -323,7 +323,7 @@ additionalContent: links: - url: ai/index.yml text: AI for .NET developers - - url: ai/quickstarts/get-started-azure-openai.md + - url: ai/quickstarts/get-started-openai.md text: Build a chat app - url: ai/conceptual/prompt-engineering-dotnet.md text: Understand prompt engineering diff --git a/docs/zone-pivot-groups.yml b/docs/zone-pivot-groups.yml index ee5a06569354a..1480c03def97d 100644 --- a/docs/zone-pivot-groups.yml +++ b/docs/zone-pivot-groups.yml @@ -140,9 +140,9 @@ groups: title: "Other" - id: openai-library title: OpenAI Library - prompt: Choose a library for OpenAI + prompt: Choose a host service for OpenAI pivots: - - id: semantic-kernel - title: Semantic Kernel - - id: azure-openai-sdk - title: Azure OpenAI SDK + - id: openai + title: OpenAI + - id: azure-openai + title: Azure OpenAI