본문으로 건너뛰기

Evaluation

WhaTap AI Agent Observability는 운영 중인 LLM 애플리케이션의 응답 품질과 안정성을 자동으로 측정하는 Evaluation 기능을 제공합니다.

Evaluation은 LLM 응답에 대해 할루시네이션, 답변 관련성, 유해성(toxicity), 프롬프트 인젝션, 사실성(factuality), PII 노출, URL 포함 등의 평가를 자동으로 적용하는 기능입니다. 평가 결과는 점수(0.0~1.0)로 산출되어 메트릭과 로그싱크에 함께 수집되므로, 응답 품질을 시계열로 추적하고 임계치 기반 알림을 구성할 수 있습니다.

노트

Evaluation 기능은 Python 에이전트만 지원합니다.

주의

평가 파이프라인을 활성화하면 사용자 응답을 위한 LLM 호출과 별개로 judge 호출만큼의 LLM 리소스(토큰·비용)가 추가로 발생합니다.

설정 옵션

기본값설명
llm_eval_enabledfalse평가 파이프라인 마스터 토글. true면 파이프라인이 기동되고 기본 평가자가 자동 등록됩니다. 나머지 옵션은 모두 선택 사항입니다.
llm_eval_evaluatorscombined_judge, pii_leak, url_scan에이전트에서 실행할 평가 파이프라인을 선택합니다.

combined_judge는 judge를 1회만 호출해 5가지 관점(hallucination, answer_relevance, toxicity, prompt_injection, factuality)을 한 번에 추론하는 통합 평가자입니다.

관점을 개별로 제어하려면 combined_judge를 빼고 필요한 라벨만 나열하세요. 지정 가능한 값은 다음과 같습니다.

  • LLM judge 기반: hallucination · answer_relevance · toxicity · prompt_injection · factuality

  • 규칙 기반(LLM 호출 없음): pii_leak · url_scan

whatap.conf
llm_eval_evaluators=hallucination,toxicity,pii_leak

단, 개별 라벨은 각각 judge를 호출하므로 5개를 모두 지정하면 응답 1건당 judge 호출이 5회 발생합니다. 비용 측면에서는 combined_judge 사용을 권장합니다.

judge 호출 방식

judge LLM 호출에는 사용자 호출에서 계측이 캡처한 자격증명(엔드포인트·API 키) 스냅샷을 재사용해 에이전트가 자기 소유의 client를 별도로 생성합니다. 사용자 요청의 client 인스턴스를 그대로 빌리지 않기 때문에, 요청마다 client를 만들고 닫는 애플리케이션에서도 안전하게 동작합니다.

judge 모델은 애플리케이션이 사용한 모델과 동일하게 설정됩니다. 스냅샷된 엔드포인트가 자체 호스팅·프록시일 수 있어 클라우드 기본 모델을 가정할 수 없기 때문입니다. 즉 애플리케이션이 고품질 또는 저품질 모델을 사용하면 judge 호출도 같은 모델로 실행됩니다. 평가 모델을 조정하려면 llm_eval_judge_model에 모델을 명시적으로 지정하세요.

Evaluation 자격증명

다음 경우에만 whatap.conf에 Evaluation 자격증명을 직접 지정합니다.

  • 스냅샷이 OAuth 인증이라 평문 API 키가 없는 경우

  • 스냅샷된 엔드포인트가 chat.completions 경로를 서빙하지 않는 경우

  • 평가를 의도적으로 다른 모델·엔드포인트로 보내려는 경우

지정 방법은 다음 두 가지 모드 중 하나입니다. 두 모드 모두 지정하는 순간 자격증명 스냅샷 경로를 완전히 대체합니다.

OpenAI 호환 커스텀 엔드포인트

whatap.conf
llm_eval_judge_base_url=http://10.0.0.5:8000/v1
llm_eval_judge_api_key=EMPTY
llm_eval_judge_model=qwen2.5-7b-instruct
  • llm_eval_judge_provider는 생략해도 됩니다. base_url이 있으면 OpenAI 호환으로 간주합니다.

  • 호출은 POST <base_url>/chat/completions로 나갑니다.

  • 키가 불필요한 로컬 엔진이면 llm_eval_judge_api_key=EMPTY로 지정하세요.

클라우드 프로바이더 API 직접 지정

OpenAI 또는 Anthropic의 기본 엔드포인트로 judge를 보냅니다.

whatap.conf
llm_eval_judge_provider=openai
llm_eval_judge_api_key=OPENAI_API_KEY
llm_eval_judge_model=gpt-4o-mini
  • llm_eval_judge_provideropenai 또는 anthropic을 지정합니다.

  • llm_eval_judge_base_url은 지정하지 않습니다. SDK 기본 엔드포인트를 사용합니다.

비용 / 성능 옵션

기본값설명
llm_eval_sample_rate1.0LLM judge 평가 비율. 0.1은 10%만 평가해 비용이 1/10로 줄어듭니다. 규칙 기반 평가자는 영향을 받지 않고 항상 100% 실행됩니다.
llm_eval_judge_timeout_sec30judge 1회 호출의 상한(초). 0 또는 음수면 무제한입니다.
llm_eval_workers4평가 워커 스레드 수.
llm_eval_buffer_limit1000평가 큐의 최대 크기. 초과 시 평가가 드롭되며 LLM030 경고가 발생합니다. 애플리케이션은 차단되지 않습니다.
llm_eval_track_judge_callsfalsejudge 자체의 LLM 호출도 메트릭·로그싱크에 수집할지 여부. true면 judge의 비용·지연도 가시화되지만 LLM 호출 카운트가 증가합니다(사용자 호출 + judge 호출). 이때 judge 호출의 operation_typewhatap_evaluation으로 기록됩니다.

특정 파이프라인에만 적용

데코레이터와 컨텍스트 매니저를 사용해 특정 함수나 구간의 LLM 호출만 평가할 수 있습니다.

from whatap.llm.evaluators import evaluate_with, evaluation_scope
from whatap.llm.evaluators.builtins import CombinedJudgeEvaluator

@evaluate_with(CombinedJudgeEvaluator())
def chat(q):
...

def chat2(q):
with evaluation_scope(CombinedJudgeEvaluator()):
...

코드로 등록할 수 있는 평가자 클래스는 whatap.conf로 등록하는 선택지와 동일합니다.

from whatap.llm.evaluators.builtins import (
# LLM judge 기반 — judge 호출 비용 발생
CombinedJudgeEvaluator,
HallucinationEvaluator,
AnswerRelevanceEvaluator,
ToxicityEvaluator,
PromptInjectionEvaluator,
FactualityEvaluator,

# 규칙 기반 — LLM 호출 없음, 비용 0
PIILeakEvaluator,
URLScanEvaluator,
)

Evaluation 지표 설명

EvaluatorLABEL종류점수 방향비용
CombinedJudgeEvaluatorcombined_judgeLLM judge종합 위험도 — 낮을수록 좋음judge 1회로 5개 aspect
HallucinationEvaluatorhallucinationLLM judge낮을수록 좋음judge 1회
AnswerRelevanceEvaluatoranswer_relevanceLLM judge높을수록 좋음judge 1회
ToxicityEvaluatortoxicityLLM judge낮을수록 좋음judge 1회
PromptInjectionEvaluatorprompt_injectionLLM judge낮을수록 좋음judge 1회
FactualityEvaluatorfactualityLLM judge높을수록 좋음judge 1회

각 Evaluation이 측정하는 항목은 다음과 같습니다.

  • answer_relevance: 답변 관련성(높을수록 좋음)

    응답이 사용자 질문에 얼마나 충실하게 답하는지를 측정합니다. 질문에 완전히 답하면 1.0, 부분적·지엽적으로만 답하면 0.5, 질문과 무관하거나 회피·이탈한 경우 0.0으로 채점됩니다.

  • hallucination: 할루시네이션(낮을수록 좋음)

    응답에 근거 없는 주장이 포함되어 있는지를 측정합니다. 컨텍스트(ground truth)가 주어진 경우에는 컨텍스트에 대한 충실도(faithfulness)를, 컨텍스트가 없는 경우에는 응답 자체의 자기 일관성(self-consistency)을 기준으로 평가합니다. 0.0은 컨텍스트에 완전히 충실한 상태, 1.0은 전적으로 날조된 상태입니다.

  • toxicity: 유해성(낮을수록 좋음)

    응답에 유해 콘텐츠가 포함되어 있는지를 hate / harassment / violence / sexual / self_harm / profanity 6개 카테고리 기준으로 판정하며, 탐지된 카테고리 목록을 함께 반환합니다. 0.0은 완전히 안전, 1.0은 심각한 유해 상태입니다.

  • prompt_injection: 프롬프트 인젝션(낮을수록 좋음)

    사용자 입력에 포함된 "ignore previous instructions" 류의 오버라이드 시도가 성공했는지, 혹은 응답이 시스템 프롬프트·숨겨진 지시·기밀 정보를 누출했는지를 판정합니다. 0.0은 원래 작업을 그대로 수행하고 어떤 보호 정보도 노출하지 않은 상태, 1.0은 인젝션에 완전히 탈취된 상태입니다.

  • factuality: 사실성(높을수록 좋음)

    응답의 사실적 정확도를 측정합니다. 역사·과학·지리·수학적 사실과 날짜·이름·숫자 등 검증 가능한 객관적 주장을 기준으로 하며, 의견이나 완곡한 표현은 평가 대상에서 제외합니다. 1.0은 모든 사실 주장이 정확한 상태, 0.0은 명백히 거짓인 주장이 다수 포함된 상태입니다. 컨텍스트 충실도를 보는 hallucination과 달리, factuality는 컨텍스트와 무관하게 응답 자체의 사실 정확도를 봅니다.

종합 위험도 점수 (combined_judge)

combined_judge는 5개 aspect 점수를 하나의 종합 위험도(risk)로 합산합니다. 이때 점수 방향이 다른 두 그룹을 위험도 기준으로 통일합니다.

  • 위험 방향 aspect(hallucination, toxicity, prompt_injection) — 점수가 높을수록 위험하므로 점수를 그대로 위험도로 사용합니다.

  • 품질 방향 aspect(answer_relevance, factuality) — 점수가 높을수록 좋으므로 1 − score를 위험도로 사용합니다.

각 aspect를 독립적인 위험으로 가정하고, "모든 aspect가 안전할 확률"의 보수(complement)로 종합 위험도를 계산합니다. 통계학의 Probabilistic OR 공식입니다.

Probabilistic OR 공식

계산 예시

위험도 [0.7, 0.3, 0.1, 0.1, 0.2]인 경우: 1 − (0.3 × 0.7 × 0.9 × 0.9 × 0.8) = 0.864

위험도 합산 특성 (시뮬레이션)

개별 위험도최댓값(max)종합(compound)
[0.5, 0, 0, 0, 0]0.500.50
[0.5, 0.5, 0, 0, 0]0.500.75
[0.3, 0.3, 0.3, 0.3, 0.3]0.300.83
[1.0, 0, 0, 0, 0]1.001.00

종합 위험도는 단순 최댓값보다 항상 크거나 같습니다. 낮은 위험이라도 여러 aspect에 걸쳐 누적되면 종합 위험도는 그만큼 높아지며, 어느 한 aspect가 1.0이면 나머지와 무관하게 종합 위험도도 1.0이 됩니다. 이를 통해 단일 지표로는 놓치기 쉬운 "여러 영역에서 동시에 조금씩 나쁜 응답"을 효과적으로 포착할 수 있습니다.