덕규의 아즈카반
GenAI on EKS/K8s 인퍼런스 최적화(4) 본문
작업을 진행해오며 모델, 게이트웨이, 관측성을 갖춘 Agentic AI 플랫폼을 구축했습니다.
이번에는 이 플랫폼 위에,
"Loan Buddy" 라는 지능형 대출 처리 어플리케이션을 구축해보겠습니다.
이 과정에서 AI 에이전트가 복잡한 워크플로우를 어떻게 자동화하는지,
배포하고 추적하며 확인하겠습니다.
어플리케이션 목표
- AI 어플리케이션 구축: 앞서 구축한 플랫폼 사용
- 지능형 에이전트 배포: 비즈니스 의사결정을 자동으로 수행
- Model Context Protocol(MCP) 사용: 에이전트에 외부 도구와의 기능 제공
- 에이전트 워크플로우 추적: Langfuse를 활용한 관측성 확보
- 아키텍처: Kubernetes 위의 AI 에이전트 구조
아키텍처

이전에 만들어 놓은 플랫폼에 에이전트와 MCP 서버를 추가해 구축할 예정입니다.
플랫폼을 통해 모델 서빙과 라우팅, 추적을 진행하고,
에이전트와 MCP를 이용해 해야할 업무들을 자동화할 수 있습니다.
- 모든 AI 요청은 LiteLLM Gateway를 통해 처리
- 모든 에이전트 활동을 Langfuse로 추적
- 어플리케이션은 지금까지 학습한 패턴 그대로 EKS에 배포
사용하는 기술 스택은 다음과 같습니다.
- AI Frameworks
- LangGraph: AI 에이전트를 위한 워크플로우 오케스트레이션
- LangChain: AI 애플리케이션 구축 기반
- Model Context Protocol: 도구 통합 표준
- Pydantic: 데이터 검증 및 직렬화
- Platform Integration
- LiteLLM Gateway: 모든 AI 요청 라우팅
- Langfuse: 모든 에이전트 활동 추적
- Claude 4.5 Sonnet: AI 모델
- Application Components
- Loan Processing Agent: 메인 워크플로우 오케스트레이터
- Address Validator: 주소 검증 MCP 서버
- Employment Checker: 고용 검증 MCP 서버
- Image Processor: 문서 분석 MCP 서버
John의 대출 신청
Loan Buddy는 다음과 같은 대출 신청서 이미지들을 처리할 예정입니다.

서류는 John Michael Doe 씨의 것으로,
개인정보와 고용 정보(Tech Solutions Inc, Software Engineer, 연봉 $75,000),
주소 정보(123 Main Street, 자가 4년 거주),
대출 조건($8,500, 36개월, 월 $275)을 가지고 있습니다.
은행의 대출 담당자가 이 서류를 사람 손으로 처리한다면 다음 작업이 필요합니다.
- 데이터 추출: 이름, 생년월일, SSN 등 신청서 항목 옮겨 적기
- 고용 확인: Tech Solutions Inc에 연락해 재직 여부 확인
- 소득 검증: 연봉 $75,000 (월 $6,250) 확인
- 주소 검증: 123 Main Street가 실재하는 주거용 주소인지 확인
- 안정성 평가: 거주 기간, 주택 소유, 근속 연수 기록
- 비율 계산: 대출액 대비 소득, 월 상환액 산출
- 결정: 모든 요소를 종합해 승인 또는 거부
이 모든 과정은 통상 2~3시간을 소모합니다.
Loan Buddy는 이 전체 프로세스를 자동화합니다.
- 신청서 읽기: 비전 LLM을 활용해 이미지에서 데이터 추출
- 정보 검증: 외부 서비스를 통해 주소·고용 확인
- 비즈니스 규칙 적용: 대출 한도, 소득 비율, 위험 평가
- 결정과 기록: 판단 근거를 Langfuse에 감사 추적으로 보존
이처럼 자동화 도구를 도입하여 기존 대비 처리 시간을 2~3시간에서 분 단위로 줄이고,
동일한 기준을 도입 및 모든 결정에 대한 근거를 남길 수 있습니다.
처리 구조
그렇다면 Loan Buddy는 이를 어떻게 처리할까요?

John의 신청서가 업로드되면 Loan Processing Agent(LangGraph) 가 이를 처음 맡습니다.
LangGraph를 활용해 Workflow를 Orchestrate 하여 LiteLLM으로 넘깁니다.
에이전트에 대한 모든 요청은 LiteLLM을 거쳐 Claude가 추론과 판단을 맡고,
주소 검증, 고용 확인, 이미지 처리를 각 MCP 서버가 담당합니다.
그리고 이 모든 과정을 Langfuse로 추적합니다.
구성요소
이 구조를 코드 레벨에서 하나씩 살펴보겠습니다.
LangGraph와 LangChain
LangGraph란?
LLM 기반 에이전트의 워크플로우를 그래프로 정의하고 실행하는 오케스트레이션 프레임워크.
상태 관리, 분기, 오류 처리, 도구 호출 루프를 담당합니다.
출처: LangChain Docs
AI 시스템의 프로젝트 관리자에 해당하는 역할입니다.
# 에이전트에서 LangGraph는 워크플로우를 생성합니다
from langgraph.prebuilt import create_react_agent
# 다음을 수행할 수 있는 에이전트를 생성:
# 1. 입력에 반응
# 2. 도구 사용 (MCP 서버)
# 3. 단계 간 상태 유지
# 4. 결정 내리기
graph = create_react_agent(model, tools, debug=True)
LangChain이란?
LLM 애플리케이션을 구성하는 빌딩 블록 프레임워크.
모델 연결, 도구 추상화, 메모리 관리, 프롬프트 템플릿을 제공합니다.
출처: LangChain Docs
LangChain이 구성요소를 제공하면, LangGraph가 이를 워크플로우로 엮는 관계입니다.
# LangChain이 플랫폼에 연결
from langchain_openai import ChatOpenAI
model = ChatOpenAI(
model="bedrock/claude-4.5-sonnet",
api_key=model_key,
# 게이트웨이
base_url="http://litellm.litellm.svc.cluster.local:4000"
)
여기서 base_url은 Bedrock이나 Anthropic의 엔드포인트가 아니라,
클러스터 내부의 LiteLLM 서비스 주소를 바라봅니다.
에이전트 입장에서는 OpenAI 호환 API 하나를 쓰고,
모델 라우팅과 비용 추적은 전부 게이트웨이가 처리하는 것입니다.
MCP 서버 3종
MCP(Model Context Protocol)란?
AI 모델이 외부 도구와 데이터 소스에 접근하는 방식을 표준화한 오픈 프로토콜.
도구를 MCP 서버로 만들어두면, 어떤 에이전트든 같은 방식으로 연결해 사용할 수 있습니다.
출처: modelcontextprotocol.io
각 MCP 서버는 한 가지 작업에만 전문성을 가지며, Loan Buddy는 3개의 MCP 서버를 사용합니다.
1. Image Processor MCP (신청서 이미지에서 구조화된 데이터 추출)
- 신청서 이미지 ID 수신
- S3 스토리지에서 이미지 검색
- Claude의 비전 기능으로 문서 읽기
- 구조화된 JSON 데이터 추출
이미지는 S3에 한 번 저장된 후 ID로만 참조됩니다.
모든 LLM 호출에 이미지를 다시 실어 보내지 않기에, 토큰 비용을 절약할 수 있습니다.
2. Address Validator MCP (주소 실재 여부와 위험도 평가)
- 주소 형식 및 우편번호 검증
- 주거용 여부 확인
- 사기 위험 지표 평가
- 소유 상태 검증
- 거주 기간 기반 안정성 점수 계산
3. Employment Validator MCP (고용 및 소득 주장 확인)
- 고용 상태 확인 (정규직 여부)
- 소득 정확성 검증 (연봉/월급 일치)
- 고용 기간 확인
- 고용 이력 기반 안정성 평가
오케스트레이터
이 모든 과정을 Loan Processing Agent가 지휘하며, 전체 워크플로우는 다음과 같습니다.

신청서 업로드부터 데이터 추출, 여러 검증을 거쳐 승인/거부 결정에 이릅니다.
순차적으로 이루어지고, 모든 단계를 Langfuse로 기록합니다.
이런 아키텍처 구성이 가지는 장점은 다음과 같습니다.
- 관심사 분리
- 각 MCP 서버는 한 가지 작업만 잘 수행
- 에이전트는 오케스트레이션만 하고 비즈니스 로직을 직접 구현하지 않음
- 인프라(라우팅, 추적)는 플랫폼 컴포넌트가 처리
- 확장성
- MCP 서버는 독립적으로 확장 가능
- 여러 에이전트가 동일한 MCP 서버를 공유 가능
- 유지보수성
- 에이전트를 건드리지 않고 MCP 서버의 비즈니스 규칙 업데이트
- 기존 코드 변경 없이 새로운 검증 도구 추가
- 비용 최적화
- 이미지는 한 번 처리되고 캐시됨
- 효율적인 토큰 사용 (모든 호출에 이미지를 싣지 않음)
어플리케이션 배포
배포에 앞서 플랫폼 컴포넌트가 실행 중인지 확인합니다.
# 플랫폼 구성요소 확인
kubectl get pods -n litellm
kubectl get pods -n langfuse
# LiteLLM 게이트웨이 접근 확인
echo "LiteLLM URL: http://$(kubectl get ingress -n litellm litellm -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')"
# Langfuse 접근 확인
echo "Langfuse URL: http://$(kubectl get ingress -n langfuse langfuse -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')"
배포에 필요한 구성
Loan Buddy가 동작하려면 다음 요소들이 연결되어야 합니다.
- S3 Bucket: 업로드된 대출 문서 저장. Langfuse 배포 시 Terraform이 만든 버킷을 재사용
- terraform output langfuse_bucket_name
- AWS Region: .env 파일의 REGION 값. S3 및 AWS 서비스 호출에 사용
- LiteLLM API Key: Virtual Key(agent-key). 에이전트가 모델을 호출할 수 있게 함
- Langfuse Credentials: 관측성을 위한 공개/비밀 키 쌍
- Service Account + Pod Identity: Langfuse 서비스 계정을 workshop 네임스페이스로 복사
- Pod Identity Association 생성
Pod Identity Association을 사용하게 된다면,
Pod는 하드코딩된 자격 증명 없이 IAM 역할을 통해 S3에 접근합니다.
# 서비스 계정 복사
kubectl get serviceaccount langfuse -n langfuse -o yaml | \
sed 's/namespace: langfuse/namespace: workshop/' | \
kubectl apply -f -
# Pod Identity Association 생성
aws eks create-pod-identity-association \
--cluster-name genai-on-eks \
--namespace workshop \
--service-account langfuse \
--role-arn <IAM_ROLE_ARN>
자동 배포
이 모든 절차를 배포 스크립트 하나로 자동화했다면, 딸깍으로 끝납니다.
# credit validation 디렉토리로 이동
cd /workshop/workshops/eks-genai-workshop/static/code/module3/credit-validation
# 배포 스크립트 실행
chmod +x deploy-workshop-app.sh
./deploy-workshop-app.sh
스크립트는 앞서 정리한 구성을 순서대로 수행도록 구성됐습니다.
Terraform 출력에서 S3 버킷을 조회,
LiteLLM/Langfuse 키를 매니페스트에 주입,
네임스페이스와 서비스 계정, Pod Identity를 만들어,
어플리케이션을 배포합니다.
# 배포 예시
Loan Buddy Workshop Deployment
Step 1: Checking prerequisites... ✅
Step 2: Retrieving S3 bucket name... ✅ genai-on-eks-bucket-langfuse-xxxxx
Step 3: Getting AWS region... ✅ us-west-2
Step 4: Getting LiteLLM API key... ✅ sk-xxxxx...
Step 5: Getting Langfuse credentials... ✅ lf_pk_xxxxx... / lf_sk_xxxxx...
Step 6: Creating workshop namespace... ✅
Step 7: Setting up service account... ✅ (+ Pod Identity Association)
Step 8: Configuring deployment file... ✅
Step 9: Deploying Loan Buddy application... ✅
Step 10: Waiting for deployments... ✅
NAME READY STATUS RESTARTS AGE
loan-buddy-agent-xxx 1/1 Running 0 1m
mcp-address-validator-xxx 1/1 Running 0 1m
mcp-employment-validator-xxx 1/1 Running 0 1m
mcp-image-processor-xxx 1/1 Running 0 1m
에이전트 1개와 MCP 서버 3개, 총 4개의 Deployment가 올라갑니다.
동작 확인
배포한 어플리케이션을 이용해서 John의 신청서를 실제로 처리해보겠습니다.
example1.png 를 사용해 테스트를 진행해보겠습니다.
# 새 터미널에서 에이전트 로그 관찰
kubectl logs -f deployment/loan-buddy-agent -n workshop
# Loan Buddy 배포
kubectl port-forward service/loan-buddy-agent 8888:8080 -n workshop &
# 테스트 데이터 디렉토리로 이동
cd /workshop/workshops/eks-genai-workshop/static/code/module3/credit-validation/
# John Michael Doe의 대출 신청서 처리
curl -X POST -F "image_file=@./example1.png" \
http://localhost:8888/api/process_credit_application_with_upload | jq
요청이 들어가면 로그에서 에이전트의 작업 흐름을 실시간으로 볼 수 있습니다.
🔄 Starting credit application processing...
📄 Processing uploaded loan application image...
✅ Image stored in S3 with ID: a7b9c2d4e5f6...
🔧 Loading MCP tools...
🤖 Processing with agent...
[Agent]: I'll help you process this credit application.
[Image Processor MCP]: Extracting data from loan application...
Found: John Michael Doe, DOB: 03/15/1985, SSN: ***-**-7890
Income: $75,000, Employer: Tech Solutions Inc
Address: 123 Main Street, Anytown, CA 90210
[Address Validator MCP]: Checking 123 Main Street, Anytown, CA 90210
✅ Valid residential address - Owner occupied - 4 years
✅ Risk score: 15 (Low risk)
[Employment Validator MCP]: Verifying Tech Solutions Inc
✅ Employment confirmed - Software Engineer, $75,000, 3.5 years
✅ Stability score: 85 (High stability)
[Agent]: Calculating loan metrics...
- Loan amount: $8,500 / Monthly payment: $275
- Debt-to-income ratio: 4.4% (Excellent)
FINAL DECISION: ✅ APPROVED
워크플로우 순서도에 따라서,
이미지 추출 → 주소 검증 → 고용 확인 → 비율 계산 → 승인 결정이 차례로 실행됩니다.
만약 사람이 했다면 2~3시간 걸릴 검토가, 업로드 한 번으로 몇 분 안에 끝납니다.
Langfuse에서 에이전트 추적
이 실행은 Langfuse에도 그대로 기록되는데,
지금까지 봤던 단일 호출과는 다른 모양의 에이전트 트레이스가 찍힙니다.

단일 span이 아니라, 에이전트 실행 전체가 중첩된 트리형태로 기록됩니다.
- 최상위 트레이스 하위에 agent → call_model → 도구 호출이 계층으로 쌓이고
- agent와 tools span이 번갈아 반복되며 ReAct 루프(추론 → 행동 → 관찰)가 시각화돼
- 각 단계의 지연시간과 LLM 호출별 토큰 사용량을 개별적으로 확인할 수 있습니다
지난 글에 잠시 등장한 애플리케이션 레이어(Langfuse SDK) 추적이 바로 이것입니다.
게이트웨이 레이어가 "LLM을 몇 번, 얼마에 불렀는가"를 보여준다면,
SDK 레이어는 "에이전트가 왜 호출을 했고, 어떤 도구를 거쳐 도달했는가"를 보여줍니다.
대출 심사처럼 근거가 중요한 도메인에서는,
이 추적 기록이 규정 준수에 대한 중요한 감사 자료가 됩니다.
마무리
Loan Buddy를 끝으로, 전체 워크샵을 진행할 수 있었습니다.
- Phase 1 : 모델과 상호작용
- EKS Auto Mode 클러스터 위에 Open WebUI 배포
- AWS Neuron 칩에서 vLLM으로 Qwen 3 8B, DeepSeek R1 서빙
- Bedrock을 통한 Claude 4.5 Sonnet 통합, 자체 호스팅 vs 관리형 비교
- Phase 2 : 플랫폼 컴포넌트
- LiteLLM 통합 게이트웨이 구성과 무중단 모델 추가
- Langfuse 관측성 스택과 게이트웨이/SDK 이중 추적
- Phase 3 : 어플리케이션 구축
- LangGraph 에이전트와 MCP 서버 3종으로 Loan Buddy 구현
- Pod Identity 기반의 자격 증명 없는 S3 접근
- 에이전트 워크플로우의 완전한 추적
이번 모듈을 만들면서 가장 크게 느낀 것은,
에이전트 애플리케이션 코드가 생각보다 얇다는 점입니다.
이러한 과정을 거치며 에이전트를 활용하는 어플리케이션의 경우,
생각보다 코드가 그렇게 무겁지 않다는 것을 배울 수 있었습니다.
어플리케이션 내에서 모델 선택, 라우팅, 비용 집계, 추적 등을 하지 않다보니,
플랫폼으로 책임을 분산시켜 어플리케이션의 크기가 줄어드는 것 같습니다..
문서 처리, 고객 서비스 자동화, 모니터링 등 Loan Buddy와 같은 패턴을 적용할 수 있는 곳은 많습니다.
이번 워크샵에서 배운 플랫폼 우선 접근을 바탕으로,
실무에서도 작은 에이전트들을 도입해 볼 생각입니다.
참고로, 워크샵과 동일한 플랫폼을 직접 배포해볼 수 있는
AWS GenAI on EKS Starter Kit이 GitHub에 오픈소스로 공개되어 있습니다.
이 스타터 킷에는 llm-d라는 K8s 기반 분리형 LLM 서빙 프레임워크도 포함되어 있습니다.
제가 진행한 과정을 따라 진행해보고자 한다면, 깃허브에서 참고하시면 좋을 것 같습니다..
'DevOps' 카테고리의 다른 글
| HW 기본 원리 (2) | 2026.08.25 |
|---|---|
| Gen AI on K8s/EKS 인퍼런스 최적화 (3) (2) | 2026.08.09 |
| GenAI on K8s/EKS 인퍼런스 최적화 (2) (1) | 2026.08.04 |
| GenAI on K8s/EKS 인퍼런스 최적화 (0) | 2026.08.02 |
| LDAP 알아보기 (3) | 2026.07.15 |