RAG Lab

왜 RAG에는 decision layer가 필요할까?

검색은 됐는데 답은 흔들리는 순간이 있습니다. 최근 retrieval 뒤에 rerank와 corrective retrieval을 붙이는 방향을 검토하면서, 결국 필요한 것은 더 큰 모델보다 decision layer라는 쪽으로 생각이 정리됐습니다.

왜 RAG는 문서를 찾고도 답이 흔들릴까?

최근에 손보려 했던 것도 그 지점이었습니다. 검색은 되는데, 애매한 문서가 앞에 오고, 지금 가진 문맥만으로는 답이 부족한데도 모델은 계속 뭔가 말하려고 하더라고요.

문제는 generation보다 retrieval 쪽에 더 가까웠습니다

기존 흐름은 단순했습니다.

  • 문서를 찾고
  • context를 만들고
  • 답을 생성하는 구조였죠

이 구조는 빠르고 이해하기 쉽습니다. 그런데 질문이 조금만 복잡해지면 약점도 분명했습니다.

예를 들면 이런 상황입니다.

  • 관련은 있지만 직접 답은 아닌 문서가 위로 올라오는 경우
  • 하나의 문서 집합만으로는 정보가 부족한 경우
  • 근거가 약한데도 답변은 계속 생성되는 경우

결국 핵심은 이거였습니다.

찾았다는 것과, 답할 만큼 충분하다는 것은 다르다.

그래서 retrieval 뒤에 판단 단계를 넣으려 했습니다

검토한 방향은 단순한 rerank 추가가 아니었습니다. 검색 뒤에 “이 결과가 정말 쓸 만한가?”를 판단하는 단계를 넣는 쪽이었습니다.

큰 흐름은 이렇습니다.

단계역할
1초기 검색으로 후보를 넓게 가져오기
2후보를 다시 정렬하기
3결과가 충분한지 판정하기
4부족하면 다른 문맥까지 확장해서 다시 찾기
5그래도 부족하면 모른다고 말하기

여기서 중요한 건 rerank 자체보다, rerank 결과를 다음 액션으로 연결하는 구조였습니다.

왜 overfetch가 필요했냐면요

검색 결과를 바로 top-k로 잘라서 넘기면, rerank가 실제로 할 수 있는 일이 생각보다 줄어듭니다. 그래서 먼저 조금 넓게 가져오고, 그 안에서 다시 순서를 잡는 쪽이 더 안정적이었습니다.

이 방식의 장점은 분명합니다.

  • 초기 retrieval이 놓친 문서가 최종 후보에 남을 가능성이 커집니다.
  • 최종 top-k를 더 의미 있게 정리할 수 있습니다.
  • retrieval score와 semantic relevance를 분리해서 볼 수 있습니다.

즉, 검색 결과를 바로 믿는 대신 한 번 더 의심하는 단계가 생기는 셈입니다.

“애매함”을 시스템이 이해해야 했습니다

RAG 운영에서 자주 부딪히는 문제는 이거였습니다. 검색 결과가 완전히 틀린 것도 아니고, 그렇다고 충분히 맞는 것도 아닌 경우요.

이 중간 상태를 그냥 점수로만 두면 운영하기가 어렵습니다. 그래서 결과를 몇 가지 상태로 나눠서 해석하는 접근이 필요했습니다.

예를 들면 이런 식입니다.

  • 충분히 관련 있음
  • 애매함
  • 지금 문맥으로는 부족함

이렇게 나누면 retrieval이 단순 검색기가 아니라 다음 행동을 결정하는 컨트롤 포인트가 됩니다.

부족하면 더 찾고, 그래도 부족하면 멈추는 쪽이 맞았습니다

질문에 대해 지금 문맥만으로 확신이 안 서면, 바로 답을 꾸미기보다 다른 관련 문맥을 더 찾아보는 것이 먼저여야 했습니다. 그래도 충분한 근거가 안 나오면, 그때는 솔직하게 부족하다고 말하는 쪽이 낫습니다.

이건 모델 품질보다 더 근본적인 운영 원칙에 가깝습니다.

모를 때 멈출 수 있어야, 아는 척하는 시스템이 되지 않습니다.

provenance도 같이 중요해졌습니다

문맥을 더 넓게 보기 시작하면 바로 생기는 질문이 있습니다.

“이 답은 어디에서 왔지?”

초기 RAG에서는 source가 몇 개 붙는 정도로 충분할 수 있습니다. 그런데 retrieval이 여러 경로를 거치기 시작하면 그걸로는 부족합니다.

그래서 결과를 보여줄 때도 단순 텍스트 미리보기만이 아니라,

  • 어떤 근거를 썼는지
  • 어느 문맥에서 왔는지
  • 왜 이 답이 선택됐는지

를 같이 볼 수 있어야 했습니다.

정확도만 높아서는 부족합니다. 운영에서는 설명 가능성이 같이 따라와야 합니다.

붙이면서 바로 보인 것도 있었습니다

이런 종류의 개선은 “붙였다”로 끝나지 않더라고요. 넣는 순간부터 새로운 질문이 생깁니다.

질문왜 중요했나
실패했을 때 얼마나 보수적으로 동작할 것인가장애 시 오답을 줄이기 위해
어떤 검색 경로에는 이 단계를 생략할 것인가retrieval path마다 특성이 달라서
문맥 확장은 어디까지 허용할 것인가recall과 precision의 균형 때문에
사용자와 운영자가 내부 상태를 얼마나 볼 수 있어야 하는가디버깅과 신뢰를 위해

즉, retrieval을 똑똑하게 만드는 일은 단순히 ranking 모델 하나 더 넣는 문제가 아니었습니다.

판단, 확장, 중단, 설명을 같이 설계해야 하는 문제였습니다.

이번에 얻은 결론은 분명했습니다

RAG는 “찾고 말하는 시스템”으로 두면 금방 흔들립니다.

대신 더 안정적인 방향은 이쪽이었습니다.

  • 먼저 넓게 찾고
  • 다시 정렬하고
  • 충분한지 판단하고
  • 부족하면 더 찾고
  • 그래도 부족하면 멈추는 것

이 흐름이 들어가야 retrieval이 단순한 검색을 넘어서 답할 수 있는 상태인지 판단하는 계층이 됩니다.

최근에 도입하려 한 것도 결국 그 방향이었습니다.

모델을 더 크게 바꾸는 것보다 먼저, retrieval이 언제 답해야 하고 언제 멈춰야 하는지를 더 잘 알게 만드는 일요.

다음은 벤치입니다

여기까지는 설계와 구현 방향에 대한 이야기였습니다. 이 방향이 실제로 맞는지는 결국 retrieval benchmark로 확인해야 합니다.

특히 다음 질문에는 숫자로 답해야 합니다.

  • rerank가 실제로 top-k 품질을 얼마나 올리는가
  • corrective retrieval이 recall을 얼마나 올리는가
  • precision 손실은 어느 정도인가
  • latency overhead는 운영 가능한 수준인가

다음 글은 이 decision layer를 실제 benchmark로 검증한 기록이 될 가능성이 큽니다.