단일 라운드 RAG는 완벽한데 다중턴만 가면 무너진다 — 문제는 생성이 아니라 검색에 있다

← 전체 목차 · 이전: Rerank 모델은 언제 반드시 필요한가 · 다음: RAG 캐시, 그냥 질문을 키로 쓰면 되는 거 아닌가

"컨텍스트 윈도우를 늘린다 / 이력 대화를 더 많이 넘긴다 / Prompt 화술을 다듬는다"로 답하면 전부 헛다리다. 셋 다 생성 측을 건드리는 동작인데, 다중턴 RAG가 무너지는 지점은 검색 측이다. 단일 라운드에서 지식베이스에 정확히 들어맞던 시스템이, 대화가 이어지자마자 답이 어긋나고 앞 맥락을 잊고 흐름이 끊기는 것은 우연이 아니라 네 가지 검색단 병목이 겹친 결과다.

Demo와 실제 다중턴의 낙차

로컬 Demo(자체 테스트)실제 사용자
질문 형태독립적, 키워드 명확연속 대화, 즉흥 추가 질문, 전방 지시, 축약 질문
의미 품질명확·완결모호함 다수, 중복 컨텍스트
결과검색 정확, 답변 안정여러 턴 지나면 무너짐

단일 라운드 평가셋만 돌리는 팀은 다중턴 실패를 구조적으로 볼 수 없다 — 시스템은 테스트해 본 분포에서만 잘 작동한다.

네 가지 검색단 병목

병근 1: 원 질문의 의미 모호, 핵심 정보 결손
   다중턴 추가 질문은 습관적으로 화술을 간소화한다 (예: "그럼 그건요?")
   원문 그대로 검색 → 키워드 결손 → 벡터 매칭이 완전히 빗나감 → 무관 문서 대량 리콜

병근 2: 이력 컨텍스트 중복, 유효 의미가 희석됨
   대화가 길수록 무효 잡담·만료된 질문이 섞인다
   무차별 전량 전달 → 벡터 매칭 교란 → 핵심 질문 가중치 희석 → 검색 정밀도 급락

병근 3: 단일 라운드 고정 검색 로직, 다중턴에 적응 불가
   단일 라운드는 "현재 질문"만 매칭하면 되지만 다중턴은 전역 맥락과 결합해야 한다
   고정된 검색 로직은 이력 핵심 정보를 통합하지 못해 사용자의 진짜 의도를 식별하지 못한다

병근 4: 컨텍스트 윈도우 상한, 초장문 대화가 절단되며 정보 손실
   모델 컨텍스트 길이는 유한 → 강제 절단 → 앞쪽 핵심 대화 정보 유실
   → 앞 맥락 망각, 대화 단절, 논리 혼란

병근 1·3은 검색 전략 자체가 다중턴을 모른다는 것이고, 병근 2·4는 이력을 다루는 방식이 틀렸다는 것이다.

네 가지 방어선

#방어선대응 병근핵심 동작
1다중턴 의도 재구성(Query Rewrite)병근 1이력 맥락 + 현재 추가 질문 → 완결·독립된 표준 질문으로 재작성
2컨텍스트 동적 디노이징병근 2잡담·만료 질문·중복 내용 폐기, 현재 질문과 강관련된 핵심만 보존
3기억 계층 관리병근 4단기 기억(최근 대화) / 장기 기억(핵심 문답 아카이브) / 압축 요약(초장문 자동 요약)
4다중턴 동적 검색병근 3대화 턴수·의미 연관도에 따라 검색 전략을 동적으로 조정, 이력 연관 지식점 우선 매칭
디노이징 필터
  ├─ 무효 잡담     → 폐기
  ├─ 만료된 질문   → 폐기
  ├─ 중복 내용     → 폐기
  └─ 현재 질문과 강관련된 핵심 컨텍스트 → 보존

방어선 1이 가성비가 가장 높다. 검색 직전에 위치해 "키워드 결손"과 "전방 지시"라는 두 실패 유형을 동시에 완화하기 때문이다. 재작성 결과는 검색에만 쓰고 사용자에게 보여주는 원 질문을 대체하지 않는다 — 이렇게 분리해야 Bad Case 귀인이 가능하다.

생산 규범 3원칙

  1. 모든 다중턴 대화는 질문 재구성을 거쳐야 한다 — 원생 모호 문장을 그대로 검색에 넣는 것을 금지.
  2. 이력 대화 캐시를 정기적으로 정리한다 — 컨텍스트 누적은 성능 저하와 정밀도 저하를 동시에 유발한다.
  3. 다중턴 Bad Case를 별도로 모아 이터레이션한다 — 단일 라운드 평가셋에 섞으면 평균에 묻혀 사라진다.

핵심 통찰

  1. 다중턴 RAG 붕괴의 근인은 생성단이 아니라 검색단이다 — 대부분 반사적으로 Prompt를 고치거나 모델을 바꾸거나 윈도우를 늘리지만, 둘째 라운드부터 답이 어긋나기 시작하면 먼저 봐야 할 것은 "이번 라운드에 무엇이 리콜됐는가"이지 시스템 프롬프트가 아니다.
  2. 다중턴에서 사용자가 표현을 퇴화시키는 것은 이상 입력이 아니라 제품의 상수다 — "대명사·짧은 문장으로 습관적으로 간소화하고 완결 질문을 반복하지 않는" 것은 인간 대화의 기본 동작이다. 이것을 방어해야 할 입력 분포로 받아들이는 것이 생산적 사고의 출발점이다.
  3. "이력을 실었다"와 "이력을 제대로 실었다"는 별개다 — 이력을 무차별로 전량 전달하면 핵심 질문의 가중치를 희석해 검색 정밀도를 급락시키고, 디노이징을 거쳐 강관련 부분만 남겨야 이력이 비로소 증익이 된다. 정보량이 정보 가치와 같지 않다.
  4. 고정된 검색 전략은 변화하는 대화 상태에 태생적으로 맞지 않는다 — 단일 라운드 RAG의 암묵적 가정은 "질문이 자기완결적"이라는 것인데, 다중턴이 이 가정을 깨자마자 고정 로직은 실효한다. 검색 전략은 상수가 아니라 대화 턴수와 의미 연관도의 함수여야 한다.
  5. 컨텍스트 윈도우는 경성 제약이므로 계층화·압축으로 우회해야지 늘려서 버텨서는 안 된다 — 단기 기억이 연속성을, 장기 기억이 핵심을, 압축 요약이 정보 밀도를 지킨다. 셋의 조합만이 상한이 있는 시스템에서 지속 가능한 해법이고, 윈도우가 더 큰 모델로 바꾸는 것은 붕괴 지점을 뒤로 미루는 것에 불과하다.
  6. 질문 재구성은 다중턴 RAG에서 가성비가 가장 높은 단일 개조다 — 검색 이전에 위치해 한 번의 재구성으로 "키워드 결손"과 "전방 지시" 두 실패 유형을 동시에 완화한다.
  7. Demo와 프로덕션의 격차는 본질적으로 평가셋의 격차다 — "평소 단일 라운드 문답만 테스트하고 다중턴의 온라인 숨은 함정을 밟아 본 적이 없다"는 것은, 시스템이 테스트해 본 분포에서만 잘 작동한다는 뜻이다. 다중턴 평가셋을 만들지 않으면 다중턴 문제는 영원히 잠복한다.
  8. 면접에서 "완전하게 답하는" 구조와 온라인에서 "제대로 고치는" 구조는 같다 — 4대 병근 → 4개 방어선 → 3원칙이라는 골격 자체가 답변 템플릿이자 실제 치리 로드맵이다.

엔지니어링 실전 Tips

  • 먼저 리콜을 보고 그다음 답을 볼 것: 다중턴 붕괴의 원인 규명 입구는 매 라운드의 검색 결과 로그다. 답은 틀렸는데 문서가 맞은 것과 문서 자체가 틀린 것은 완전히 다른 수리 경로다.
  • 재작성된 query와 원 query를 분리 저장할 것: 재작성 산출물은 검색에만 쓰고, 사용자에게 보이는 것은 여전히 본인의 원문이어야 한다. 섞어 쓰면 Bad Case 귀인이 불가능해진다.
  • "정기적으로 캐시 정리"는 두 가지를 동시에 막는다: 컨텍스트 누적 과다는 성능 지연과 정밀도 저하를 동시에 유발하므로, 캐시 전략을 짤 때 지연 지표만 보지 말고 정밀도도 함께 모니터링할 것.
  • 다중턴 Bad Case는 별도 집합으로 모을 것: 단일 라운드 평가에 섞이면 평균에 묻힌다 — 단일 라운드 지표가 깨끗한 것 자체가 다중턴 문제가 가려진 전형적 징후다.
  • 디노이징은 설명 가능해야 한다: 걸러낸 이력 조각에 사유(잡담/만료/중복)를 남겨 두지 않으면, "실려야 할 것이 안 실렸다"는 문제가 발생했을 때 위치를 특정할 수 없다.
  • 장기 기억 아카이브 판정은 보수적으로: 무엇을 "핵심 문답"으로 볼지 명확한 규칙이 필요하다. 아카이브를 누락하는 것이 잡담을 장기 기억으로 승격시키는 것보다 낫다 — 후자는 중복을 더 지속적인 형태로 되돌려 놓는다.
  • 압축은 손실이 있으므로 경계를 정할 것: 초장문 대화 요약이 핵심 정보를 남기려면 먼저 "핵심"을 정의해야 하고, 이는 장기 기억의 아카이브 규칙과 같은 판정 기준을 공유하는 것이 좋다.