상세 컨텐츠

본문 제목

RAG 미니 프로젝트 : 논문 읽어주는 챗봇 만들기

본문

Streamlit UI + RAGAS 정량 평가 연결

 

RAG는 만들었다.
그런데 이 시스템은 정말 잘 동작하고 있는 걸까?

 

 

3일차의 목표는 단순 구현이 아니었다.
이제부터는 측정 가능한 RAG 시스템으로 고도화하는 단계다.

 

오늘 진행한 내용은 크게 세 가지다.

  1. RAG 엔진 구조 재정리
  2. Streamlit 기반 실험 환경 구축
  3. RAGAS 기반 RAG 평가 자동화

이번 글의 핵심 키워드는 RAG 평가 자동화다.


왜 “평가”가 필요한가?

RAG(Retrieval-Augmented Generation)는 다음 구조를 가진다.

 
 
Query → Retriever → Context → LLM → Answer
 

문제는 여기서 발생한다.

  • Retriever가 잘못된 문서를 가져오면?
  • LLM이 context를 왜곡하면?
  • 답변이 그럴듯하지만 사실과 다르면?

이 모든 문제가 발생해도
겉으로 보기엔 “잘 되는 것처럼” 보인다.

그래서 이번 3일차의 핵심 질문은 이것이었다.

“이 RAG 시스템을 정량적으로 평가할 수는 없을까?”


RAG 엔진 구조 재정비

기존 코드는 단순 실행 중심이었다.
이번에는 실험 중심 구조로 정리했다.

📌 전체 아키텍처

 
 
Vector Store (FAISS)

Retriever (k 조절 가능)

LLM

Answer + Source Documents

Evaluation Module (RAGAS)
 

설계 의도는 명확하다.

  • Retriever 교체 가능
  • Embedding 교체 실험 가능
  • 평가 모듈 독립 실행 가능

 


핵심 코드

retriever = vectorstore.as_retriever(
    search_type="similarity",
    search_kwargs={"k": 3}
)

qa_chain = RetrievalQA.from_chain_type(
    llm=llm,
    retriever=retriever,
    return_source_documents=True
)

 

중요한 설계 포인트

  • k=3 → Context 과다 주입 방지
  • return_source_documents=True → 평가 데이터 확보

이 설정이 이후 RAG 평가 자동화의 핵심 기반이 된다.

 


실행 로그

  • 질문 입력
  • Retriever가 반환한 source_documents
  • LLM 최종 answer

 


Streamlit 기반 RAG 실험 환경 구축

CLI 기반 실험은 반복 테스트에 불편했다.

그래서 목표는 “RAG 실험을 웹 환경에서 실시간으로 가능하게 만들자”

 

 

기본 UI 구성

streamlit으로 간단하게 구현해봤다.

import streamlit as st

st.title("RAG 실험 환경")

query = st.text_input("질문을 입력하세요")

if query:
    result = qa_chain({"query": query})
    st.write(result["result"])

 

Source Document 시각화

-> LLM의 hallucination 여부를 즉시 확인

 

for doc in result["source_documents"]:
    st.markdown("---")
    st.write(doc.page_content)

 

 

Streamlit 화면 로그

  1. 질문 입력 화면
  2. 답변 출력 화면
  3. Source 문서 출력 화면

이 3개가 들어가면 글의 신뢰도가 급격히 올라간다.

 


RAGAS 주요 지표

Context Precision 불필요한 문서가 얼마나 적은가
Context Recall 필요한 문서를 얼마나 잘 가져왔는가
Faithfulness 답변이 context 기반인가
Answer Relevancy 질문과 관련 있는 답변인가

 

 

평가 데이터 구성

dataset = Dataset.from_dict({
    "question": questions,
    "answer": answers,
    "contexts": contexts,
})

 

RAGAS 실행 로그

  • metric별 점수
  • 평균 점수
  • 전체 출력 결과

 

RAG는 LLM보다 Retriever가 더 중요하다

Context Recall이 낮으면
LLM이 아무리 좋아도 답변 품질은 떨어진다.


 k 값은 Precision–Recall Trade-off 문제다

  • k ↑ → Recall 증가, Precision 감소
  • k ↓ → Precision 증가, 정보 부족 가능

이제는 감이 아니라 지표로 판단한다.


평가 자동화가 있어야 개선이 가능하다

이전 - “잘 되는 것 같은데요?”

이후 - “Context Recall이 낮아서 k값을 5로 조정했고, Faithfulness가 개선되었습니다.”

이 차이는 매우 크다.

 

 

 

현재는 pdf를 로드하여 해당 문서를 청크 단위별로 분리한 후 인덱스를 정렬하는 방식을 사용하고 있다.

이후 Ollama라는 로컬 LLM 모델을 사용해서 챗봇을 만들었다보니 답변에 정확도가 떨어지는 부분을 발견할 수 있었다.

해당 문제는 현재 pdf 문서는 올바르게 영문으로 분리되어 있다. 하지만 현재 input으로 사용자에게 질문을 한국어로 받고 있기 때문에 대답의 성능이 나오지 못하고 있었다. 이런 기초적인 실수.. 

이후 질문과 답변을 하는 모델을 교체하고 성능이 개선될 수 있었다.

크레딧과 미니 프로젝트로 활용할 수 있는 모델 중 내 환경과 적합하고 최대의 성능을 낼 수 있는 것이 Ollama라고 생각했지만 이후 openai를 활용한 방안도 얼마든지 확장이 가능하다.

 

 

요즘 논문을 많이 읽고 LLM을 활용하고 있다. 문라이트를 가장 많이 이용하지만 이 프로젝트를 해보니 나도 비슷한 서비스를 만들 수 있다는 생각이 들었다. 그래서 이후 Mac환경에서 팝업으로 이용할 수 있는 서비스를 만들어 보겠다.

관련글 더보기