후속 질문이 RAG 검색 성능을 망치고 있는데, 어느 계층을 수정해야 할지 모르겠네요
Follow-up questions are wrecking my RAG retrieval and I'm not sure which layer to fix
핵심 요약
LangGraph 기반 RAG 시스템에서 후속 질문 처리 시 검색 품질이 급격히 떨어지는 문제를 해결하기 위한 최적의 아키텍처를 고민 중입니다.
- RAG 검색 성능 — 후속 질문 시 문맥 파악 실패로 검색 품질이 급격히 저하됨
- 쿼리 재작성 한계 — LLM을 통한 쿼리 압축 시 핵심 키워드가 누락되어 리콜이 감소함
- 히스토리 관리 — 대화 이력을 단순히 연결하면 임베딩이 희석되어 관련 없는 정보가 검색됨
- 프로덕션 패턴 — 대규모 환경에서 대화형 RAG의 검색과 문맥 처리를 분리하는 표준적인 방법 탐색
LangGraph 기반의 고객 지원 봇을 구축 중입니다. 검색 엔진은 Denser Retriever를 사용하는데, 몇 달 전 BM25, 벡터, 리랭크 스택을 직접 관리하기 싫어서 선택했습니다. 단일 턴 질문은 리콜과 지연 시간 모두 만족스럽게 잘 작동합니다. 대용량 문서 업로드 시 재인덱싱은 시간이 좀 걸리지만, 실시간 쿼리 경로는 탄탄합니다.
문제는 멀티 턴입니다. 누군가 후속 질문을 하는 순간 검색 품질이 바닥으로 떨어지는데, 이 문제를 검색 호출 단계에서 고쳐야 할지, 아니면 그 앞단에서 고쳐야 할지 모르겠습니다.
구체적인 예시를 들자면, 사용자가 "what's your billing cycle for the Pro plan."이라고 물으면 검색은 정확한 가격 문서를 가져옵니다. 사용자가 이어서 "and is it different in Europe."이라고 물으면, 검색기에 새로운 질문만 보낼 경우 "it"이 무엇을 의미하는지 전혀 알지 못합니다. 최근 몇 번의 대화를 연결해서 전체를 임베딩하면, "Europe"이나 "different" 같은 토큰이 임베딩을 지배해서 일반적인 EU 규정 콘텐츠를 가져오게 됩니다. 결제 주기라는 주제는 희석되어 버리죠.
몇 가지 시도해 봤지만 깔끔한 해결책은 없었습니다.
명시적인 쿼리 재작성 단계를 도입했습니다. 검색 호출 전에 작은 모델이 대화 내용과 후속 질문을 독립적인 쿼리로 압축하게 했습니다. 턴당 LLM 호출이 한 번씩 늘어나 지연 시간이 증가했습니다. 더 큰 문제는 재작성기가 가끔 중요한 특정 용어를 삭제한다는 점입니다. "Is it different in Europe"이 "regional pricing variations for Europe"으로 재작성되면서, 정작 필요한 문서에 있던 "billing cycle, EU"라는 문구가 사라져 리콜이 떨어졌습니다.
최근 사용자 질문과 현재 질문만 연결하고 이전 기록은 제외하는 좁은 범위의 연결 방식은 어떤 턴에서는 도움이 되었지만, 다른 턴에서는 오히려 방해가 되었습니다. 두 턴 정도 연결하는 건 괜찮지만, 세 턴이 넘어가면 임베딩이 엉망이 됩니다.
LangChain의 create_history_aware_retriever가 당연히 다음 시도 대상이었습니다. 그런데 이것도 내부적으로는 재작성 방식을 쓰고 있어서, 똑같이 재작성기가 키워드를 놓치는 문제가 발생했습니다. 단지 저에게 추상화되어 있을 뿐이었죠.
계속 고민되는 점은 이게 정말 내 체인 안에서 해결해야 할 전처리 문제인지, 아니면 프로덕션 환경에서 사람들이 사용하는 더 깔끔한 패턴이 따로 있는지입니다. 대화형 문맥 처리와 실제 검색 호출이 같은 단계여야 할 것 같지는 않은데, 대규모 환경에서 이 분리가 실제로 어떻게 이루어지는지 공개된 사례를 보지 못했습니다.
LangChain이나 LangGraph로 대규모 멀티 턴 RAG를 운영하는 팀들이 이 문제를 어떻게 해결하고 있는지 궁금합니다. 검색 앞단의 재작성기에서 해결해야 할 문제인지, 아니면 제가 생각하지 못한 다른 곳에 해결책이 있는지 파악하려고 합니다.


