TechFeedTechFeed
AI/LLM

LLM Evals 실전 가이드 — AI 앱 출력 품질을 CI/CD로 검증하는 법

DeepEval, Langfuse, Braintrust를 활용해 LLM 앱의 출력 품질을 정량 지표로 측정하고, GitHub Actions 품질 게이트로 배포 전 회귀를 잡는 실무 가이드. LLM-as-Judge 패턴, 골든 테스트셋 구성, 비용 관리 방법까지 정리한다.

LLM 앱을 프로덕션에 배포하기 시작한 팀들이 공통으로 겪는 문제가 있다. 프롬프트를 조금 바꿨더니 다른 기능이 망가졌고, 새 모델 버전으로 교체했더니 출력 품질이 눈에 띄게 달라졌다. 그런데 무엇이 얼마나 달라졌는지 측정할 방법이 없다. LLM Evals(평가 파이프라인)는 이 문제를 해결한다. AI 앱의 출력 품질을 정량 지표로 측정하고, CI/CD에 품질 게이트를 붙여 배포 전에 회귀를 잡아내는 실무 가이드를 정리한다.

AI 서비스를 프로덕션에 운영 중이거나, LLM 기반 기능에 테스트를 붙이고 싶은 백엔드/풀스택 개발자에게 필요한 글이다.

LLM evaluation pipeline diagram
LLM 평가 파이프라인 — 개발 단계 evals와 프로덕션 모니터링의 구조

LLM Evals란 무엇인가 — 단순 assert와 다른 이유

일반 소프트웨어 테스트는 결정론적이다. 함수에 입력을 넣으면 항상 같은 출력이 나오고, assert output == expected로 검증할 수 있다. LLM은 다르다. 같은 프롬프트에도 출력이 매번 달라지고, '정답'이 하나가 아닌 경우가 많다.

LLM Evals는 이 비결정론적 출력을 다음 세 가지 축으로 평가한다.

  • 관련성(Relevance): 답변이 질문에 실제로 응답하는가
  • 충실도(Faithfulness): RAG 시스템이라면 컨텍스트 문서의 내용과 일치하는가
  • 할루시네이션(Hallucination): 근거 없는 사실을 만들어냈는가

이 지표들은 단순 문자열 비교로는 측정할 수 없다. 그래서 세 가지 측정 방식이 쓰인다.

  • LLM-as-Judge: GPT-4나 Claude를 심판으로 써서 출력 품질을 자동 채점
  • 휴리스틱 지표: BLEU, ROUGE 같은 텍스트 유사도 점수 (빠르지만 의미 파악 못함)
  • 임베딩 유사도: 기대 답변과 실제 출력의 의미적 거리를 벡터로 측정

핵심 Evals 도구 3종 비교 — DeepEval, Langfuse, Braintrust

2026년 현재 가장 많이 쓰이는 LLM 평가 도구는 세 가지로 정리된다. 포지션이 다르기 때문에 보통 두 가지를 조합해서 쓴다.

소규모 팀이라면 DeepEval + Langfuse 조합이 현실적이다. DeepEval로 CI 테스트를 붙이고, Langfuse로 프로덕션 트레이스를 수집해 품질 추세를 모니터링한다. Braintrust는 프롬프트 실험이 잦은 팀에 더 적합하다.

DeepEval CI pipeline screenshot
DeepEval을 GitHub Actions에 통합한 예 — PR마다 점수 리포트가 코멘트로 붙는다

LLM-as-Judge 패턴 — 자동 채점 설계 방법

LLM-as-Judge는 GPT-4나 Claude 같은 강력한 모델을 심판으로 써서 평가 대상 모델의 출력을 자동으로 채점하는 패턴이다. 사람이 직접 평가하는 Human Evaluation보다 빠르고, 단순 휴리스틱보다 의미를 더 잘 이해한다.

핵심은 루브릭(채점 기준) 설계다. 심판 모델에게 모호한 지시를 주면 채점 일관성이 떨어진다. 잘 설계된 루브릭은 다음 요소를 포함한다.

  • 0~5점 척도 정의: 각 점수가 무엇을 의미하는지 구체적으로 명시
  • 평가 차원 분리: 관련성, 완성도, 정확성을 각각 따로 채점
  • 근거 요청: 심판 모델이 점수와 함께 이유를 설명하도록 강제 (CoT)
  • 형식 고정: JSON 출력 강제로 파싱 오류 방지
LLM-as-Judge 루브릭 프롬프트 예시 (Python)
from openai import OpenAI import json client = OpenAI() def judge_response(question: str, answer: str, context: str) -> dict: prompt = f""" You are an expert evaluator for AI assistant responses. Evaluate the following response on two dimensions. Question: {question} Context: {context} Answer: {answer} Return JSON with this exact format: {{ "relevance": {{"score": 0-5, "reason": "..."}}, "faithfulness": {{"score": 0-5, "reason": "..."}} }} Scoring guide: - relevance 5: Directly and completely answers the question - relevance 3: Partially answers, some irrelevant content - relevance 0: Does not address the question at all - faithfulness 5: All claims are supported by the context - faithfulness 0: Contains claims not in the context (hallucination) """ response = client.chat.completions.create( model="gpt-4o", messages=[{"role": "user", "content": prompt}], response_format={"type": "json_object"} ) return json.loads(response.choices[0].message.content)
주의: LLM-as-Judge는 심판 모델에도 편향이 있다. GPT-4는 GPT 계열 출력을 약간 편호하고, Claude는 긴 답변에 더 높은 점수를 주는 경향이 있다. 같은 평가 세트를 여러 심판 모델로 돌려보거나, 주기적으로 Human Evaluation으로 심판 모델 자체의 정확도를 교차 검증하는 것이 좋다.

CI/CD 통합 실전 — PR마다 품질 게이트 붙이기

DeepEval을 GitHub Actions에 통합하면 PR이 열릴 때마다 LLM 출력 품질을 자동 검사하고, 점수가 임계값 아래로 떨어지면 merge를 차단할 수 있다.

DeepEval 유닛 테스트 예시 (Python)
# tests/test_rag_quality.py from deepeval import assert_test from deepeval.metrics import AnswerRelevancyMetric, FaithfulnessMetric from deepeval.test_case import LLMTestCase from my_rag_app import query_rag def test_rag_answer_quality(): # 실제 앱 함수를 호출해 테스트 케이스 생성 question = "What is the capital of France?" result = query_rag(question) test_case = LLMTestCase( input=question, actual_output=result["answer"], retrieval_context=result["source_docs"] ) assert_test(test_case, metrics=[ AnswerRelevancyMetric(threshold=0.7), FaithfulnessMetric(threshold=0.8) ])
GitHub Actions 워크플로우 (.github/workflows/evals.yml)
name: LLM Quality Gate on: pull_request: branches: [main] jobs: evals: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Set up Python uses: actions/setup-python@v5 with: python-version: '3.11' - name: Install dependencies run: pip install deepeval pytest - name: Run LLM evals env: OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }} run: | deepeval test run tests/test_rag_quality.py
Langfuse dashboard production LLM monitoring
Langfuse 대시보드 — 실서비스 LLM 요청의 지연시간, 토큰 사용량, 품질 지표를 한눈에 확인

Offline Evals vs Online Evals — 각각 언제 쓰는가

LLM 평가는 사용 시점에 따라 두 종류로 나뉜다. 둘을 혼동하면 잘못된 지표를 보고 잘못된 결정을 내리게 된다.

  • Offline Evals (개발·테스트 단계): 고정된 테스트 데이터셋을 이용해 배포 전에 실행. 속도보다 정확도가 중요하며, 실험적 변경(프롬프트 수정, 모델 교체)의 영향을 정량 비교하는 데 적합. DeepEval, Braintrust가 여기에 해당.
  • Online Evals (프로덕션 모니터링): 실제 사용자 요청을 실시간으로 샘플링해 품질을 추적. 오프라인에서 잡지 못한 엣지 케이스, 사용자 다양성에서 오는 품질 저하를 감지. Langfuse, Arize AI가 여기에 해당.

권장 워크플로우는 다음과 같다.

  1. Offline Evals로 골든 테스트셋 구성 (50~200개 케이스)
  2. CI/CD에 Offline Evals 통합 — 점수 임계값 설정
  3. 프로덕션 배포 후 Online Evals로 1~5% 요청 샘플링
  4. 품질 저하 감지 시 새 케이스를 골든 테스트셋에 추가 (피드백 루프)

골든 테스트셋 구성 — 처음 50개를 어떻게 만드는가

Evals 파이프라인을 구축하는 것보다 좋은 테스트 데이터를 만드는 것이 더 어렵다. 처음 골든 테스트셋을 구성하는 실용적인 방법은 세 가지다.

  • 실제 사용자 로그에서 추출: 프로덕션 로그에서 다양한 유형의 질문을 샘플링. 사용자가 실제로 묻는 것을 반영하므로 가장 현실적.
  • LLM으로 데이터 합성: 도메인 문서를 주고 GPT-4에게 질문-정답 쌍을 생성하도록 지시. 빠르지만 다양성이 부족할 수 있어 수동 검토 필수.
  • 실패 케이스 우선 수집: 사용자가 불만을 표시했거나, 재질문을 한 케이스를 수집. 회귀 방지에 가장 효과적.

첫 50개는 직접 작성해야 한다. LLM이 생성한 정답도 사람이 검토해 라벨링해야 한다. 처음부터 자동화하려고 하면 쓸모없는 테스트셋이 된다.

실무 팁: 테스트 케이스 수가 적어도 괜찮다. 50개짜리 잘 만든 골든 테스트셋이 500개짜리 허술한 테스트셋보다 훨씬 유용하다. 케이스마다 왜 이 질문이 중요한지, 정답의 기준이 무엇인지 주석을 남겨두면 나중에 다른 팀원이 유지보수하기도 쉽다.
LLM evaluation golden dataset spreadsheet
골든 테스트셋 구성 예 — 질문, 기대 출력, 컨텍스트, 라벨 태그를 포함

Evals 비용 관리 — 테스트마다 GPT-4를 부를 수 없는 이유

LLM-as-Judge를 모든 테스트 케이스에 적용하면 비용이 급증한다. GPT-4o 기준으로 케이스당 평균 0.01~0.05달러, 200개 케이스를 하루 10번 돌리면 월 수백 달러가 나올 수 있다.

비용을 줄이는 실용적인 방법이 있다.

  • 빠른 휴리스틱 먼저: ROUGE, 임베딩 유사도 같은 저비용 지표로 먼저 필터링하고, 경계선 케이스만 LLM-as-Judge로 판별
  • 소형 Judge 모델 활용: GPT-4o 대신 GPT-4o-mini나 Claude Haiku로 1차 채점하고, 불확실한 케이스만 대형 모델로 재채점
  • 캐싱: 동일한 입력-출력 쌍에 대한 Judge 결과를 캐시. 회귀 테스트에서 변경이 없는 케이스는 재평가 생략
  • 배치 처리: PR마다 전체 테스트를 돌리지 말고, 변경된 모듈과 관련된 케이스만 선택적으로 실행
LLM EvalsDeepEvalLangfuseBraintrustLLM-as-JudgeAI 품질 검증CI/CDRAGLLMOpsAI 프로덕션

관련 포스트

Meta Llama Stack 실전 가이드 — OpenAI 호환 API로 Llama 4 로컬·프로덕션 배포2026-04-14LLM 옵저버빌리티 도구 완전 비교 — LangSmith vs Langfuse vs Helicone 20262026-04-17Grok 4.20 완전 분석 — 4에이전트 병렬 추론, 내부 토론 메커니즘, API 실전 가이드2026-04-26xAI Grok 4.3 개발자 가이드 — Speech-to-Text·Text-to-Speech API 실전 활용2026-04-24