AWS Bedrock, Python, TypeScript, C# .NET 및 Blazor를 활용한 생성형 AI (GenAI) FAQ 시스템 설계
요약
AWS Bedrock, OpenSearch, Lambda를 활용하여 RAG 기반의 생성형 AI FAQ 시스템을 구축하는 단계별 가이드입니다. Python, TypeScript, C# .NET, Blazor를 결합한 풀스택 아키텍처와 Bedrock Guardrails를 통한 컴플라이언스 준수 방법을 다룹니다.
핵심 포인트
- AWS Bedrock과 OpenSearch를 활용한 RAG 아키텍처 설계
- Python, TypeScript, C# .NET을 활용한 멀티 언어 기반 서버리스 구현
- Bedrock Guardrails를 통한 AI 응답의 안전성 및 컴플라이언스 확보
- S3와 Lambda를 이용한 문서 정제 및 임베딩 자동화 파이프라인
이 가이드는 LLM(대규모 언어 모델) 및 임베딩(embeddings)을 위한 AWS Bedrock, 시맨틱 검색(RAG)을 위한 OpenSearch, 프로세싱을 위한 Lambda, C# .NET API, 그리고 Blazor UI를 사용하여 프로덕션 환경에 적합한 생성형 AI (Generative AI) FAQ 시스템을 구축하는 단계별 가이드입니다. Bedrock Guardrails를 통해 전 과정에서 컴플라이언스(compliance)를 준수합니다.
아키텍처 개요 (Architecture Overview)
사용자 (User) → Blazor UI → C# .NET API → API Gateway → TypeScript Lambda
↓
AWS Bedrock (Claude)
...
구성 요소:
- S3 — 원본 및 정제된 FAQ 문서 저장
- Python Lambda (CleanDocuments) — S3 업로드 시 트리거되어 텍스트를 정제하고 SNS로 발행
- Python Lambda (GenerateEmbeddings) — 정제된 문서를 읽어 Titan 임베딩(embeddings)을 생성하고 OpenSearch에 저장
- OpenSearch — 시맨틱 문서 검색을 위한 k-NN 인덱스
- TypeScript Lambda (ProcessQuestion) — 사용자 질문을 임베딩하고 OpenSearch를 검색(RAG)하며, Guardrails가 적용된 Claude를 호출
- C# .NET API — Blazor와 API Gateway 사이의 RESTful 계층
- Blazor UI — 질문을 하기 위한 웹 인터페이스
- Bedrock Guardrails — 주제를 벗어나거나 금지된 응답을 차단
1단계: AWS 인프라 설정 (AWS Infrastructure Setup)
S3 버킷 (S3 Bucket)
faq-documents-2025 버킷(us-east-1)을 생성합니다. 프라이빗(private) 설정, 버전 관리(versioning) 활성화, SSE-S3 암호화를 적용합니다. faqs/(원본)와 processed/(정제됨)라는 두 개의 폴더를 생성합니다.
faqs/product_faq.txt를 위한 샘플 FAQ 문서:
Q: 제품 보증 기간은 어떻게 되나요?
A: 제품에는 제조 결함을 보장하는 1년 보증이 포함됩니다.
Q: 고객 지원팀에 어떻게 연락하나요?
...
OpenSearch 도메인 (OpenSearch Domain)
faq-embeddings-2025 도메인을 생성합니다. 인스턴스 유형은 t3.small.search를 사용하며, 세밀한 액세스 제어(fine-grained access control)를 설정합니다. 그런 다음 k-NN 인덱스를 생성합니다:
curl -X PUT "https://<domain>/faq_index" \
-H 'Content-Type: application/json' \
-u admin:password \
...
dimension: 1536 설정은 Bedrock의 Titan Embeddings 모델 출력과 일치합니다.
Bedrock
Bedrock 콘솔(us-east-1)에서 Anthropic Claude v2 및 Amazon Titan Embeddings G1 — Text에 대한 액세스 권한을 요청합니다.
Guardrail FaqGuardrail을 생성합니다:
- 콘텐츠 필터 (Content filters): 혐오 표현 (hate speech), 폭력 (violence), 비속어 (profanity) — 임계값 (threshold): Medium
- 주제 필터 (Topical filter): 키워드
product, support, warranty, features, faq허용; 관련 없는 주제 차단
Lambda를 위한 IAM 역할 (IAM Role)
S3 (s3:GetObject, s3:PutObject, s3:ListBucket), OpenSearch (es:ESHttpPut, es:ESHttpGet, es:ESHttpPost), Bedrock (bedrock:InvokeModel, bedrock:ApplyGuardrail), 그리고 AWSLambdaBasicExecutionRole에 대한 정책을 포함하는 FaqLambdaRole을 생성합니다.
API Gateway
REST API FaqApi를 생성합니다. 리소스 /faq, POST 메서드를 생성하고 ProcessQuestion을 가리키는 Lambda 프록시 통합 (Lambda proxy integration)을 설정합니다. prod 스테이지로 배포합니다.
단계 2: 데이터 정제 Lambda (Python)
faqs/로의 S3 업로드에 의해 트리거됩니다. 텍스트를 정제하여 processed/에 저장하고, SNS를 통해 GenerateEmbeddings에 알림을 보냅니다.
import boto3, re, json, logging
logging.basicConfig(level=logging.INFO)
...
배포 (Deploy): 런타임 (Runtime) Python 3.9, 역할 (role) FaqLambdaRole, faqs/ 접두사(prefix)에 대한 S3 트리거, 제한 시간 (timeout) 30초, 메모리 (memory) 256MB.
단계 3: 임베딩 생성 Lambda (Python)
정제 Lambda의 SNS에 의해 트리거됩니다. Titan 임베딩 (embeddings)을 생성하고 이를 OpenSearch에 저장합니다.
import boto3, json, logging
from opensearchpy import OpenSearch, RequestsHttpConnection
from aws_requests_auth.boto_utils import BotoAWSRequestsAuth
...
배포 (Deploy): 런타임 (Runtime) Python 3.9, FaqProcessingTopic에 대한 SNS 트리거, 제한 시간 (timeout) 60초, 메모리 (memory) 512MB. pip install opensearch-py aws-requests-auth -t . 명령어로 패키징합니다.
단계 4: 질문 처리 Lambda (TypeScript)
사용자 질문을 임베딩하고, OpenSearch에서 k-NN 검색을 실행하며, RAG 프롬프트 (prompt)를 구축한 뒤 Guardrails를 적용하여 Claude를 호출합니다.
import { APIGatewayProxyEvent, APIGatewayProxyResult } from 'aws-lambda';
import { Client } from '@opensearch-project/opensearch';
import { defaultProvider } from '@aws-sdk/credential-provider-node';
...
배포 (Deploy): 런타임 Node.js 18.x, npx tsc로 컴파일, zip -r function.zip dist node_modules로 패키징, 타임아웃 60초, 메모리 512MB.
단계 5: C# .NET API
Blazor와 API Gateway 사이에서 동작합니다. 입력을 검증하고, Lambda로 전달하며, 답변을 반환합니다.
[ApiController]
[Route("api/faq")]
public class FaqController : ControllerBase
...
Program.cs — Blazor를 위한 CORS 설정:
builder.Services.AddHttpClient();
builder.Services.AddCors(o => o.AddPolicy("AllowBlazor", b =>
b.WithOrigins("https://localhost:5001").AllowAnyMethod().AllowAnyHeader()));
...
Elastic Beanstalk에 배포: eb init -p dotnetcore FaqApi && eb create faq-api-env && eb deploy.
단계 6: Blazor UI
@page "/faq"
@using System.Net.Http.Json
@inject HttpClient Http
...
단계 7: 보안 및 프로덕션 체크리스트
- 모든 역할(Role)에 IAM 최소 권한 적용 — 프로덕션 환경에서 와일드카드(*) 사용 금지
- 버킷에 SSE-S3 적용, 모든 구간에 HTTPS 사용
- 새로운 금지 용어를 사용하여
FaqGuardrail을 정기적으로 업데이트 - 모든 Lambda 및 API Gateway에 대해 CloudWatch 로그 활성화
- S3 생명주기 규칙(Lifecycle rule):
processed/경로의 데이터를 30일 후 Glacier로 아카이브 - OpenSearch: 프로덕션에서는 퍼블릭 엔드포인트가 아닌 VPC 액세스 사용
- OpenSearch 인덱스 복제본(Replica) 확장:
"number_of_replicas": 2
단계 8: CloudFormation을 이용한 IaC
전체 설정을 자동화합니다:
Resources:
FaqBucket:
Type: AWS::S3::Bucket
...
aws cloudformation deploy \
--template-file template.yaml \
--stack-name FaqStack \
...
일반적인 문제 해결 (Common Troubleshooting)
| 증상 | 해결 방법 |
|---|---|
| OpenSearch에 임베딩(Embeddings)이 없음 | CloudWatch 로그에서 GenerateEmbeddings 확인 |
| ... |
원문은 Medium에 게시되었습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기