RAG 챗봇이 잘못된 답변을 내놓는 이유와 해결 방법
요약
RAG 챗봇이 부정확한 답변을 내놓는 주된 원인은 AI 모델 자체가 아니라 문서 준비 및 검색 과정의 실수에 있습니다. 이 글은 청크 크기, 중복 처리, 지저분한 데이터 전처리 등 실제 RAG 앱에서 발생할 수 있는 문제점과 구체적인 해결 방법을 제시합니다.
핵심 포인트
- 잘못된 답변 원인은 대부분 검색(Retrieval) 단계에 있음.
- 청크는 300~500단어 크기로 시작하고, 중복(overlap)을 추가해야 함.
- 스캔 PDF나 헤더/푸터 등 지저분한 데이터 전처리가 필수적임.
- 검색 결과가 부실할 경우 모델 사용을 막는 'No I Don't Know Path'를 구현해야 함.
사용자가 '문서로 채팅하기' 앱을 만들었습니다. PDF를 업로드하고 간단한 질문을 던졌더니, 답변이 틀리거나, 반만 맞거나, 아니면 완전히 지어낸 내용입니다.
혹시 이런 경험을 했다면, AI 모델 탓부터 하지 마세요. 대부분의 RAG(Retrieval-Augmented Generation) 앱에서 잘못된 답변은 문서 준비 및 검색 방식에 있는 몇 가지 간단한 실수에서 비롯됩니다. 어디를 봐야 하는지 알면 쉽게 고칠 수 있습니다.
이 글은 저의 RAG 시리즈 중 파트 2입니다. 파트 1에서는 간단한 'PDF로 채팅하기' 앱을 만들었습니다. 여기서는 실제 문서를 가지고 테스트할 때 나타나는 문제들을 해결합니다.
먼저, 문제가 어디 있는지 찾으세요
RAG 앱은 두 가지 작업을 수행합니다:
- 검색 (Retrieval): 질문에 맞는 문서 조각을 찾아냅니다.
- 생성 (Generation): 그 조각들을 사용하여 답변을 작성합니다.
대부분의 잘못된 답변은 검색 문제입니다. 모델이 올바른 텍스트를 본 적이 없기 때문에 잘 답변할 수 없는 것입니다. 아무것도 바꾸기 전에, 앱이 찾은 조각들(chunks)을 출력해 보세요:
relevant_chunks = search(index, chunks, query_embedding, top_k=3)
for chunk in relevant_chunks:
...
만약 답변이 그 조각들에 없다면, 검색(아래 문제 1~4 및 7)을 수정하세요. 만약 답변은 있지만 응답이 여전히 틀리다면, 프롬프트(문제 5 및 6)를 수정하세요.
문제 1: 청크가 너무 크거나 너무 작음
청크(chunks)가 너무 크면 하나의 조각에 여러 주제가 담겨 검색이 혼란스러워집니다. 반대로 너무 작으면, 그 자체로는 유용한 의미가 없는 조각이 됩니다.
해결 방법: 청크당 약 300~500단어로 시작하세요. 그런 다음 자신만의 질문으로 두세 가지 크기를 테스트하고 가장 잘 작동하는 것을 유지하세요.
for size in [200, 400, 600]:
chunks = chunk_text(text, chunk_size=size)
print(size, 'words ->', len(chunks), 'chunks')
...
문제 2: 청크 간에 중복이 없음
텍스트를 일정한 단어 수로 자르면, 문장이 반으로 나뉠 수 있습니다. 앞부분은 한 청크에 있고 뒷부분은 다른 청크에 있게 됩니다. 어느 청크도 전체 답변을 제공하지 못합니다.
해결 방법: 각 청크가 바로 앞 청크의 마지막 50단어 정도를 반복하도록 하세요.
def chunk_text(text, chunk_size=400, overlap=50):
words = text.split()
chunks = []
...
문제 3: PDF의 텍스트가 지저분한 경우
이것은 매우 흔하며 사람들이 확인하는 것을 잊습니다. 추출된 텍스트 자체가 나쁘면, 그 이후의 모든 것도 나쁩니다. 다음 사항들을 주의하세요:
- 스캔된 PDF. 이것들은 이미지이기 때문에 추출기가 빈 텍스트를 반환합니다.
- 헤더 및 푸터(Headers and footers).
prompt = f'''아래 컨텍스트만을 사용하여 질문에 답하세요.
만약 답변이 컨텍스트에 없다면, '문서에서 해당 내용을 찾을 수 없습니다.'라고 말하세요.
외부 지식은 사용하지 마세요.
...
문제 6: '모르겠다' 경로 부재 (No "I Don't Know" Path)
벡터 검색(vector search)은 문서에 질문과 가까운 내용이 전혀 없더라도 항상 무언가를 반환합니다. 확인 절차 없이 앱이 쓸모없는 청크(chunks)를 모델로 보내고, 모델은 어쨌든 최선을 다해 답변하려고 시도하게 됩니다.
해결책: 거리 차단값(distance cutoff)을 추가하세요. 충분히 가까운 청크가 없다면, 모델 사용을 건너뛰고 그 사실을 사용자에게 알려주세요.
def search_with_cutoff(index, chunks, query_embedding, top_k=4, max_distance=1.2):
distances, indices = index.search(np.array([query_embedding]), top_k)
results = []
...
적절한 max_distance는 사용자의 임베딩 모델에 따라 다르므로 1.2는 단지 시작점일 뿐입니다. 문서가 답변하는 몇 가지 질문과 그렇지 않은 몇 가지 질문에 대해 거리를 출력해 보세요. 그런 다음 두 그룹 사이의 숫자를 선택하세요.
문제 7: 잘못되거나 혼합된 임베딩 모델 (Wrong or Mixed Embedding Models)
여기에는 두 가지 실수가 있습니다:
- 문서 청크와 질문에 서로 다른 모델 사용. 숫자 값이 일치하지 않아 검색 결과가 무작위로 나옵니다. 이는 모델을 변경했지만 인덱스(index)를 다시 구축하는 것을 잊었을 때 자주 발생합니다.
- 다른 언어에 영어 전용 모델 사용. 문서가 타밀어, 힌디어 또는 다른 언어로 되어 있다면, 영어 모델은 검색을 제대로 수행하지 못합니다.
해결책: 둘 다 같은 모델을 사용하고, 모델을 변경했다면 전체 인덱스를 다시 구축하세요. 다른 언어의 경우, 다국어(multilingual) 모델을 시도해 보세요।
from sentence_transformers import SentenceTransformer
model = SentenceTransformer('paraphrase-multilingual-MiniLM-L12-v2')
...
문제 8: 출처 부재, 검증 불가 (No Sources, So No Way to Check)
앱이 답변만 보여주고 출처를 제시하지 않으면, 그 답변이 맞는지 알 수 없습니다. 그리고 틀렸을 때도 왜 틀렸는지 알 수 없습니다.
해결책: 모든 청크에 파일 이름과 페이지 번호를 저장하고, 답변과 함께 이를 표시하세요.
chunks_with_meta = [
{'text': chunk_text_value, 'file': 'manual.pdf', 'page': 12},
# 청크당 하나의 항목
...
출처(Sources)는 사용자가 답변을 신뢰하도록 돕고, 여러분이 디버깅하는 것을 더 빠르게 도와줍니다.
디버깅 체크리스트 (Your Debugging Checklist)
RAG 챗봇이 잘못된 답변을 내놓을 때, 이 목록을 순서대로 확인해 보세요:
- 추출된 텍스트를 출력해 보세요. 올바른가요?
- 검색된 청크들을 출력해 보세요. 정답이 그 안에 있나요?
- 청크 크기는 300~500 단어 정도이며, 일부 중복(overlap)이 있나요?
-
top_k값은 3에서 5 사이인가요? - 청크와 질문에 동일한 임베딩 모델을 사용했나요?
- 프롬프트에 "컨텍스트만 사용하라"는 지침이 있고, "찾을 수 없습니다(I could not find this)"라는 문구가 있나요?
- 거리 차단값(distance cutoff)을 설정했나요?
- 모든 답변과 함께 출처를 보여주고 있나요?
또 하나의 팁: 알려진 정답이 있는 테스트 질문 10개를 작성하여 변경할 때마다 실행해 보세요. 이렇게 하면 어떤 수정 사항이 도움이 되었는지, 아니면 상황을 악화시켰는지를 알 수 있습니다.
마무리 (Wrap-Up)
대부분의 RAG 문제는 AI 모델 자체에 관한 것이 아닙니다. 텍스트가 어떻게 정리(cleaned), 분할(split), 검색(searched)되고 모델로 전달되는지 방식에서 발생합니다. 이 부분들을 수정하면 답변이 훨씬 좋아집니다.
만약 모든 것을 직접 고치는 대신 작동하는 코드베이스를 시작점으로 원한다면, 제가 RAG 챗봇 소스코드 키트: **RAG Source code**을 만들었습니다.
이 문제들 중 어떤 것이 가장 와닿았나요? 댓글로 알려주시면 다음 부분에서 다뤄보겠습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기