RAG 전에 질문을 재작성하고 의도를 분류해야 하는 이유

대화형 질문은 검색 query로 쓰기에 지나치게 짧거나 앞선 문맥에 의존할 때가 많습니다. 운영용 AI 챗봇에서도 처음에는 사용자 원문을 그대로 embedding하면 대화 맥락이 자연스럽게 반영될 것으로 기대했습니다. 그러나 RAG 검색 전에 독립된 질문으로 재작성하고 intent를 분류해야 검색 품질을 높이고 불필요한 비용을 줄일 수 있었습니다.

대명사와 생략이 포함된 후속 질문은 검색어만으로는 의미가 불분명했고, 정보 질문과 실행 요청도 같은 흐름으로 들어갔습니다.

후속 질문은 그대로 검색할 수 없었다

사용자는 ‘그건 왜 실패했어?’처럼 이전 대상을 생략해 질문합니다. 이 문장을 그대로 embedding하면 핵심 식별자와 도메인 용어가 없어 관련 없는 문서가 상위에 나왔습니다. 모든 질문에 RAG를 실행하면 인사, 간단한 계산, 실제 시스템 조회가 필요한 요청에도 문서 검색 비용이 발생하고 잘못된 근거가 붙었습니다.

검색 전에 필요한 세 가지 판단

재작성 결과 하나만 다음 단계로 넘기지 않았습니다. 원문, 대화 문맥을 반영한 독립 질문, 정보 조회인지 실행인지 나타내는 intent를 함께 보존했습니다. confidence가 낮으면 재작성문으로 밀어붙이지 않고 원문 검색이나 사용자 확인으로 되돌아갈 수 있게 했습니다.

  • 재작성 결과는 원래 의도를 보존한 독립 문장이어야 합니다.
  • 의도 분류는 답을 생성하지 않고 다음 처리 경로만 선택합니다.
  • 확신이 낮을 때는 위험한 실행보다 사용자 확인 또는 검색 경로를 선택합니다.

원문·재작성문·Intent의 동시 보존

최근 대화의 제한된 구간과 현재 질문을 작은 모델에 보내 검색 가능한 독립 질문을 만듭니다. 프로젝트명, 오류 코드, 기간처럼 앞 문맥의 핵심 정보만 복원합니다.

분류기는 일반 대화, 지식 검색, 실시간 조회, 변경 실행 같은 소수의 의도로 나눕니다. 변경 실행은 별도의 확인과 권한 검증 경로로 이동합니다. 재작성된 질문으로 vector와 keyword 검색을 결합하고 원문 질문은 최종 답변 생성에 함께 제공해 표현 의도가 사라지지 않게 합니다.

{"standaloneQuery":"프로젝트 삭제 후 복구 가능 기간은 며칠인가?","intent":"KNOWLEDGE_SEARCH","confidence":0.94,"entities":{"resource":"project"}}
const route = result.confidence < 0.65
  ? 'AMBIGUOUS'
  : result.intent;
const query = normalize(result.standaloneQuery || originalQuestion);
대화: "그 프로젝트는 삭제했어"
질문: "언제까지 살릴 수 있어?"
재작성: "삭제한 프로젝트를 복구할 수 있는 보존 기간은 얼마인가?"

틀린 재작성과 낮은 Confidence 테스트

평가 세트에는 대명사가 많은 후속 질문, 주제가 바뀐 질문, 검색이 필요 없는 인사와 실행 요청을 섞었습니다. 재작성 문장이 자연스러운지만 보는 대신 올바른 문서를 찾았는지와 불필요한 도구 호출을 만들지 않았는지를 측정했습니다. 이 과정에서 “잘 쓴 문장”과 “검색에 유용한 문장”이 다를 수 있음을 확인했습니다.

  • 재작성 모델이 대화에 없는 프로젝트명이나 날짜를 만들어 검색을 오염하는 문제.
  • 모든 질문을 지식 검색으로 보내 인사·작업 명령까지 vector DB를 조회하는 문제.
  • 한국어 조사와 제품 고유명사 정규화 과정에서 중요한 token이 사라지는 문제.

검색하지 않아야 할 요청도 측정하기

  • 원문·재작성문·선택 문서를 함께 기록하되 민감 정보는 마스킹합니다.
  • 대명사와 생략이 많은 실제 대화 세트로 검색 recall을 비교합니다.
  • 분류 실패가 도구 실행으로 이어지지 않도록 보수적 fallback을 둡니다.
  • 원문·재작성·기대 문서 relevance를 한 묶음으로 평가합니다.
  • 의도별 confusion matrix와 low-confidence 비율을 봅니다.
  • 재작성 실패 시 원문 검색으로 되돌아가는 안전한 fallback을 둡니다.

검색 품질과 비용에서 확인한 변화

후속 질문에서도 검색 쿼리에 핵심 대상이 포함되어 관련 문서가 안정적으로 상위에 나타났습니다. RAG가 필요 없는 요청을 일찍 분리해 응답 시간과 토큰 비용을 줄이고 실행 요청의 안전 경계도 강화했습니다.

재작성 모델이 원문의 의미를 바꿀 수 있으므로 원문을 버리지는 않았습니다. confidence가 낮거나 원문과 대상이 크게 달라진 경우 검색을 강행하지 않고 추가 질문으로 돌렸습니다.

Embedding을 바꾸기 전에 볼 것

후속 질문의 검색 품질이 낮을 때 embedding 모델부터 교체하면 입력 문제를 그대로 둔 채 비용만 늘 수 있습니다. 실제로 필요했던 것은 “그거”, “아까 오류” 같은 표현을 검색 가능한 독립 질문으로 바꾸는 단계였습니다.

재작성문과 intent, confidence를 함께 기록하면 잘못된 검색이 어느 판단에서 시작됐는지 추적할 수 있습니다. 검색하지 않아야 할 요청을 일찍 분리하는 것 역시 검색 정확도를 높이는 일만큼 중요한 개선이었습니다.

댓글

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다