실행 프로그램과 확장

로컬 LLM·RAG 품질 평가: DeepEval로 바뀐 설정 검증하기

빠른 설정이 업무 답변까지 좋아졌는지는 따로 확인해야 합니다

업무 질문과 정답 근거를 고정하고, DeepEval으로 검색 문맥과 답변을 따로 채점합니다. Ollama를 평가 모델로 지정할 수 있으며, 점수는 원문 검토와 응답시간·메모리 기록을 함께 봐야 합니다.

실행 조건과 핵심 내용
  • 질문마다 기대 답과 검색되어야 할 문장을 기록합니다.
  • Contextual Recall로 검색 문맥을, Faithfulness로 답의 근거 여부를 봅니다.
  • Ollama를 평가 모델로 지정하고 deepeval test run을 실행합니다.
  • 평가 점수와 검색·첫 토큰·생성 시간 및 최대 메모리를 함께 저장합니다.

휴가 규정 질문 20개를 먼저 정답과 함께 적습니다

예시로 사내 휴가 규정 PDF를 검색하는 RAG1를 평가하겠습니다. ‘입사 6개월 차 직원도 여름휴가를 쓸 수 있나요?’처럼 답이 문장 하나에 있는 질문, 표의 예외 조건을 찾아야 하는 질문, 문서에 답이 없는 질문을 섞어 20개를 준비합니다. 각 행에 질문, 기대 답, 반드시 검색되어야 할 근거 문장 또는 ‘문서에 근거 없음’을 적습니다. 실제 업무 질문에서 뽑되, 개인정보나 기밀 문서 원문을 평가 서비스로 보내도 되는지 먼저 확인합니다.

비교할 기준 실행을 먼저 저장한 뒤 모델, 양자화2, 청크 설정 중 하나만 바꾸세요. 두 설정에 같은 질문과 같은 정답을 적용해야 질문 구성 차이를 성능 차이로 착각하지 않습니다. 다만 문서 내용이나 기대 답이 바뀌었다면 질문 세트도 버전을 올려 함께 기록해야 합니다.

서로 다른 유형의 질문과 근거를 고르게 배치한 평가 세트
쉬운 질문과 어려운 질문, 짧은 입력과 긴 입력을 실제 사용 비율에 맞춰 섞습니다.

검색 근거와 답변을 따로 채점합니다

검색이 실패했는지 답변이 실패했는지를 구분하려면 평가 데이터에 입력, 기대 답, 모델 답변, 검색된 근거를 함께 넣어야 합니다. DeepEval의 ContextualRecallMetric은 기대 답에 필요한 내용이 검색 문맥에 있는지 살피고, FaithfulnessMetric은 생성 답이 검색 문맥을 벗어나지 않았는지 살핍니다. AnswerRelevancyMetric은 답이 질문에 직접 답하는지 확인하는 데 쓸 수 있습니다. 세 지표가 같은 것을 재는 건 아니므로 질문별 점수와 판정 이유를 나란히 읽으세요.

RAG 점수만으로 규정 위반을 판정하지 마세요. 평가 모델은 문장 의미를 자동으로 비교하는 보조자이지 정답 자체가 아닙니다. ‘6개월 이상’ 같은 필수 조건이 빠지면 실패로 봐야 하는 질문은 실제 검색 문장과 답을 사람이 확인합니다. DeepEval의 LLM3 기반 지표는 별도 평가 모델을 호출하므로, 로컬에서 실행하는 애플리케이션이라고 평가까지 자동으로 로컬이 되는 것은 아닙니다.

자동 평가 결과를 원문과 함께 검토하는 사람
작은 점수 차이는 원문과 판정 이유를 사람이 함께 확인합니다.

평가 모델도 로컬로 지정하고 첫 테스트를 실행합니다

DeepEval 공식 문서는 Ollama를 로컬 평가 모델로 설정하는 방법을 제공합니다. Ollama를 설치하고 서버를 실행한 뒤, 프로젝트의 새 Python 가상환경4에 DeepEval을 설치합니다. ollama pull deepseek-r1:1.5b는 예시 평가 모델을 내려받고, deepeval set-ollama --model=deepseek-r1:1.5b는 DeepEval의 기본 평가 모델을 그 모델로 지정합니다. 이미 가진 모델을 쓴다면 ollama list에 표시된 이름을 사용하세요. 여기서 평가하는 것은 앱의 답변 품질이므로, 아래 테스트 코드의 예시 답변과 검색 조각을 실제 RAG 실행 결과로 바꿔야 합니다.

다음 예시는 휴가 규정에서 자격 조건을 검색해 답한 한 건을 시험합니다. 먼저 이 파일을 test_rag.py로 저장하고 deepeval test run test_rag.py를 실행해 Ollama 평가 모델이 실제로 연결되는지 확인하세요. 설치·다운로드 단계는 네트워크가 가능한 준비 환경에서 해야 합니다. 모델을 받을 수 없거나 폐쇄망에서 평가자 연결을 검증하지 못했다면 실행 결과를 확인한 것으로 간주할 수 없습니다. 지표 점수 기준도 예시일 뿐, 조직의 필수 질문과 사람 검토 결과에 맞춰 정해야 합니다.

Ollama 모델을 준비하고 위 명령을 실행할 수 없는 환경이라면 이 절차를 로컬 실행 완료로 간주하지 마세요. 테스트 코드를 준비해도 평가 모델 연결이 검증되기 전까지 결과는 나오지 않습니다. 또한 평가 결과를 Confident AI 같은 외부 서비스로 동기화하거나 로그인하면 실행 기록이 기기를 떠날 수 있으므로, 폐쇄망에서는 로컬 결과 저장과 네트워크 차단 상태를 별도로 확인해야 합니다.

설치와 로컬 평가 모델 설정
python -m venv .venv
source .venv/bin/activate
pip install -U deepeval
ollama pull deepseek-r1:1.5b
deepeval set-ollama --model=deepseek-r1:1.5b
Ollama 모델을 로컬에 내려받고 DeepEval의 기본 평가 모델로 지정합니다. 이미 설치한 Ollama 모델은 이름을 바꿔 사용하세요.
test_rag.py
from deepeval import assert_test
from deepeval.metrics import (
    AnswerRelevancyMetric,
    ContextualRecallMetric,
    FaithfulnessMetric,
)
from deepeval.test_case import LLMTestCase


def test_vacation_policy_answer():
    test_case = LLMTestCase(
        input="입사 6개월 차 직원도 여름휴가를 쓸 수 있나요?",
        actual_output="입사 후 6개월 이상이면 여름휴가를 신청할 수 있습니다.",
        expected_output="입사 후 6개월 이상이면 여름휴가를 신청할 수 있습니다.",
        retrieval_context=[
            "여름휴가는 입사 후 6개월 이상 근무한 직원이 신청할 수 있습니다."
        ],
    )
    assert_test(
        test_case,
        [
            ContextualRecallMetric(threshold=0.5),
            FaithfulnessMetric(threshold=0.5),
            AnswerRelevancyMetric(threshold=0.5),
        ],
    )
코드는 테스트 연결 예시입니다. 실제 평가에서는 actual_output과 retrieval_context를 내 RAG의 기록으로 채웁니다. 0.5는 지표의 시작 기준일 뿐 업무 통과선을 뜻하지 않습니다.

통과 기준을 정한 뒤 속도와 메모리를 비교합니다

각 실행 기록에 답변 모델과 양자화, 청크 크기, 임베딩 모델, 평가 모델 이름과 버전, 첫 토큰5 대기시간, 생성 속도, 검색 시간, 최대 메모리를 함께 남깁니다. 같은 질문 세트의 평가 점수만 놓고 보면 빨라진 구성이 실제 사용에서 얼마나 기다리게 하는지 알 수 없고, 속도만 보면 중요한 조건을 빠뜨렸는지 놓칩니다.

선택은 전체 평균 하나로 끝내지 마세요. 휴가 자격처럼 반드시 맞아야 할 질문의 실패 개수 또는 통과율을 먼저 정하고, 그 기준을 넘긴 구성 사이에서 속도와 메모리를 비교합니다. 예를 들어 필수 질문에서 ‘근거 없음’을 근거가 있는 답처럼 말하는 구성은 평균 점수가 높아도 제외할 수 있습니다. 점수 차이가 작거나 판정 이유가 이상한 항목은 원문, 검색 조각, 답변을 사람이 확인한 뒤 다음 설정을 비교하세요.

빠른 답변과 근거가 충실한 답변을 나란히 비교하는 장비
품질 기준을 먼저 통과시킨 뒤 그 안에서 더 빠르고 저렴한 구성을 고릅니다.

용어 각주

  1. 검색 증강 생성 — 질문과 관련된 자료를 검색해 모델 입력에 보태고 답변을 생성하는 방식입니다. 검색 범위와 자료 품질은 구현에 따라 다릅니다.

    본문으로 돌아가기
  2. 양자화 — 모델의 수치를 더 적은 비트로 표현하는 방법입니다. 메모리 사용량과 함께 정확도나 실행 속도도 달라질 수 있으며, 영향은 형식과 구현에 따릅니다.

    본문으로 돌아가기
  3. 대규모 언어 모델 — 대량의 텍스트 데이터로 학습해 텍스트를 처리하고 생성하는 언어 모델입니다. 기능과 지원 입력은 모델마다 다릅니다.

    본문으로 돌아가기
  4. Python 가상환경 — 프로젝트별로 Python 패키지를 분리해 설치하는 공간입니다. 패키지 버전 충돌을 줄이며 가상 머신과는 다릅니다.

    본문으로 돌아가기
  5. 토큰 — 모델이 입력이나 출력을 나누어 처리하는 단위입니다. 토큰 하나가 글자 하나나 일정한 시간 길이에 해당하지는 않습니다.

    본문으로 돌아가기