본문 바로가기

이 게시물은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다

스타트업 투자/데이터 + 테크

패스트캠퍼스 환급챌린지 46일차 : LLM 정량 평가 강의 후기

by Sungwook Choi 2025. 5. 16.

본 포스팅은 패스트캠퍼스 환급 챌린지 참여를 위해 작성하였습니다.

*_1. 학습 인증샷 4장 이상 포함
*_① 오늘자 날짜, 공부 시작 시각 포함 사진 1장

② 오늘자 날짜, 공부 종료 시각 포함 사진 1장

 

③ 1개 클립 수강 인증 사진 (강의장 목록 캡쳐, 강의 내용이 담긴 수강화면이 보이지 않도록) 1장

④ 학습 인증샷 1장 이상 (ex. 필기 촬영, 작업물, 등)

2. 학습 후기 700자 이상 (공백 제외)

코드 정리

def evaluate_rag_with_llm(questions, contexts, predictions, labels):
    """
    LLM 평가 메트릭으로 RAG 시스템 평가

    Args:
        questions: 질문 리스트
        contexts: 검색 결과 리스트
        predictions: 예측 리스트
        labels: 레이블 리스트

    Returns:
        평가 결과가 포함된 데이터프레임
    """

    # 결과를 저장할 리스트
    results = []

    # 평가 프롬프트
    prompt_template = """
당신은 RAG(Retrieval-Augmented Generation) 시스템 평가 전문가입니다. 아래 정보를 바탕으로 생성된 답변의 품질을 철저히 평가해주세요.

질문: {question}

검색된 컨텍스트:
{context}

생성된 답변:
{prediction}

참조 답변(정답):
{label}

다음 4가지 평가 기준으로 1-5점 척도로 점수를 매겨주세요:

1. 응답 정확성 (Answer Correctness) [1-5]:
   * 생성된 답변이 참조 답변과 비교하여 정확하고 완전한 정보를 제공하는지 평가
   * 1점: 완전히 잘못된 정보
   * 2점: 부분적으로 관련된 정보를 담고 있으나 대부분 부정확함
   * 3점: 정확한 정보와 부정확한 정보가 혼재되어 있음
   * 4점: 대부분 정확하지만 일부 정보가 누락되거나 미미한 오류가 있음
   * 5점: 참조 답변과 비교했을 때 완전히 정확하고 포괄적인 정보를 제공함

2. 컨텍스트 관련성 (Context Relevance) [1-5]:
   * 검색된 컨텍스트가 질문에 대답하기 위해 관련성이 높은지 평가
   * 1점: 컨텍스트가 질문과 전혀 관련이 없음
   * 2점: 컨텍스트가 질문과 간접적으로만 관련됨
   * 3점: 컨텍스트 중 일부만 질문과 직접적으로 관련됨
   * 4점: 대부분의 컨텍스트가 질문과 직접적으로 관련됨
   * 5점: 모든 컨텍스트가 질문에 완벽하게 관련되어 있고 불필요한 정보가 없음

3. 컨텍스트 충실성 (Context Faithfulness) [1-5]:
   * 생성된 답변이 주어진 컨텍스트에만 기반하는지, 아니면 없는 정보를 추가했는지 평가
   * 1점: 답변이 컨텍스트에 없는 정보로만 구성됨 (심각한 환각)
   * 2점: 답변이 주로 컨텍스트에 없는 정보로 구성됨
   * 3점: 답변이 컨텍스트 정보와 없는 정보가 혼합되어 있음
   * 4점: 답변이 주로 컨텍스트에 기반하지만 약간의 추가 정보가 있음
   * 5점: 답변이 전적으로 컨텍스트에 있는 정보만을 사용함

4. 컨텍스트 충분성 (Context Recall) [1-5]:
   * 검색된 컨텍스트가 질문에 완전히 답변하기에 충분한 정보를 포함하는지 평가
   * 1점: 컨텍스트가 답변에 필요한 정보를 전혀 포함하지 않음
   * 2점: 컨텍스트가 필요한 정보의 일부만 포함함
   * 3점: 컨텍스트가 필요한 정보의 약 절반을 포함함
   * 4점: 컨텍스트가 필요한 정보의 대부분을 포함하지만 일부 누락됨
   * 5점: 컨텍스트가 질문에 완전히 답변하기 위한 모든 필요한 정보를 포함함

반드시 다음 JSON 형식으로만 응답하세요. 마크다운은 사용하지 않습니다.:
{
  "answer_correctness": 정수로 된 점수(1-5),
  "context_relevance": 정수로 된 점수(1-5),
  "context_faithfulness": 정수로 된 점수(1-5),
  "context_recall": 점수(1-5),
  "analysis": "종합적인 분석 의견"
}

다른 형식의 응답은 하지 마세요. 오직 마크다운이 아닌 JSON만 반환하세요.
"""

    # 각 항목에 대해 평가 수행
    for i in tqdm(range(len(questions)), total=len(questions), desc="RAG 평가 진행 중"):
        try:
            # 프롬프트 생성 - format 대신 replace 사용
            prompt = prompt_template
            prompt = prompt.replace("{question}", str(questions[i]) if questions[i] is not None else "")
            prompt = prompt.replace("{context}", str(contexts[i]) if contexts[i] is not None else "")
            prompt = prompt.replace("{prediction}", str(predictions[i]) if predictions[i] is not None else "")
            prompt = prompt.replace("{label}", str(labels[i]) if labels[i] is not None else "")

            # GPT-4 API 호출
            response = client.chat.completions.create(
                model="gpt-4o",
                messages=[
                    {"role": "system", "content": "당신은 RAG 평가 도구입니다. 반드시 유효한 JSON 형식으로만 응답하세요."},
                    {"role": "user", "content": prompt}
                ],
                temperature=0,
                response_format={"type": "json_object"}
            )

            # 결과 파싱
            result = json.loads(response.choices[0].message.content)

            # 개별 메트릭 점수 추출
            answer_correctness = result['answer_correctness']
            context_relevance = result['context_relevance']
            context_faithfulness = result['context_faithfulness']
            context_recall = result['context_recall']

            # 총점 직접 계산 (개별 메트릭의 합)
            total_score = answer_correctness + context_relevance + context_faithfulness + context_recall

            # 원본 데이터와 평가 결과 결합
            row_result = {
                'id': i,
                'question': questions[i],
                'answer_correctness': answer_correctness,
                'context_relevance': context_relevance,
                'context_faithfulness': context_faithfulness,
                'context_recall': context_recall,
                'total_score': total_score,
                'analysis': result['analysis']
            }

            results.append(row_result)

        except Exception as e:
            print(f"항목 {i} 평가 중 오류 발생: {e}")
            results.append({
                'id': i,
                'question': questions[i],
                'error': str(e)
            })

    # 결과 데이터프레임 생성
    results_df = pd.DataFrame(results)

    # 요약 통계 계산
    if 'total_score' in results_df.columns:
        metrics_summary = {
            '평균 총점': results_df['total_score'].mean(),
            '응답 정확성 평균': results_df['answer_correctness'].mean(),
            '컨텍스트 관련성 평균': results_df['context_relevance'].mean(),
            '컨텍스트 충실성 평균': results_df['context_faithfulness'].mean(),
            '컨텍스트 충분성 평균': results_df['context_recall'].mean()
        }
        print("\n===== 평가 요약 =====")
        for metric, value in metrics_summary.items():
            print(f"{metric}: {value:.2f}")

    return results_df, metrics_summary if 'total_score' in results_df.columns else results_df

url : https://abit.ly/lisbva

댓글