RAG 챗봇이 여전히 환각을 일으키는 이유: 5가지 설계 실수와 해결 방법
요약
RAG 챗봇의 환각 현상은 모델 자체의 문제가 아닌, 상류 설계 단계에서 발생하는 구조적 실수들 때문입니다. 본문은 의미 단위로 청킹하고, 메타데이터를 활용해 데이터 신뢰성을 관리하며, 체계적인 평가 과정을 거치는 등 5가지 핵심 개선 방안을 제시합니다.
핵심 포인트
- 청크는 구조(제목/단락) 기반으로 분할하고 중복을 유지해야 합니다.
- 메타데이터에 출처, 버전, 날짜를 포함하여 데이터 신뢰성을 관리하세요.
- 테스트 세트를 구축하여 검색과 생성 성능을 측정하는 것이 필수입니다.
- 답변이 불가능한 경우 '모른다'고 명확히 말하도록 지시해야 합니다.
당신은 RAG 챗봇을 구축했습니다. 문서들은 인덱싱되었고, 벡터 데이터베이스는 정상적으로 작동하며, 데모도 성공적이었습니다. 그러다가 사용자가 환불 정책에 대해 질문하자, 봇이 작년에 폐지된 규칙을 자신감 있게 인용합니다.
RAG는 환각(hallucination)을 줄이는 것이 목적입니다. 실제로 그렇게 하지만, 검색(retrieval)이 좋을 때만 그렇습니다. 이 파이프라인은 두 단계로 이루어져 있습니다: 관련 텍스트를 찾고, 그 텍스트로부터 답변을 생성하는 것입니다. 만약 당신이 검색한 텍스트가 잘못되었거나, 불완전하거나, 오래되었다면, 모델은 그것을 바탕으로 매끄럽고 자신감 있는 답변을 기꺼이 작성할 것입니다.
대부분의 프로젝트에서 문제는 모델 자체가 아닙니다. 모델 상류(upstream)에 있는 설계 문제입니다. 여기 반복적으로 나타나는 다섯 가지 실수가 있습니다.
1. 의미를 반으로 자르는 청킹(Chunking)
모든 문서를 고정된 500 토큰 조각으로 나누는 것은 쉽습니다. 하지만 이것은 표도 반으로 자르고, 단계와 경고문을 분리하며, 정의에서 그 용어를 잘라냅니다. 청크 자체가 독립적으로 의미가 통하지 않는다면, 그것을 기반으로 만들어진 답변 역시 마찬가지일 것입니다.
해결책:
• 구조를 기준으로 먼저 분할하세요: 제목(headings), 단락(paragraphs), 목록 항목(list items)
• 인접한 청크 사이에 약간의 중복(overlap)을 유지하세요
• 모든 청크에 문서 제목과 섹션 제목을 첨부하세요
• 표와 단계별 목록은 함께 유지하세요
빠른 테스트: 무작위 청크 20개를 읽어보세요. 나머지 문서 없이도 각각 이해할 수 있습니까? 그렇지 않다면, 당신의 모델도 마찬가지일 것입니다.
2. 벡터 검색에만 의존하는 것
임베딩(Embeddings)은 의미를 파악하는 데는 뛰어나지만 정확한 일치(exact matches)에는 약합니다. 제품 코드, 오류 ID, 버전 번호, 이름 등은 종종 누락됩니다.
3. 오래되거나 상충되는 데이터 (Stale and conflicting data)
문서는 변경됩니다. 하지만 인덱스는 보통 그렇지 않습니다. 더 심각한 문제는, 정책의 오래된 버전과 새로운 버전이 모두 인덱스에 남아 있을 수 있으며, 리트리버(retriever)는 어떤 것이 최신인지 알 길이 없습니다.
해결 방법:
- 모든 청크(chunk)에 메타데이터(metadata) 저장: 출처(source), 버전(version), 최종 업데이트 날짜(last-updated date)
- 문서가 변경되거나 정기적인 일정에 따라 재인덱싱(re-index) 수행
ScaleDojo | 블로그 아티클 | 발행용 초안 페이지 2 - 구식화된(superseded) 버전은 제거하거나 필터링
- 답변에 출처와 날짜를 표시하여 사용자가 판단할 수 있도록 함
4. 평가가 없고, 느낌만 믿기 (No evaluation, just vibes)
'작동하는 것 같다'는 것은 측정 지표(metric)가 아닙니다. 측정 없이는 새로운 청크 크기가 도움이 되었는지 해로웠는지 알 수 없습니다.
해결 방법: 작은 테스트 세트(test set)를 구축합니다. 정확한 답변과 해당 내용을 담고 있는 문서를 포함하여 30~50개의 실제 질문으로 시작합니다. 그런 다음 두 가지를 별도로 측정합니다:
- 검색 (Retrieval): 올바른 청크가 상위 결과에 포함되었는가?
- 생성 (Generation): 최종 답변이 실제로 검색된 텍스트로 뒷받침되는가?
변경할 때마다 이 세트를 재실행합니다. 이는 추측을 제거하고 튜닝(tuning)을 가능하게 합니다.
5. '모르겠다'고 말할 방법이 없음
언어 모델은 도움이 되려고 노력합니다. 만약 검색된 컨텍스트에 답이 없다면, 많은 모델들이 그 빈틈을 그럴듯한 무언가로 채웁니다. 이것이 사용자들이 인지하는 환각(hallucination)입니다.
해결 방법:
- 제공된 컨텍스트만을 사용하여 답변하도록 지시합니다.
- 답변이 없을 때 명확하게 거절할 수 있는 방법을 제시합니다.
- 모든 주장에는 출처를 요구합니다.
- 검색 점수 임계값(retrieval-score threshold)을 설정하고, 그 이하일 경우 거부하거나 질문을 구체화하도록 요청합니다.
- 거부된 질문들을 기록하세요. 왜냐하면 그것들이 문서의 공백이 있는 곳을 보여주기 때문입니다.
시작 프롬프트:
아래 컨텍스트만을 사용하여 질문에 답변하세요.
만약 컨텍스트에 답이 없다면, 다음 문구로 회신하세요: "문서에서 해당 내용을 찾을 수 없습니다."
모든 주장에 대해 출처 제목을 인용하세요.
컨텍스트:
{retrieved_chunks}
질문: {question}
시간을 절약하는 디버깅 순서
잘못된 답변이 보일 때, 다음 순서대로 질문해 보세요:
- 올바른 정보가 인덱스에 아예 있었나요?
- 검색되었나요?
- 프롬프트에 포함될 만큼 충분히 높은 순위(ranked high enough)였나요?
- 모델이 실제로 그것을 사용했나요? 대부분의 버그는 모델을 탓하기 훨씬 전에 앞의 세 단계에서 나타납니다. 전체 아키텍처(데이터 수집(ingestion), 임베딩, 벡터 데이터베이스 및 검색)에 대한 더 깊은 내용을 보려면, ScaleDojo의 RAG 및 벡터 데이터베이스 가이드가 각 구성 요소를 안내합니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기