Gen AI on K8s/EKS 인퍼런스 최적화 (3)
LiteLLM 게이트웨이를 구성하며,
모든 모델 요청이 한 지점을 지나가는 구조를 만들었습니다.
이번 글에서는 게이트웨이를 지나간 모든 대화를 추적하는 관측성 플랫폼에 대해 살펴보겠습니다.
Langfuse
Langfuse란?
Langfuse는 다음을 제공하는 오픈소스 LLM 관측성 플랫폼
- 포괄적인 추적: 전체 컨텍스트와 함께 캡처되는 모든 LLM 상호작용
- 비용 추적: 모든 모델에 걸친 토큰 사용량 및 비용
- 성능 분석: 지연시간, 처리량, 품질 지표
- 디버깅 도구: 상세한 요청/응답 검사
- 다중 데이터베이스 아키텍처: 확장을 위한 PostgreSQL + ClickHouse + Redis
출처: AWS Workshop
관측성 스택 탐색
먼저 Langfuse가 어떤 컴포넌트로 구성되어 있는지 확인합니다.
# 완전한 관측성 스택 확인
kubectl get all -n langfuse
- langfuse-web: 대시보드 UI와 API를 담당하는 메인 어플리케이션
- langfuse-worker: 수집된 이벤트를 비동기로 처리해 ClickHouse에 적재
- langfuse-postgresql-0: 추적 메타데이터, 프로젝트, 사용자 정보 저장
- langfuse-clickhouse-shard0-0: 대량의 트레이스 분석을 위한 컬럼형 데이터베이스
- langfuse-zookeeper-0: ClickHouse 복제 코디네이터
- langfuse-redis-primary-0: 큐잉과 캐싱 레이어
요청을 받아 대시보드 역할을 하는 역할(web)과,
트레이스를 소화해 분석 DB에 쌓는 역할(worker)이 나눠져 있습니다.
구성과 배포
실제 구성은 IDE에서 확인할 수 있습니다.
# Langfuse Helm values 확인
cat /workshop/components/o11y/langfuse/values.template.yaml
# 스택 구성 확인
grep -A 5 "postgresql:\|clickhouse:\|redis:" /workshop/components/o11y/langfuse/values.template.yaml
배포는 공식 Langfuse Helm Chart를 사용합니다.
# Langfuse Helm 레포지토리 추가
helm repo add langfuse https://langfuse.github.io/langfuse-k8s
helm repo update
# 커스텀 values로 Langfuse 배포
helm upgrade --install langfuse langfuse/langfuse \
--namespace langfuse \
--create-namespace \
-f values.rendered.yaml
# 배포 상태 확인
kubectl rollout status deployment/langfuse-web -n langfuse
배포 과정에서 일어나는 일을 정리하면 다음과 같습니다.
- 템플릿 렌더링: values.template.yaml → values.rendered.yaml
- Helm 설치: 렌더링된 values로 차트 배포
- 데이터베이스 초기화: PostgreSQL, ClickHouse, Redis 설정
- 프로젝트 설정: 조직 및 프로젝트 자동 생성, 워크샵 자격 증명으로 사용자 계정 생성
- 통합 준비: LiteLLM 연결을 위한 API 키 구성
4~5번을 거쳐, 접속하면 LiteLLM의 트레이스가 쌓이는 상태로 시작할 수 있습니다.
Langfuse 사용해보기
첫 접속
echo "Langfuse URL: http://$(kubectl get ingress -n langfuse langfuse -o jsonpath='{.status.loadBalancer.ingress[0].hostname}')"
로그인하면 Organizations 화면이 먼저 나타납니다.

Provisioned Org와 Provisioned Project가 이미 만들어져 있습니다.
Go to project를 눌러 프로젝트로 들어갑니다.
홈 대시보드

Past 1 day 기준으로 다음이 집계되어 있습니다.
- Traces: 4건 (중간에 DB 초기화 해서 일부 날아갔습니다..)
- Model costs: $0.002727 — bedrock/openai.gpt-oss-20b-1:0, 20.17K 토큰
- Scores: 0건 (아직 평가를 붙이지 않았으므로)
지난 글에서 LiteLLM Usage 탭으로 봤던 것과 같은 데이터가,
이번에는 모델별 비용과 시간대별 차트로 훨씬 자세하게 펼쳐집니다.
트레이스 목록
Tracing 메뉴에서는 개별 대화 기록을 볼 수 있습니다.

각 행에 타임스탬프, 입력/출력 미리보기, Latency, 토큰 수, 비용이 정리되어 있습니다.
트레이스 4건 중 실제로 질문을 한 것은, "Langfuse에 대해 설명해줘", "트레이스 분석하게 도와줘" 2건입니다.
나머지 2건은 Suggest 3-5 relevant follow-up questions...로 시작하는,
Open WebUI가 후속 질문 추천을 위해 자동으로 보내는 요청입니다.
채팅 한 번에 실제로는 LLM 호출이 두 번 나가고 있었던 것입니다.
관측성을 켜보면, UI가 뒤에서 조용히 보내던 요청까지 확인할 수 있던것입니다.
개별 트레이스 검사
목록에서 트레이스 하나를 클릭하면 상세 화면으로 들어갑니다.

- Latency: 5.29초 (Time to first token 5.29초)
- Total Cost: $0.0005
- Token Usage: 5,575 프롬프트 → 367 완성 (총 5,942)
- 모델: bedrock/openai.gpt-oss-20b-1:0
- 파라미터: stream: false, max_retries: 0, aws_region_name: us-west-2
Preview 탭에는 요청 전문이 그대로 담겨 있는데, Chat History에 낯익은 대화가 보입니다.
지난 글에서 gpt-oss-20b를 테스트하며 물었던 "오늘 저녁 메뉴 추천 해줘" 를 볼 수 있습니다.
이 트레이스가 바로 그 대화에 대한 후속 질문 생성 요청이었던 것입니다.
프롬프트가 실제로 사용한 5,575 토큰에 대한 근거도 확인해볼 수도 있습니다.
후속 질문을 만들기 위한 직전 대화 전체가 컨텍스트로 다시 들어가기 때문입니다.
응답 몇 줄을 추천받자고 대화 전체를 다시 지불하는 셈이니,
이런 부가 기능의 비용도 관측성이 있어야 보입니다.
기본 제공 대시보드
Dashboards 메뉴에는 Langfuse가 관리하는 대시보드 4종이 기본 제공됩니다.

- Langfuse Home: 프로젝트 홈에 표시되는 전체 개요
- Langfuse Cost Dashboard: LLM 비용 리뷰
- Langfuse Latency Dashboard: 트레이스/생성 단위 지연시간 모니터링
- Langfuse Usage Management: 리소스 할당을 위한 사용량 추적
이 중 Cost Dashboard를 열어보겠습니다.

- Total Count Traces 7 / Observations 10: 전체 기간 누적 집계
- Cost by Model Name: bedrock/openai.gpt-oss-20b-1:0가 비용 대부분을 차지
- Cost by Environment: default 환경에 전액($0.002727)이 몰린 도넛 차트
- Top 20 Users / Use Cases by Cost: 사용자와 유스케이스 단위의 비용 분석 틀
위젯을 직접 추가해 커스텀 대시보드를 만들 수도 있지만,
기본 제공 대시보드만으로도 비용, 지연시간, 사용량 관점이 이미 갖춰져 있습니다.
고급 기능: LLM-as-a-Judge
Langfuse는 AI 모델을 심사자로 사용해 응답 품질을 자동 평가하는 기능도 지원합니다.
- 자동 채점: 응답의 품질, 정확성, 유용성을 모델이 평가
- 일관성 평가: 서로 다른 모델의 응답을 객관적으로 비교
- 품질 벤치마킹: 표준화된 지표로 시간 경과에 따른 개선 추적
- 지속적인 평가: 모든 상호작용을 자동으로 평가해 품질 패턴 파악
모델 비교, 프롬프트 최적화, 품질 저하 감지, A/B 테스트에 활용되며,
모듈 4에서 사용할 수 있습니다.
자세한 내용은 Langfuse LLM-as-a-Judge 문서를 참고하세요.
Langfuse 동작 원리
그렇다면 이 트레이스들은 어떻게 Langfuse까지 흘러온 걸까요?

LiteLLM은 모델 호출과 별개로 트레이스를 전송합니다.
- 사용자가 메시지를 보내면 Open WebUI가 LiteLLM에 API 요청
- LiteLLM이 모델로 라우팅하면서 동시에 Langfuse에 Start trace
- 모델 응답이 돌아오면 Complete trace with metrics 전송
- Langfuse는 프롬프트, 응답, 토큰, 비용, 지연시간을 저장
Open WebUI는 Langfuse의 존재를 전혀 모릅니다.
게이트웨이가 추적을 대신 해주기에, 어플리케이션 코드 변경이 없는 것입니다.
Langfuse로 트레이스를 보내는 경로는 이 방법 하나만이 아닙니다.
통합 작동 방식
| LiteLLM Callbacks | 게이트웨이를 통과하는 모든 LLM 요청을 자동 추적. 어플리케이션 코드 변경 불필요 |
| Langfuse SDK | 어플리케이션 코드에 CallbackHandler를 직접 삽입해, 에이전트 워크플로우와 도구 호출 수준까지 추적 |
| OpenTelemetry | 표준 OTEL 프로토콜로 Langfuse의 OTEL 호환 엔드포인트에 전송. 다국어 환경이나 기존 OTEL 계측에 유용 |
이 중 두 레이어를 함께 사용합니다.
- 게이트웨이 레이어 (LiteLLM Callbacks): 모든 LLM 호출의 토큰, 비용, 지연시간 캡처
- 어플리케이션 레이어 (Langfuse SDK): 에이전트 워크플로우, 도구 호출, 의사결정 체인 캡처
낮은 수준의 모델 성능과 높은 수준의 어플리케이션 동작을,
하나의 Langfuse 대시보드에서 모두 볼 수 있게 되는 구조입니다.
마무리
이번 작업으로, 플랫폼의 관측성 레이어를 완성할 수 있었습니다.
모델별 응답 시간과 비용이 상호작용 단위로 집계되고,
UI가 뒤에서 보내는 자동 요청까지 포함해 모든 호출을 기록합니다.
관측성 모델을 통해 채팅 한 번이 LLM 호출 두 번이 되고,
그 부가 호출이 대화 전체를 컨텍스트로 다시 소비한다는 사실을 알 수도 있었습니다.
또한, 기능을 추가할 때마다 토큰 비용이 어디서 새는지 알 수도 있었습니다.
이제 LiteLLM(게이트웨이)과 Langfuse(관측성)를 모두 갖추며,
EKS 위의 Agentic AI 플랫폼 기반을 완성했습니다.
다음 모듈에서는 이 기반 위에서 LangChain과 LangGraph를 사용해,
도구 호출과 메모리를 갖춘 실제 에이전트 어플리케이션을 구축해보겠습니다.