> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sifi.life/llms.txt
> Use this file to discover all available pages before exploring further.

# 모델 평가

> 이 문서는 **[머신러닝](/training/09-machine-learning/overview)** 섹션의 일부입니다.

<CardGroup cols={1}>
  <Card title="MLflow Evaluate 기본과 Scorer — 기초" href="mlflow-evaluation-basics-basics">
    기본 개념과 핵심 기능
  </Card>

  <Card title="MLflow Evaluate 기본과 Scorer — 심화" href="mlflow-evaluation-basics-advanced">
    고급 패턴과 실전 활용
  </Card>
</CardGroup>

## 평가 데이터셋 설계 전략

### 효과적인 평가 데이터셋 구성

| 카테고리             | 비율  | 목적                 | 예시                             |
| ---------------- | --- | ------------------ | ------------------------------ |
| **Happy Path**   | 40% | 정상적인 질문에 올바르게 답하는지 | "반품 정책은?" → 정확한 정책 안내          |
| **Edge Case**    | 25% | 경계 조건, 모호한 질문 처리   | "반품" (맥락 없는 단어), 오타가 있는 질문     |
| **Out-of-Scope** | 15% | 범위 밖 질문에 적절히 거절하는지 | "오늘 날씨 어때?", "주식 추천해줘"         |
| **Adversarial**  | 10% | 악의적 질문에 안전하게 대응하는지 | Prompt Injection, Jailbreak 시도 |
| **Multi-turn**   | 10% | 대화 맥락을 유지하는지       | "배송 기간은?" → "좀 더 빠른 방법은?"      |

### 데이터셋 크기 가이드

| 단계           | 권장 크기        | 목적                     |
| ------------ | ------------ | ---------------------- |
| **초기 개발**    | 20\~50개      | 빠른 반복, 주요 문제 식별        |
| **품질 검증**    | 100\~300개    | 체계적 평가, 통계적 유의성 확보     |
| **프로덕션 게이트** | 300\~1000개   | 배포 전 최종 검증, CI/CD 게이트  |
| **지속 모니터링**  | 프로덕션 트레이스 기반 | 실제 사용 패턴 반영, 지속적 품질 관리 |

### Delta 테이블 기반 평가 데이터셋 관리

```python theme={null}
# 평가 데이터셋을 Delta 테이블로 중앙 관리
eval_df = spark.createDataFrame(eval_data)
eval_df.write.mode("overwrite").saveAsTable("catalog.ml.agent_eval_dataset_v1")

# 버전 관리: 데이터셋 변경 이력 추적
spark.sql("DESCRIBE HISTORY catalog.ml.agent_eval_dataset_v1")

# 이전 버전의 데이터셋으로 평가
eval_data_v0 = spark.read.option("versionAsOf", 0) \
    .table("catalog.ml.agent_eval_dataset_v1")
```

***

## 프로덕션 모니터링과의 연결

### 오프라인 평가 → 온라인 모니터링 연속체

| 단계            | 도구                              | 시점    | 목적                   |
| ------------- | ------------------------------- | ----- | -------------------- |
| **개발 평가**     | `mlflow.genai.evaluate()`       | 개발 중  | 프롬프트/RAG 품질 확인       |
| **CI/CD 게이트** | `mlflow.genai.evaluate()` + 임계값 | 배포 전  | 자동 품질 게이트 (통과/실패 판정) |
| **A/B 테스트**   | Model Serving + 트래픽 분할          | 배포 직후 | 신규 버전과 기존 버전 비교      |
| **프로덕션 모니터링** | Inference Table + 샘플링 평가        | 상시    | 품질 드리프트 감지           |

### MLflow Tracing → 평가 데이터셋 자동 생성

```python theme={null}
# 프로덕션 트레이스에서 평가 데이터셋 추출
production_traces = spark.table("catalog.ml.agent_inference_logs")

# 최근 7일의 실제 질문에서 평가 데이터 생성
new_eval_data = production_traces.filter(
    "timestamp >= DATE_SUB(CURRENT_DATE(), 7)"
).select(
    col("request.question").alias("inputs"),
    col("response.answer").alias("actual_response")
).limit(100)

# 전문가 검토 후 expected_response 추가 → 평가 데이터셋에 병합
```

***

## CI/CD 통합 패턴

### 자동 평가 파이프라인

```python theme={null}
# ci_evaluate.py — CI/CD 파이프라인에서 실행
import mlflow
import sys

# 평가 데이터셋 로드
eval_data = spark.table("catalog.ml.agent_eval_dataset_v1").toPandas().to_dict("records")

# 에이전트 로드
agent = mlflow.pyfunc.load_model("models:/catalog.ml.customer_agent@challenger")

# 평가 실행
results = mlflow.genai.evaluate(
    data=eval_data,
    predict_fn=agent.predict,
    scorers=[
        mlflow.genai.scorers.Correctness(),
        mlflow.genai.scorers.Safety(),
        mlflow.genai.scorers.RetrievalGroundedness(),
        mlflow.genai.scorers.Guidelines(
            guidelines=["답변은 한국어로 작성되어야 합니다"]
        )
    ]
)

# 품질 게이트: 임계값 확인
thresholds = \{
    "correctness/mean": 0.80,
    "safety/mean": 0.95,
    "retrieval_groundedness/mean": 0.85,
\}

failed = []
for metric, threshold in thresholds.items():
    actual = results.metrics.get(metric, 0)
    if actual \< threshold:
        failed.append(f"\{metric\}: \{actual:.2f\} \< \{threshold:.2f\}")

if failed:
    print("❌ Quality gate FAILED:")
    for f in failed:
        print(f"  - \{f\}")
    sys.exit(1)  # CI/CD 파이프라인 실패
else:
    print("✅ Quality gate PASSED — ready for deployment")
    # champion alias 업데이트
    client = mlflow.MlflowClient()
    challenger_version = client.get_model_version_by_alias(
        "catalog.ml.customer_agent", "challenger"
    ).version
    client.set_registered_model_alias(
        "catalog.ml.customer_agent", "champion", challenger_version
    )
```

### DABs (Databricks Asset Bundles)와 통합

```yaml theme={null}
# databricks.yml — 평가 작업 정의
resources:
  jobs:
    agent_evaluation:
      name: "agent-quality-gate"
      tasks:
        - task_key: evaluate
          notebook_task:
            notebook_path: ./notebooks/ci_evaluate
          existing_cluster_id: $\{var.cluster_id\}

      # 트리거: 모델이 등록되면 자동 실행
      trigger:
        pause_status: UNPAUSED
```

### 평가 결과 대시보드 연동

```python theme={null}
# 평가 결과를 Delta 테이블에 저장 → 대시보드로 추적
import pandas as pd
from datetime import datetime

eval_record = \{
    "timestamp": datetime.now(),
    "model_version": "challenger_v5",
    "correctness_mean": results.metrics["correctness/mean"],
    "safety_mean": results.metrics["safety/mean"],
    "groundedness_mean": results.metrics["retrieval_groundedness/mean"],
    "eval_dataset_size": len(eval_data),
    "passed": len(failed) == 0
\}

spark.createDataFrame([eval_record]).write.mode("append") \
    .saveAsTable("catalog.ml.evaluation_history")
```

***

## Edge Case와 주의사항

| 주의사항             | 설명                                                                         |
| ---------------- | -------------------------------------------------------------------------- |
| **LLM Judge 비용** | 대규모 평가 데이터셋에서 LLM Judge는 상당한 토큰 비용이 발생합니다. 1,000개 평가 시 약 $5~$20            |
| **Judge 모델의 편향** | LLM Judge도 자체적인 편향이 있습니다. 특히 장문의 답변을 더 높게 평가하는 경향이 있으므로, 정량적 Scorer와 병행하세요 |
| **비결정적 평가**      | LLM Judge의 점수는 매번 약간 다를 수 있습니다. 동일 데이터셋으로 반복 평가 시 ±5% 편차가 정상입니다            |
| **기대 답변 품질**     | 기대 답변(expected\_response)이 부정확하면 Correctness 점수가 의미 없어집니다. 전문가 검토가 필수입니다   |
| **평가 데이터 과적합**   | 평가 데이터셋에만 최적화하면 실제 성능과 괴리가 생깁니다. 주기적으로 프로덕션 트레이스에서 새 데이터를 추가하세요            |

***

## 정리

| 핵심 개념               | 설명                                                |
| ------------------- | ------------------------------------------------- |
| **MLflow Evaluate** | 모델/에이전트 품질을 자동으로 평가하는 프레임워크입니다                    |
| **Scorer**          | 평가 기준. Correctness, Safety, Guidelines 등 내장 + 커스텀 |
| **LLM Judge**       | LLM을 심판으로 사용하여 답변 품질을 자동 판단합니다                    |
| **평가 데이터셋**         | 질문 + 기대 답변으로 구성된 테스트 세트입니다                        |
| **CI/CD 통합**        | 품질 임계값을 설정하여 배포 전 자동 게이트를 구현합니다                   |
| **프로덕션 모니터링**       | 트레이스 기반으로 지속적으로 품질을 추적합니다                         |
| **반복 개선**           | 평가 → 개선 → 재평가 사이클로 품질을 높입니다                       |

***

## 참고 링크

* [Databricks: MLflow Evaluation](https://docs.databricks.com/aws/en/mlflow/llm-evaluate.html)
* [Databricks: Agent Evaluation](https://docs.databricks.com/aws/en/generative-ai/agent-evaluation/)
* [MLflow: Evaluate](https://mlflow.org/docs/latest/llms/llm-evaluate/index.html)
