.NET을 사용하여 Azure AI 채팅 앱 빌드
간단한 .NET 8 콘솔 채팅 애플리케이션을 만들어 의미 체계 커널을 시작합니다. 애플리케이션은 로컬로 실행되며 Azure OpenAI 계정에 배포된 OpenAI gpt-35-turbo
모델을 사용합니다. 다음 단계에 따라 Azure OpenAI를 프로비전하고 의미 체계 커널을 사용하는 방법을 알아봅니다.
간단한 .NET 8 콘솔 채팅 애플리케이션을 만들어 .NET Azure OpenAI SDK를 시작합니다. 애플리케이션은 로컬로 실행되며 Azure OpenAI 계정에 배포된 OpenAI gpt-35-turbo
모델을 사용합니다. 다음 단계에 따라 Azure OpenAI를 프로비전하고 .NET Azure OpenAI SDK를 사용하는 방법을 알아봅니다.
필수 조건
- .NET 8.0 SDK - .NET 8.0 SDK 설치
- Azure 구독 - 체험 구독 만들기
- Azure Developer CLI - Azure Developer CLI 설치 또는 업데이트
- Azure OpenAI 서비스에 액세스합니다.
- Windows에서는 PowerShell
v7+
이 필요합니다. 버전의 유효성을 검사하려면 터미널에서pwsh
를 실행합니다. 현재 버전을 반환해야 합니다. 오류가 반환되면 다음 명령을 실행합니다.dotnet tool update --global PowerShell
.
Azure 리소스 배포
Azure OpenAI Service와 Azure Developer CLI에 액세스하려면 필수 조건을 따르고 다음 가이드에 따라 샘플 애플리케이션을 시작하도록 설정합니다.
리포지토리 복제: dotnet/ai-samples
터미널이나 명령 프롬프트에서 quickstarts 디렉터리로 이동합니다.
그러면 Azure OpenAI 리소스가 프로비전됩니다. Azure OpenAI 서비스를 만들고 모델을 배포하는 데 몇 분 정도 걸릴 수 있습니다.
azd up
참고 항목
사용 가능한 Azure OpenAI 서비스가 이미 있는 경우 배포를 건너뛰고 Program.cs(IConfiguration
권장)에서 해당 값을 사용할 수 있습니다.
문제 해결
Windows에서는 azd up
을 실행한 후 다음과 같은 오류 메시지가 나타날 수 있습니다.
postprovision.ps1은 디지털 서명되지 않았습니다. 스크립트가 시스템에서 실행되지 않습니다.
애플리케이션에 사용되는 .NET 사용자 비밀을 설정하기 위해 postprovision.ps1 스크립트가 실행됩니다. 이 오류를 방지하려면 다음 PowerShell 명령을 실행합니다.
Set-ExecutionPolicy -Scope Process -ExecutionPolicy Bypass
그런 다음 azd up
명령을 다시 실행합니다.
발생할 수 있는 다른 오류:
'pwsh'가 내부 또는 외부 명령, 실행 가능한 프로그램 또는 배치 파일로 인식되지 않습니다. 경고: 종료 코드: '1', 경로: '.\infra\post-script\postprovision.ps1'으로 인해 'postprovision' 후크가 실패했습니다. : 종료 코드: 1 ContinueOnError가 true로 설정되었으므로 실행이 계속됩니다.
애플리케이션에 사용되는 .NET 사용자 비밀을 설정하기 위해 postprovision.ps1 스크립트가 실행됩니다. 이 오류를 방지하려면 다음 PowerShell 명령을 사용하여 스크립트를 수동으로 실행합니다.
.\infra\post-script\postprovision.ps1
이제 .NET AI 앱에 사용자 비밀이 구성되어 테스트할 수 있습니다.
HikerAI 샘플 체험
- 터미널이나 명령 프롬프트에서
semantic-kernel\02-HikerAI
디렉터리로 이동합니다.
- 터미널이나 명령 프롬프트에서
azure-openai-sdk\02-HikerAI
디렉터리로 이동합니다.
이제 콘솔 애플리케이션을 사용해 볼 차례입니다. 앱을 실행하려면 다음을 입력합니다.
dotnet run
오류 메시지가 표시되면 Azure OpenAI 리소스 배포가 완료되지 않았을 수 있습니다. 몇 분 정도 기다렸다가 다시 시도해 보세요.
코드 이해
애플리케이션은 NuGet에서 사용할 수 있는 Microsoft.SemanticKernel
패키지를 사용하여 Azure에 배포된 Azure OpenAI 서비스에 요청을 보내고 가져옵니다.
전체 애플리케이션은 Program.cs 파일에 포함되어 있습니다. 코드의 처음 몇 줄은 애플리케이션 프로비전 중에 dotnet user-secrets
에 설정된 비밀 및 구성 값을 로드합니다.
// == Retrieve the local secrets saved during the Azure deployment ==========
var config = new ConfigurationBuilder().AddUserSecrets<Program>().Build();
string endpoint = config["AZURE_OPENAI_ENDPOINT"];
string deployment = config["AZURE_OPENAI_GPT_NAME"];
string key = config["AZURE_OPENAI_KEY"];
AzureOpenAIChatCompletionService
서비스는 요청과 응답을 편리하게 수행할 수 있습니다.
// == Create the Azure OpenAI Chat Completion Service ==========
AzureOpenAIChatCompletionService service = new(deployment, endpoint, key);
AzureOpenAIChatCompletionService
서비스가 만들어지면 시스템 프롬프트를 추가하여 모델에 더 많은 컨텍스트를 제공합니다. 이렇게 하면 대화 중에 모델이 어떻게 행동하기를 원하는지 모델에 지시할 수 있습니다.
// 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.
""");
그런 다음 AddUserMessage
함수를 사용하여 모델에 사용자 메시지를 추가할 수 있습니다.
모델이 시스템 프롬프트와 사용자 요청을 기반으로 응답을 생성하도록 하려면 GetChatMessageContentAsync
함수를 사용합니다.
// 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 response to chat history
chatHistory.Add(response);
// Print Response to console
Console.WriteLine($"{chatHistory.Last().Role} >>> {chatHistory.Last().Content}");
시스템 프롬프트와 사용자 메시지를 사용자 지정하여 원하는 하이킹 코스를 찾을 수 있도록 모델이 어떻게 반응하는지 확인합니다.
코드 이해
애플리케이션은 NuGet에서 사용할 수 있는 Azure.AI.OpenAI
클라이언트 SDK를 사용하여 Azure에 배포된 Azure OpenAI 서비스에 요청을 보내고 가져옵니다.
전체 애플리케이션은 Program.cs 파일에 포함되어 있습니다. 코드의 처음 몇 줄은 애플리케이션 프로비전 중에 dotnet user-secrets
에 설정된 비밀 및 구성 값을 로드합니다.
// == Retrieve the local secrets saved during the Azure deployment ==========
var config = new ConfigurationBuilder().AddUserSecrets<Program>().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);
OpenAIClient
클래스는 요청과 응답을 편리하게 수행할 수 있습니다. ChatCompletionOptions
는 모델이 응답하는 방식에 대한 매개 변수를 지정합니다.
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
};
OpenAIClient
클라이언트가 만들어지면 시스템 프롬프트를 추가하여 모델에 더 많은 컨텍스트를 제공합니다. 이렇게 하면 대화 중에 모델이 어떻게 행동하기를 원하는지 모델에 지시할 수 있습니다.
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));
그런 다음 ChatRequestUserMessage
클래스를 사용하여 모델에 사용자 메시지를 추가할 수 있습니다.
모델이 시스템 프롬프트와 사용자 요청을 기반으로 응답을 생성하도록 하려면 GetChatCompletionsAsync
함수를 사용합니다.
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));
채팅 기록 또는 컨텍스트를 유지하려면 모델의 응답을 ChatRequestAssistantMessage
로 추가해야 합니다.
시스템 프롬프트와 사용자 메시지를 사용자 지정하여 원하는 하이킹 코스를 찾을 수 있도록 모델이 어떻게 반응하는지 확인합니다.
리소스 정리
샘플 애플리케이션이나 리소스가 더 이상 필요하지 않으면 해당 배포와 모든 리소스를 제거합니다.
azd down
다음 단계
.NET
피드백
https://aka.ms/ContentUserFeedback
출시 예정: 2024년 내내 콘텐츠에 대한 피드백 메커니즘으로 GitHub 문제를 단계적으로 폐지하고 이를 새로운 피드백 시스템으로 바꿀 예정입니다. 자세한 내용은 다음을 참조하세요.다음에 대한 사용자 의견 제출 및 보기