상세 컨텐츠

본문 제목

RAG 파이프라인 완벽 이해하기

본문

안녕하세요! 오늘도 AI 분야의 개발자가 되기 위해 도전 중인 하킴입니다.

오늘은 LangChain 학습의 꽃이라고 할 수 있는 RAG(Retrieval-Augmented Generation) 시스템을 직접 구현해 본 과정을 정리해 보려 합니다.

단순히 LLM에게 질문하는 것을 넘어, "내가 가진 PDF 논문이나 특정 웹사이트 데이터를 바탕으로 답변하게 만들기"가 이번 실습의 핵심이었는데요.

폴더에 있는 5개의 단계별 코드를 하나씩 실행하며 깨달은 점들을 공유합니다!


💡 RAG가 뭐야?

RAG는 쉽게 말해 "LLM에게 전용 참고서를 쥐어주는 기술"입니다. 모델이 모르는 외부 데이터를 찾아서(Retrieval), 질문과 함께 전달해 답변을 생성(Generation)하는 방식이죠.

학습 중인 파이프라인의 흐름은 다음과 같습니다:

  1. 문서 처리: Loader → Splitter → Embedding → VectorStore (데이터 주머니 만들기)
  2. 질문 처리: Question → Embedding → Retriever → LLM → Answer (답변 받기)

📁 실습 폴더 및 데이터 준비

실습은 총 5단계로 구성된 Python 스크립트로 진행했습니다. 데이터는 제가 평소 관심 있던 Spotify 음악 인기도 예측 논문(PDF)Spotify Research 블로그를 활용했습니다!

  • PDF: predicting_music.pdf (2025년 최신 논문!)
  • Web: Spotify Research 공식 블로그

🛠️ 단계별 삽질(?)과 배움의 기록

 

1단계 :  데이터 불러오기

처음엔 단순히 텍스트를 읽어오는 줄 알았는데, LangChain에서는 Document라는 객체(텍스트 + 메타데이터)로 다루는 게 중요하더라고요.

  • 느낀 점: PyPDFLoader를 쓰니 논문의 페이지 번호나 출처가 자동으로 메타데이터에 담기는 게 정말 편했습니다.

 

2단계 :  텍스트 잘게 쪼개기

논문은 너무 길어서 한 번에 LLM에 넣을 수 없죠. 그래서 '청크(Chunk)' 단위로 자르는 과정이 필수입니다.

  • 실험 결과: chunk_size를 200, 500, 1000으로 바꿔가며 테스트해 봤는데, 논문 같은 기술 문서는 500자 내외에 50자 정도 겹치게(overlap) 설정하는 것이 문맥 파악에 가장 좋았습니다.

 

3단계 : 숫자로 변환하기

컴퓨터가 글자를 이해할 수 있게 벡터(숫자 리스트)로 바꾸는 단계입니다.

  • 직접 해보니: 코사인 유사도를 계산해 보니까, 정말로 "음악"과 관련된 문장끼리 높은 점수가 나오는 게 신기했습니다. 벡터 공간에서 비슷한 주제끼리 뭉쳐 있는 걸 보니 "이게 진짜 AI의 이해 방식이구나" 싶었죠.

 

4단계 : 데이터 저장소 구축

임베딩된 데이터들을 저장하고 필요할 때 꺼내 쓰는 '데이터 주머니'를 만듭니다.

  • Chroma vs FAISS: 저는 로컬에 파일로 저장하고 관리하기 편한 ChromaDB가 더 직관적으로 느껴졌어요. 특히 MMR(Maximum Marginal Relevance) 검색을 써보니, 중복된 답변을 피하고 다양한 근거를 찾아주는 게 인상적이었습니다.

 

5단계 :  통합!

드디어 앞선 조각들을 하나로 합쳤습니다.

Python
 
# 내가 작성한 핵심 LCEL 체인
rag_chain = (
    {"context": retriever | format_docs, "question": RunnablePassthrough()}
    | prompt | llm | StrOutputParser()
)

 

실제 결과: "CNN 모델의 정확도가 뭐야?"라고 물었더니, 논문 구석에 있던 95.68%라는 숫자를 정확히 찾아내 답변했습니다! 😲


🎓 생각할 점

실습을 마치며 학생 입장에서 몇몇 생각이 들었습니다.

  1. 쓰레기를 넣으면 쓰레기가 나온다(GIGO): 데이터 로딩 단계에서 전처리가 제대로 안 되면 검색 품질이 확 떨어집니다.
  2. 한국어의 벽: 실습용 all-MiniLM-L6-v2 모델은 영어 논문에는 강하지만, 한국어 데이터에는 조금 약한 모습을 보였습니다. 향후 프로젝트를 진행할 때 BGE-M3 같은 다국어 모델을 활용하는 방안도 염두해야겠습니다.
  3. 검색이 전부다: LLM 성능보다, 질문에 맞는 정확한 문서를 찾아오는 Retriever의 성능이 전체 서비스 품질을 결정한다는 걸 깨달았습니다.

⚙️ 사용 기술 스택

구분 기술
LLM Ollama (llama3.2:3b)
임베딩 HuggingFace all-MiniLM-L6-v2 (384차원)
벡터 저장소 ChromaDB, FAISS
프레임워크 LangChain, LCEL
데이터 소스 PDF (PyPDFLoader), Web (WebBaseLoader)

 


🏃 차기 학습 계획

다음 공부는 이 Retriever를 더 똑똑하게 만드는 전략을 배울 예정입니다!

  • 질문을 여러 개로 변환해서 검색하는 MultiQuery
  • 키워드와 의미 검색을 섞는 Ensemble
  • 이전 대화를 기억하는 대화형 RAG

RAG의 세계는 파면 팔수록 깊네요. 포기하지 않고 끝까지 달려보겠습니다!

질문이나 의견은 댓글로 언제든 환영합니다. 🙌

 

관련글 더보기