Microsoft.Extensions.AI를 사용하여 C#에서 Azure OpenAI 모델 호출하기
AI는 개발자가 자신의 애플리케이션 내에서 그 기능을 사용할 수 있는 많은 흥미로운 가능성을 열어주지만, 막상 시작하면 다소 부담스럽게 느껴질 수 있습니다. 어떤 모델을 사용하고 어떻게 상호 작용하는 것이 가장 좋은지에 대해 많은 선택지가 있습니다.
이 게시물에서는 프로세스를 간소화하는 것을 목표로 하는 새로운 Microsoft.Extensions.AI NuGet 패키지를 활용하여 C#을 사용하여 Azure에서 호스팅되는 LLM과의 기본 채팅을 구현하는 단계를 살펴보고자 합니다.
여기에 유용한 튜토리얼이 있지만 그 과정에서 몇 가지 권한 관련 문제가 발생했기 때문에 제가 직접 작동하는 방법을 문서화하기로 했습니다.
1단계 - Azure 개방형 AI 모델 배포 만들기
우선 Azure에서 AI 모델 '배포’를 만들어야 합니다. 이 작업은 Azure 포털에서 매우 간단하게 수행할 수 있습니다.
먼저 “Azure OpenAI 서비스” 리소스를 만든 다음, 그 안에 “배포” 모델을 만들어야 합니다. 선택할 수 있는 모델이 여러 가지가 있고 AI를 처음 사용하는 경우 어떤 모델이 가장 적합한지 결정하는 방법이 전혀 명확하지 않기 때문에 가장 먼저 혼란스러워지는 지점 중 하나입니다. 기본적으로 비용, 성능 및 기능을 비교해야 하며, 이 튜토리얼에서는 gpt-4o-mini가 좋은 선택이 될 것입니다.
https://my-openai.openai.azure.com/
같은 오픈 AI 서비스 엔드포인트와 배포 이름(예: “my-gpt-4o-mini”)을 기록해 두어야 합니다.
2단계 - 모델 사용에 필요한 권한을 부여합니다.
인증을 위해 EntraID를 사용하려면 모델 배포를 사용하는 데 필요한 권한을 부여해야 합니다. 이 작업은 OpenAI 서비스 포털의 “액세스 제어(IAM)” 섹션으로 이동하여 사용자에게 Cognitive Services OpenAI Contributor 역할 할당을 추가하면 됩니다(저는 원래 “Cognitive Services OpenAI User” 역할을 시도했지만 그 이유는 확실하지 않지만 충분하지 않은 것 같았습니다).
3단계 - C#에서 모델 호출
C# 콘솔 앱에서 다음 패키지의 최신 버전에 대한 참조를 추가합니다:
<PackageReference Include="Microsoft.Extensions.AI.OpenAI" Version="9.0.1-preview.1.24570.5" />
<PackageReference Include="Azure.AI.OpenAI" Version="2.1.0" />
<PackageReference Include="Azure.Identity" Version="1.13.1" />
그런 다음 실제로 Azure OpenAI 서비스에 연결하기 위해 DefaultAzureCredential
을 사용할 수 있습니다. 리소스가 어느 테넌트에 있는지 명시적으로 지정해야 하는 경우가 많으므로 DefaultAzureCredentialOptions
를 사용하여 이를 수행하는 방법을 보여드렸습니다. 이 자격 증명이 작동하려면 az login
을 사용하여 Azure CLI로 Azure에 로그인해야 할 수도 있습니다.
var endpoint = "https://my-openai.openai.azure.com/";
var modelId = "my-gpt-4o-mini"; // this is the deployment name
var credential = new DefaultAzureCredential(new DefaultAzureCredentialOptions() {
TenantId = "123e4567-e89b-12d3-a456-426614174000" });
IChatClient client =
new AzureOpenAIClient(
new Uri(endpoint),
credential)
.AsChatClient(modelId);
이제 채팅 클라이언트에 질문을 제출하는 것이 매우 간단해졌습니다:
var response = await client.CompleteAsync("Should I learn about AI in 2025?");
Console.WriteLine(response.Message);
AI가 뭐라고 대답했는지 여러분께 맡기겠습니다!
키 기반 인증 사용
키 기반 인증을 사용하려는 경우 Azure 포털에서 OpenAI 서비스의 키에 액세스할 수 있습니다. 프로젝트 폴더에서 다음 명령을 실행하여 설정할 수 있는 닷넷 시크릿을 사용하면 로컬 개발에서 키를 사용할 수 있는 좋은 방법이 될 수 있습니다.
dotnet user-secrets init
dotnet user-secrets set "AzureOpenAI:ApiKey" "your-api-key-here"
dotnet add package Microsoft.Extensions.Configuration
dotnet add package Microsoft.Extensions.Configuration.UserSecrets
dotnet add package Microsoft.Extensions.Configuration.EnvironmentVariables
그런 다음 Program.cs
파일에서 구성에서 비밀 번호를 가져와서 이를 사용하여 ApiKeyCredential
을 만들 수 있습니다.
var builder = new ConfigurationBuilder()
.AddUserSecrets<Program>()
.AddEnvironmentVariables();
var configuration = builder.Build();
var apiKey = configuration["AzureOpenAI:ApiKey"];
var apiKeyCredential = new ApiKeyCredential(apiKey);
그러면 DefaultAzureCredential
대신 사용할 수 있으며, 관리되는 ID를 사용할 수 없는 곳에서 애플리케이션을 실행해야 하는 경우 유용합니다.
시스템 프롬프트 및 채팅 기록
마지막으로 이 튜토리얼에서는 모델과 완전한 대화를 나눌 수 있기를 원할 수 있으며, 모델이 수행하려는 작업과 질문에 어떻게 응답해야 하는지에 대한 지침을 모델에 제공할 수 있는 “시스템” 프롬프트도 변경하고 싶을 것입니다.
이는 사용자의 모든 메시지와 함께 시스템 프롬프트가 포함된 ChatMessage
개체 모음을 구축함으로써 이루어지며, 진행 중인 대화의 맥락에서 중요한 부분을 형성하므로 모델 자체에서 생성된 응답 개체도 포함되어야 합니다.
여기서는 시스템 프롬프트와 함께 채팅 기록 메시지 목록을 초기화하고 있습니다.
List<ChatMessage> chatHistory = new()
{
new ChatMessage(ChatRole.System, """
You are an enthusiastic Arsenal supporter.
""")
};
이제 루프에서 사용자의 콘솔 입력에서 새 ChatRole.User
메시지를 생성하고 이 모든 것을 CompleteStreamingAsync
로 전달하여 모델이 반환하는 출력을 인쇄할 수 있도록 합니다. 이렇게 하면 모델이 생성되는 동안 사용자가 모델의 응답을 읽을 수 있으므로 체감 응답성이 향상됩니다.
마지막으로, 다시 반복하기 전에 전체 응답을 ChatRole.Assistant
메시지로 채팅 기록 목록에 넣습니다.
while (true)
{
// Get user prompt and add to chat history
Console.WriteLine("Your prompt:");
var userPrompt = Console.ReadLine();
chatHistory.Add(new ChatMessage(ChatRole.User, userPrompt));
// Stream the AI response and add to chat history
Console.WriteLine("AI Response:");
var response = "";
await foreach (var item in
chatClient.CompleteStreamingAsync(chatHistory))
{
Console.Write(item.Text);
response += item.Text;
}
chatHistory.Add(new ChatMessage(ChatRole.Assistant, response));
Console.WriteLine();
}
이를 테스트해 보면 실제로 시스템 프롬프트를 고려한다는 것을 알 수 있습니다.
당신의 프롬프트:
최고의 스트라이커는 누구인가요?
AI 응답:
아스널 서포터로서 최고의 스트라이커에 대해 이야기할 때 티에리 앙리에게 특별한 고개를 끄덕일 수밖에 없습니다! 기술, 속도, 골 결정력을 겸비한 그는 아스널의 전설이 되었죠. 아스널에서 200골 이상을 넣었고 두 번의 프리미어 리그 우승과 클럽 역대 최다 득점자 등 수많은 찬사를 받으며 아스널과 프리미어 리그 전체에 지울 수 없는 흔적을 남겼습니다. 하지만 의견은 다양할 수 있으며 펠레, 디에고 마라도나, 최근에는 리오넬 메시와 크리스티아누 호날두 같은 선수들도 자주 거론됩니다. 하지만 저는 헨리가 항상 최고라고 생각합니다! 여러분은 어떻게 생각하시나요?
요약
물론 이것은 C#에서 프로그래밍 방식으로 AI 모델을 호출하는 첫 단계에 불과하지만, Microsoft.AI.Extensions의 가장 큰 장점은 OpenAI의 자체 API를 사용하거나 로컬 모델을 실행하는 등 다양한 AI 서비스와 통합하도록 설계되었다는 점입니다. 현재로서는 Anthropic Claude나 Google Gemini와 같은 다른 주요 AI 모델에 대한 지원이 없는 것 같지만 조만간 지원될 것으로 예상합니다.
라이브러리의 몇 가지 기능을 더 실험하고 있으므로 조만간 다른 결과도 공유할 수 있기를 기대합니다. 댓글을 통해 AI 서비스용 API를 사용하여 어떤 것을 구축했는지 듣고 싶습니다.