내 RAG 앱이 환각 현상을 일으킨 이유와 해결 방법
한번은 동료에게 제가 만든 RAG 지원 봇을 시연한 적이 있습니다.
봇은 환불 정책이 30일이라고 말했습니다.
실제 정책은 14일입니다.
봇은 확실하지 않다고 말하지 않았습니다. 아주 자신만만하게 답변을 지어냈습니다.
RAG는 환각(hallucination)을 방지해야 합니다. 제 설정은 환각을 방지한 게 아니라 위치만 옮겼을 뿐이었습니다.
저는 다음 다섯 단계를 통해 이 문제를 해결했습니다.
- 청킹(chunking) 전략 수정하기
예전에는 글자 수 기준으로 문서를 나누었습니다. 이것은 실수였습니다.
하나의 청크에 배송과 반품 같은 서로 다른 주제가 섞이는 경우가 많았습니다. 모델은 이를 혼합하여 잘못된 답변을 내놓았습니다.
해결책: 시맨틱 청킹(semantic chunking)으로 전환했습니다. 이제 제목과 단락을 기준으로 텍스트를 나눕니다.
- 유사도 점수만 믿지 말 것
제 리트리버(retriever)는 코사인 유사도(cosine similarity)를 기반으로 상위 3개의 청크를 가져왔습니다.
유사한 것과 관련 있는 것은 다릅니다. 청크가 질문과 유사해 보일 수는 있지만, 정작 답변은 포함하지 않을 수 있습니다.
해결책: 크로스 인코더(cross-encoder)를 사용한 리랭킹(reranking) 단계를 추가했습니다. 이를 통해 시스템에 실제 데이터가 없는 경우를 파악할 수 있었습니다.
- 모델에게 실패할 권한을 줄 것
이전 프롬프트는 단순히 "컨텍스트를 사용하여 질문에 답하세요"라고만 되어 있었습니다.
컨텍스트에 답변이 없으면, 모델은 추측으로 그 빈틈을 채웠습니다.
해결책: 직접적인 지침을 추가했습니다. "만약 컨텍스트에 답변이 없다면, 모른다고 답하세요." 이 지침 하나만으로도 대부분의 환각 현상이 멈췄습니다.
- 검색 임계값(threshold) 설정하기
검색이 실패했을 때 모델이 일반적인 지식을 사용하는 경우가 있었습니다. 프롬프트가 작동하기를 바랐지만, 희망은 전략이 될 수 없습니다.
해결책: 점수 컷오프(cutoff)를 추가했습니다. 검색 점수가 너무 낮으면 시스템은 폴백(fallback) 응답을 반환합니다. 컨텍스트가 없으면 답변도 없습니다.
- 성공이 아닌 실패를 테스트할 것
예전에는 쉬운 질문들만 테스트했습니다. 모호한 질문이나 정보가 누락된 경우는 무시했습니다.
해결책: 함정 질문(trap questions)으로 구성된 평가 세트를 구축했습니다. 이는 답변이 누락된 경우들을 포함합니다. 이러한 테스트를 정기적으로 수행하면 시스템이 정확히 어느 부분에서 무너지는지 알 수 있습니다.
RAG가 환각을 완전히 없애주는 것은 아닙니다. 다만 환각을 제어 가능하게 만들어 줄 뿐입니다.
제 봇이 여전히 모든 세부 사항을 아는 것은 아닙니다. 하지만 이제는 확실하지 않을 때 모른다고 인정합니다. 그 덕분에 실제로 사용할 수 있게 되었습니다.
Source: https://dev.to/pallavi_sharma_10c1a6f1da/why-my-rag-app-kept-hallucinating-and-how-i-fixed-it-3i10
Optional learning community: https://t.me/GyaanSetuAi