본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 23. 03:20

ASP.NET Core를 사용하여 보안이 강화된 AI 채팅 API 구축하기: 오늘은 로컬 Mock, 내일은 Azure OpenAI 준비 완료

요약

ASP.NET Core를 사용하여 보안이 강화된 AI 채팅 API를 구축하는 방법을 다룹니다. 인터페이스 기반 설계를 통해 로컬 Mock 서비스와 Azure OpenAI를 유연하게 교체할 수 있는 클린 아키텍처 구현 방법을 제시합니다.

핵심 포인트

  • 보안을 위해 AI 서비스를 백엔드 API 뒤에 배치해야 함
  • 인터페이스 기반 설계를 통해 AI 제공업체 결합도를 낮춤
  • Azure OpenAI 할당량 문제에 대비한 Mock 서비스 활용법
  • 클린 아키텍처를 적용한 확장 가능한 AI 서비스 레이어 구축

서론 (Introduction)

이전 기사에서는 .NET으로 AI 애플리케이션을 구축하기 위한 실질적인 로드맵에 대해 논의했습니다. 우리는 ASP.NET Core, Azure OpenAI, Semantic Kernel, Microsoft.Extensions.AI, Azure AI Search, RAG, 에이전트 (agents), 그리고 책임감 있는 AI (Responsible AI)가 기업용 AI 애플리케이션 개발에 어떻게 적용되는지 다루었습니다.

이번 기사에서는 로드맵에서 구현 단계로 넘어가겠습니다.

우리는 ASP.NET Core를 사용하여 보안이 강화된 AI 준비형 채팅 API를 구축할 것입니다.
핵심 포인트는 다음과 같습니다:

프론트엔드에서 AI 서비스를 직접 호출하지 마십시오. AI 서비스를 보안이 적용된 ASP.NET Core 백엔드 API 뒤에 두십시오.

하지만, 많은 개발자가 Azure OpenAI를 학습하면서 직면하는 한 가지 실질적인 어려움이 있습니다:

일부 Azure 무료 구독에는 Azure OpenAI 모델을 배포할 수 있는 할당량 (quota)이 없을 수 있습니다.

이것은 차단 요소가 아닙니다. 우리는 여전히 클린 아키텍처 (clean architecture)를 사용하여 애플리케이션을 구축할 수 있습니다.

이 기사에서는 인터페이스 기반의 AI 서비스 레이어 (interface-based AI service layer)를 생성할 것입니다. 먼저, Azure OpenAI 할당량 없이도 프로젝트를 실행할 수 있도록 로컬 MockAiChatService를 사용할 것입니다. 나중에 Azure OpenAI 모델 할당량이 확보되면 동일한 인터페이스를 AzureOpenAiChatService로 교체할 수 있습니다.

왜 이 접근 방식인가? (Why This Approach?)

실제 기업용 애플리케이션에서는 컨트롤러 (controller)가 하나의 AI 제공업체에 직접 결합되는 것을 피해야 합니다.
나쁜 접근 방식:

ChatController -> Azure OpenAI SDK 직접 호출

더 나은 접근 방식:

ChatController -> IAiChatService -> MockAiChatService / AzureOpenAiChatService

이 방식은 우리에게 유연성을 제공합니다.

Mock vs Live

이것은 컨트롤러가 어떤 AI 제공업체가 사용되고 있는지 알 필요가 없기 때문에 유용한 기업용 패턴입니다.

우리가 구축할 것 (What We Will Build)

우리는 다음과 같은 엔드포인트 (endpoint)를 가진 간단한 ASP.NET Core Web API를 구축할 것입니다:

POST /api/chat

API는 사용자 메시지를 수락하고 구조화된 응답을 반환합니다.

샘플 요청:

{
"userMessage": "건강 보험에서 공제액(deductible)이 무엇인지 설명해 주세요."
}

샘플 응답:

{
"success": true,
"answer": "공제액(deductible)은 보험 플랜이 비용을 지불하기 시작하기 전, 귀하가 보장 서비스에 대해 통상적으로 지불해야 하는 금액입니다.",
"model": "mock-ai-service-local-demo",
"errorMessage": null
}

왜 프론트엔드에서 Azure OpenAI를 직접 호출하지 않나요?

엔터프라이즈 애플리케이션(Enterprise applications)에서 프론트엔드는 Azure OpenAI나 기타 AI 모델 제공업체를 직접 호출해서는 안 됩니다.

다음 방식은 피하십시오:

브라우저 / 모바일 앱 -> Azure OpenAI

다음 방식을 사용하십시오:

브라우저 / 모바일 앱 -> ASP.NET Core API -> AI 서비스 -> Azure OpenAI

백엔드 API는 다음과 같은 역할을 수행합니다:

  • API 키 보호 (API key protection)
  • 인증 (Authentication)
  • 인가 (Authorization)
  • 입력 유효성 검사 (Input validation)
  • 속도 제한 (Rate limiting)
  • 로깅 (Logging)
  • 비용 제어 (Cost control)
  • 프롬프트 거버넌스 (Prompt governance)
  • 책임감 있는 AI 점검 (Responsible AI checks)
  • 안전한 오류 처리 (Safe error handling)

이것이 바로 ASP.NET Core가 엔터프라이즈 AI 애플리케이션을 위한 강력한 기반이 되는 이유입니다.

상위 수준 아키텍처 (High-Level Architecture)

HLD

프로젝트 설정 (Project Setup)

프로젝트 설정

새로운 ASP.NET Core Web API 프로젝트를 생성합니다.

dotnet new webapi -n EnterpriseAiChat.Api
cd EnterpriseAiChat.Api

다음 폴더들을 생성합니다:

  • Controllers
  • Models
  • Options
  • Services

권장되는 프로젝트 구조:

EnterpriseAiChat.Api

├── Controllers
│ └── ChatController.cs

├── Models
│ ├── ChatRequest.cs
│ └── ChatResponse.cs

├── Options
│ └── AzureOpenAiOptions.cs

├── Services
│ ├── IAiChatService.cs
│ ├── MockAiChatService.cs
│ ├── AzureOpenAiChatService.cs
│ ├── IChatRequestValidator.cs
│ └── ChatRequestValidator.cs

├── appsettings.json
└── Program.cs

요청 모델 생성 (Create Request Model)

다음 파일을 생성합니다:

Models/ChatRequest.cs

namespace EnterpriseAiChat.Api.Models; 
public class ChatRequest 
{ 
...

이 모델은 API로 전송되는 사용자 입력을 나타냅니다.

응답 모델 생성 (Create Response Model)

다음 파일을 생성합니다:

Models/ChatResponse.cs

namespace EnterpriseAiChat.Api.Models; 
public class ChatResponse 
{
...

이 응답 모델 (Response Model)은 응답이 Mock 서비스에서 오든 Azure OpenAI에서 오든 상관없이 일관된 구조를 제공합니다.

AI 채팅 서비스 인터페이스 생성 (Create AI Chat Service Interface)

다음 파일을 생성합니다:

Services/IAiChatService.cs

using EnterpriseAiChat.Api.Models; 
namespace EnterpriseAiChat.Api.Services; 
public interface IAiChatService 
...

이 인터페이스 (Interface)는 설계에서 가장 중요한 부분입니다.

컨트롤러 (Controller)는 특정 구현체가 아닌 IAiChatService에 의존하게 됩니다.

이는 다음과 같은 서비스들 사이를 쉽게 전환할 수 있음을 의미합니다:

MockAiChatService
AzureOpenAiChatService
기타 제공자 구현체 (Other provider implementation)

Mock AI 채팅 서비스 생성 (Create Mock AI Chat Service)

다음 파일을 생성합니다:

Services/MockAiChatService.cs

using EnterpriseAiChat.Models;

...

이를 통해 Azure OpenAI 할당량 (Quota) 없이도 전체 API 흐름을 테스트할 수 있습니다.

요청 검증기 생성 (Create Request Validator)

AI API는 사용자의 입력을 무조건적으로 수락해서는 안 됩니다.

다음 파일을 생성합니다:

Services/IChatRequestValidator.cs

using EnterpriseAiChat.Models;

namespace EnterpriseAiChat.Services;
...

또 다른 파일을 생성합니다:

Services/ChatRequestValidator.cs

using EnterpriseAiChat.Models;
using EnterpriseAiChat.Services;

...

이 간단한 검증기 (Validator)는 빈 입력과 매우 큰 프롬프트 (Prompt)로부터 API를 보호합니다.

채팅 컨트롤러 생성 (Create Chat Controller)

다음 파일을 생성합니다:

Controllers/ChatController.cs

using EnterpriseAiChat.Models;
using EnterpriseAiChat.Services;
using Microsoft.AspNetCore.Mvc;
...

로직이 서비스 (Service)로 위임되었기 때문에 컨트롤러는 단순합니다.

이것이 깔끔한 API 설계입니다.

Program.cs 업데이트 (Update Program.cs)

Program.cs를 다음 내용으로 교체합니다:

using EnterpriseAiChat.Options;
using EnterpriseAiChat.Services;

...

API 테스트 (Test the API)

애플리케이션을 실행합니다:

dotnet run

Swagger를 엽니다:

https://localhost:/swagger

테스트:

POST /api/chat

요청 (Request):

{
"userMessage": "건강 보험에서 공제액(deductible)이 무엇인지 설명해 주세요."
}

예상 응답 (Expected response):

_{
"success": true,
"answer": "공제액(deductible)은 보험 플랜이 비용을 지불하기 시작하기 전, 귀하가 보장되는 서비스에 대해 통상적으로 지불해야 하는 금액입니다. 예를 들어, 공제액이 $2,000라면 해당 금액에 도달할 때까지 보장되는 의료 비용을 직접 지불해야 할 수도 있습니다.",
"model": "mock-ai-service-local-demo",
"errorMessage": null
}

Request

Response

_
다른 요청 시도:

{
"userMessage": "AI 애플리케이션에서 RAG란 무엇인가요?"
}

예상 응답 (Expected response):

{
"success": true,
"answer": "RAG는 검색 증강 생성 (Retrieval-Augmented Generation)의 약자입니다. 먼저 문서나 데이터베이스에서 관련 정보를 검색한 다음, 그 컨텍스트 (context)를 AI 모델에 전달하여 근거 있는 답변을 생성합니다.",
"model": "mock-ai-service-local-demo",
"errorMessage": null
}

Azure OpenAI 준비 완료 설정 (Azure OpenAI Ready Configuration)

이 글에서는 로컬 테스트를 위해 모의 서비스 (mock service)를 사용하지만, 프로젝트를 Azure OpenAI를 사용할 수 있는 상태로 유지할 수 있습니다.

파일 생성:

Options/AzureOpenAiOptions.cs

namespace EnterpriseAiChat.Options;

public class AzureOpenAiOptions;
...

appsettings.json 업데이트:

{
"AzureOpenAI": {
"Endpoint": "https://your-resource-name.openai.azure.com/",
"DeploymentName": "your-deployment-name"
}
}

API 키를 appsettings.json에 저장하지 마세요.

로컬 개발을 위해서는 사용자 비밀 (User Secrets)를 사용하세요:

dotnet user-secrets init
dotnet user-secrets set "AzureOpenAI:ApiKey" "YOUR_API_KEY"

운영 환경 (production)에서는 Azure Key Vault 또는 관리 ID (Managed Identity)를 사용하세요.

향후 사용을 위한 AzureOpenAiChatService

Azure OpenAI 할당량 (quota)을 사용할 수 있게 되면, Azure OpenAI 구현체를 추가하세요.

패키지 설치:

dotnet add package Azure.AI.OpenAI
dotnet add package Azure.Identity

파일 생성:

Services/AzureOpenAiChatService.cs

using Azure;
using Azure.AI.OpenAI;
using EnterpriseAiChat.Models;
...

Azure OpenAI 배포 흐름 (Deployment Flow)

일반적인 배포 흐름은 다음과 같습니다:

OpenAI flow

무료 구독을 사용 중이고 사용 가능한 모델이 없는 경우, 할당량 (quota) 또는 지역 (region) 관련 문제가 발생할 수 있습니다.

결론

이 글에서는 ASP.NET Core를 사용하여 보안이 강화된 AI 준비형 채팅 API를 구축했습니다.

일부 무료 구독에서는 Azure OpenAI 할당량 (quota)을 사용할 수 없을 수 있기 때문에, 먼저 로컬 MockAiChatService를 사용했습니다. 이를 통해 클라우드 모델 배포를 기다리지 않고 전체 API 흐름을 테스트할 수 있었습니다.

가장 중요한 디자인 패턴은 다음과 같습니다:

Controller -> Interface -> Implementation (구현체)

이를 통해 다음과 같이 로컬에서 실행할 수 있습니다:

MockAiChatService

그리고 나중에 컨트롤러를 변경하지 않고도 다음과 같이 전환할 수 있습니다:

AzureOpenAiChatService

이는 오늘 바로 AI 애플리케이션 구축을 시작하고, 할당량 (quota)이 확보되었을 때 Azure OpenAI에 연결하고자 하는 .NET 개발자들에게 실용적이고 엔터프라이즈 친화적인 접근 방식입니다.

GitHub URL: https://github.com/indirakumar710/EnterpriseAiChat

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0