RAG 앱을 만들고 내가 어떤 차를 좋아하는지 물어봤다. 하지만 앱은 몰랐다.

저는 Kenning이라는 문서 채팅 도구를 만들고 있습니다. 이 도구는 RAG(Retrieval-Augmented Generation)를 사용하여 사용자가 업로드한 파일에 대해 질문할 수 있게 해줍니다.

저는 다음과 같은 기술을 사용하여 전체 파이프라인을 처음부터 구축했습니다:

  • Java 21 및 Spring Boot
  • Spring AI
  • pgvector를 사용하는 PostgreSQL
  • Ollama (llama3.2:3b 및 nomic-embed-text 실행)
  • Docker Compose

파이프라인은 다음과 같이 작동합니다: 파일 업로드 → 텍스트 추출 → 텍스트 청킹(Chunking) → 청크를 벡터로 변환 → pgvector에 저장 → 유사한 청크 검색 → 청크 + 질문을 모델로 전송 → 출처와 함께 답변 획득.

시스템은 작동했지만, 두 가지 서로 다른 실패를 겪었습니다. 겉보기에는 비슷해 보였지만 원인은 달랐습니다.

실패 1: 모델이 혼란을 겪음.

질문: "이 프로젝트는 어떤 임베딩 모델을 사용하나요?" 문서에는 정답이 명시되어 있었습니다. 모델은 올바른 텍스트를 검색해 왔습니다. 하지만 모델은 모른다고 답변하면서도, 바로 다음 문장에서 정답인 모델 이름을 반복하는 모순을 보였습니다.

제 가설: 3B 모델이 너무 작습니다. 올바른 데이터를 검색했지만, 확신을 가지고 답변을 내놓지 못했습니다. 더 큰 모델을 사용하면 해결될 가능성이 높습니다.

실패 2: 모델이 아무것도 찾지 못함.

질문: "내가 좋아하는 자동차 브랜드는 무엇인가요?" 문서에는 제가 BMW를 좋아한다고 언급되어 있었습니다. 하지만 시스템은 검색 결과가 0건이었습니다. 유사도 점수(similarity score)가 제가 설정한 임계값을 통과하기에는 너무 낮았습니다.

제 가설: 청크 희석(Chunk dilution). 테스트 문서가 짧았습니다. Spring AI, OAuth2, 그리고 자동차 선호도와 같은 여러 주제가 하나의 청크에 섞여 있었습니다. 그 청크의 벡터는 이 모든 주제에 걸쳐 희석되었습니다. 자동차에 대한 구체적인 질문이 광범위한 청크의 힘을 이기지 못한 것입니다. 더 나은 청킹 전략을 사용하면 해결될 문제입니다.

배운 점:

  • 작은 모델은 추론 능력에 한계가 있다.
  • 단순한(Naive) 청킹 방식은 검색 정확도에 영향을 미친다.
  • 단순히 오류를 고치는 것보다 "왜" 그런 일이 일어났는지 디버깅하는 것이 더 중요하다.

아키텍처는 견고합니다. 느리고 때로는 틀리기도 하지만, 전체적인 루프는 완성되었습니다.

Source: https://dev.to/mido-dev/i-built-a-rag-app-then-asked-it-what-car-i-like-it-didnt-know-583n

Optional learning community: https://t.me/GyaanSetuAi