AI 시스템

RAG 문서 검색 시스템

완료

문서 청킹부터 임베딩·벡터 검색·답변 생성까지의 파이프라인을 순수 Python으로 한 번, LangChain으로 한 번 구현해 두 방식을 비교했습니다.

  • Python
  • sentence-transformers
  • LangChain
  • NumPy
RAG 파이프라인 — 색인 단계와 질의 단계
색인과 질의를 분리해 보면, 답변이 틀렸을 때 어느 단계를 볼지가 정해진다

BACKGROUND

RAG를 라이브러리 호출로만 익히면 문제가 생겼을 때 어디를 봐야 할지 모른다고 생각했습니다. 그래서 프레임워크 없이 직접 한 번 만들고, 같은 파이프라인을 LangChain으로 다시 만들어 각 컴포넌트가 무엇을 대신해주는지 대조했습니다.

WHAT I BUILT

프레임워크 없이 먼저 구현

sentence-transformers로 임베딩을 만들고 NumPy 코사인 유사도로 직접 검색했습니다. 청킹 크기와 겹침이 검색 품질을 어떻게 바꾸는지, 유사도 상위 문서가 왜 엉뚱하게 잡히는지를 코드를 직접 뜯어보며 확인했습니다.

같은 파이프라인을 LangChain으로 재구현

TextSplitter·Embeddings·VectorStore·Retriever가 앞서 직접 짠 어느 부분을 대체하는지 1:1로 대응시켰습니다. 프레임워크가 감춘 것과 대신해준 것을 구분할 수 있게 됐습니다.

로컬 모델로 전 구간 실행

외부 API 없이 로컬 트랜스포머 모델로 임베딩과 생성을 모두 처리했습니다. 비용 없이 반복 실험할 수 있었고, 모델 크기와 응답 품질의 트레이드오프를 직접 체감했습니다.

생성 품질 문제 진단

답변 중간에 다른 언어가 섞여 나오는 현상을 만났습니다. 검색 결과 문제인지 생성 파라미터 문제인지 분리해서 확인했고, repetition_penalty를 1.15 부근으로 조정해 안정화했습니다.

WHAT I LEARNED

RAG의 답변 품질은 대부분 생성이 아니라 검색 단계에서 갈렸습니다. 엉뚱한 답이 나오면 모델보다 먼저 청킹과 검색 결과를 봐야 했습니다.

증상만 보고 파라미터를 만지면 재현이 안 됩니다. 검색 단계와 생성 단계를 나눠 원인을 좁히는 습관이 남았습니다.

다음 과제로 BM25 키워드 검색을 붙인 하이브리드 검색을 준비하고 있습니다. 임베딩 검색이 고유명사에 약한 지점을 보완하려는 목적입니다.