[태그:] RAG

  • RAG에서 검색 문서를 많이 넣는다고 답변이 항상 좋아지지는 않았던 이유

    RAG를 처음 구성할 때 검색 결과를 몇 개까지 LLM에 넘겨야 하는지 고민하게 된다.

    내가 처음 이 문제를 생각했을 때는 답이 비교적 단순해 보였다.

    관련 문서가 부족해서 LLM이 제대로 답하지 못하는 것이 문제라면 검색 결과를 조금 더 많이 넘기면 되는 것 아닐까.

    예를 들어 검색 결과를 한 개만 전달하는 것보다 세 개를 전달하는 것이 낫고, 세 개보다 다섯 개가 더 안전하며, 아예 열 개 정도를 넘겨주면 필요한 정보가 빠질 가능성도 줄어들 것처럼 느껴졌다.

    생각 자체는 자연스럽다.

    RAG에서는 먼저 Elasticsearch에서 관련 문서를 검색하고, 그 결과를 LLM이 답변을 생성할 때 사용할 Context로 전달한다. Elastic도 RAG를 Elasticsearch에서 관련 Context를 가져와 언어 모델에 전달하는 구조로 설명하고 있다.

    그렇다면 검색 단계에서 후보를 많이 확보할수록 LLM에게 더 많은 정보를 줄 수 있고, 정보가 많으면 더 좋은 답변을 만들 가능성도 높아질 것처럼 보였다.

    나도 처음에는 Top K를 거의 이런 의미로 생각했다.

    Top K가 작다
    → 정보가 부족할 수 있다
    
    Top K를 늘린다
    → 더 많은 관련 문서를 얻는다
    
    → LLM이 참고할 정보가 많아진다
    
    → 답변이 좋아진다
    

    그런데 RAG 구조를 조금 더 길게 따라가다 보니 이 생각에는 빠진 부분이 있었다.

    검색 결과를 더 많이 가져온다는 것은 관련 정보만 더 많이 가져온다는 뜻이 아니었다.

    관련성이 높은 문서뿐 아니라 애매하게 관련된 문서, 비슷한 내용을 반복하는 문서, 사용자의 질문과는 조금 다른 방향의 문서까지 Context 안으로 같이 들어올 가능성이 생긴다.

    그때부터 Top K를 단순히 “몇 개를 검색할까”라는 숫자로만 보기 어렵게 됐다.


    처음에는 좋은 문서를 놓치는 것이 가장 무서웠다

    예를 들어 사용자가 다음처럼 질문한다고 생각해보자.

    파이썬을 처음 공부하는 사람이 어렵지 않게 읽을 책을 추천해줘.

    내 검색 시스템에는 이 질문과 잘 맞는 책 A, B, C가 있다고 하자.

    그런데 KNN 검색에서 Top 1만 가져왔다.

    검색 결과
    
    1. A
    

    A가 정말 좋은 책이라면 별 문제가 없어 보인다.

    하지만 검색 결과의 1위가 항상 완벽하다는 보장은 없다.

    벡터 검색 자체가 approximate search를 사용할 수도 있고, 문서 embedding 구성이나 검색 문장 표현에 따라 상위 결과의 순위가 조금씩 달라질 수도 있다.

    앞에서 knum_candidates를 보면서도 같은 문제를 생각했다.

    검색 단계에서 좋은 후보가 빠지면 이후 단계에서 그 책을 정상적으로 활용하기 어렵다.

    그래서 Top 1은 조금 불안하게 느껴졌다.

    한 문서의 검색 순위가 조금만 빗나가도 LLM에게 제공되는 정보 전체가 달라지기 때문이다.

    그러면 자연스럽게 Top 3을 생각하게 된다.

    검색 결과
    
    1. A
    2. B
    3. C
    

    이제 하나의 결과가 조금 빗나가더라도 다른 후보가 존재한다.

    이때까지만 보면 Top K를 늘리는 논리가 상당히 설득력 있다.

    좋은 문서를 놓칠 가능성을 줄이기 위해 Retrieval 단계에서 어느 정도 후보를 넉넉하게 가져오는 것은 분명 필요한 접근이 될 수 있다.

    Elasticsearch의 현재 검색 기능에서도 첫 단계 Retrieval에서 후보를 만들고, 필요하면 그 후보를 별도의 semantic reranker 등으로 다시 정렬하는 파이프라인을 구성할 수 있다. 즉 검색 단계에서 후보 집합을 확보하고 이후 더 비싼 방식으로 순서를 개선하는 구조 자체가 지원된다.

    그런데 문제는 여기서 멈추지 않고 Top 5, Top 10, Top 20으로 계속 늘릴 때부터 생긴다.


    다섯 개가 좋다면 열 개는 더 좋지 않을까

    이 질문이 나에게는 꽤 중요했다.

    다섯 개의 문서를 넣었더니 좋은 후보를 놓칠 가능성이 줄었다.

    그렇다면 열 개를 넣으면 더 안전할 것 같다.

    스무 개면 더 안전할 수도 있다.

    그런데 이 논리를 끝까지 밀어붙이면 결국 이런 결론이 나온다.

    가능하면 검색된 문서를 전부 넣는 것이 가장 좋은가?

    여기에서 뭔가 이상하다는 생각이 들었다.

    만약 정보가 많을수록 무조건 좋다면 RAG에서 검색 순위를 만들 필요도 별로 없다.

    관련 가능성이 조금이라도 있는 문서를 전부 Context에 넣으면 되기 때문이다.

    하지만 실제로는 검색 시스템이 관련성이 높은 문서를 위로 올리고, 그중 일부를 선택하기 위해 존재한다.

    Elasticsearch도 검색 결과를 ranking하고, 여러 retrieval 결과를 RRF로 합치거나 상위 후보를 semantic reranker에 보내 더 정교하게 재정렬할 수 있는 기능을 제공한다.

    그렇다면 Top K를 크게 만드는 것만으로 검색 품질 문제를 해결하려는 접근은 RAG 앞단의 ranking을 제대로 활용하지 않고 LLM 쪽으로 문제를 떠넘기는 방식이 될 수도 있다는 생각이 들었다.


    검색 결과가 많아질수록 “관련 문서 수”와 “전체 문서 수”가 같은 비율로 늘어나지는 않는다

    예를 들어 실제로 매우 관련 있는 문서가 세 개 있다고 생각해보자.

    검색 결과가 다음과 같을 수 있다.

    1. 매우 관련 있음
    2. 매우 관련 있음
    3. 관련 있음
    4. 어느 정도 관련 있음
    5. 어느 정도 관련 있음
    6. 조금 관련 있음
    7. 다른 주제도 많이 포함
    8. 키워드 일부만 비슷함
    9. 거의 관계 없음
    10. 거의 관계 없음
    

    Top 3을 사용할 때는 Context 대부분이 사용자 질문과 강하게 연결되어 있다.

    그런데 Top 10으로 늘리면 정보량은 세 배 이상 증가했지만 강하게 관련된 정보의 양이 세 배로 늘어난 것은 아니다.

    오히려 Context 안에서 관련 정보의 비율이 낮아질 수 있다.

    내가 이 문제를 생각하면서 중요하게 느낀 것이 정보의 양과 정보의 밀도는 다른 문제라는 점이었다.

    LLM에 긴 Context를 준다는 것은 단순히 모델에게 많은 지식을 선물하는 것이 아니다.

    그 안에서 어떤 부분을 실제 답변 근거로 사용해야 할지 판단해야 할 정보도 같이 늘어난다.

    Elastic에서도 RAG Playground에서 모델의 답변에 추가되는 Context가 Elasticsearch에서 가져온 정보로 구성된다는 점을 설명하고 있다. 결국 검색 결과로 선택한 정보가 LLM이 실제로 보게 되는 재료가 된다.

    이 관점으로 보면 좋은 RAG Context는 단순히 많은 Context가 아니라 질문과 관련 있는 정보의 밀도가 높은 Context에 더 가깝다는 생각이 들었다.


    같은 내용을 반복하는 문서도 문제가 될 수 있었다

    도서 검색에서는 같은 책이 여러 도서관에 존재할 수도 있고, 비슷한 설명이나 키워드를 가진 도서들이 상위 결과에 여러 개 들어올 수도 있다.

    일반 문서 검색에서도 비슷하다.

    어떤 질문에 대한 Top 10을 가져왔는데 실제 내용을 보면 거의 같은 내용을 말하는 문서가 반복되어 있을 수 있다.

    문서 1
    → A라는 설명
    
    문서 2
    → A를 조금 다르게 설명
    
    문서 3
    → 거의 같은 A
    
    문서 4
    → 또 비슷한 A
    

    문서 수만 보면 네 개다.

    하지만 LLM이 얻는 새로운 정보는 거의 하나일 수 있다.

    그런데 입력 Context 크기는 네 문서만큼 사용한다.

    이런 문제 때문에 단순한 relevance만큼 검색 결과의 다양성도 생각할 필요가 있다고 느꼈다.

    흥미롭게도 현재 Elasticsearch에는 검색 결과의 다양성을 높이는 diversify retriever도 존재하며, 공식 문서에서는 RAG workflow에서 LLM에 더 다양한 Context를 제공하고 prompt의 중복을 줄이는 용도로 사용할 수 있다고 설명한다.

    이 기능 자체를 반드시 사용해야 한다는 뜻은 아니다.

    오히려 내가 중요하게 느낀 것은 Elasticsearch 쪽에서도 상위 문서를 많이 가져오는 것과 유용한 Context를 만드는 것을 같은 문제로 보지 않는다는 점이었다.


    여기에서 Top K와 Context 문서 수를 꼭 같게 만들 필요도 없다는 생각이 들었다

    처음에는 검색에서 k=10이면 LLM에도 10개를 그대로 넣는 것이 자연스럽다고 생각했다.

    KNN Top 10
        ↓
    10개 전부 Context
        ↓
    LLM
    

    하지만 다시 생각해보면 검색 엔진이 후보를 찾기 위해 필요한 문서 수와 LLM이 실제로 읽어야 하는 문서 수는 목적이 다르다.

    검색 단계에서는 좋은 후보를 놓치지 않는 것이 중요하다.

    반면 LLM Context 단계에서는 가장 관련 있는 정보를 밀도 높게 전달하는 것이 중요할 수 있다.

    그렇다면 다음과 같은 구조도 가능하다.

    1차 검색
    Top 20 후보 확보
    
         ↓
    
    ranking / reranking
    
         ↓
    
    가장 관련 있는 5개 선택
    
         ↓
    
    LLM Context
    

    Elasticsearch의 semantic reranking도 이런 생각과 비슷하다. 첫 단계 retrieval에서 후보를 확보한 뒤 보다 계산 비용이 높은 reranker로 후보 순서를 다시 정렬할 수 있다.

    이 구조를 보고 나니 Top K라는 숫자를 하나로만 관리하는 것보다:

    Retrieval Candidate K
    
    와
    
    LLM Context K
    

    를 분리해서 생각하는 것이 더 자연스럽게 느껴졌다.


    RRF를 쓰는 경우에는 이 문제가 더 재미있어졌다

    내 검색에서는 텍스트 검색과 벡터 검색을 함께 보는 구조도 생각했다.

    예를 들어:

    Keyword Search
    +
    KNN Vector Search
    

    를 조합하면 두 방식에서 서로 다른 문서가 상위로 올라올 수 있다.

    Elasticsearch의 RRF retriever는 여러 child retriever에서 나온 결과를 Reciprocal Rank Fusion으로 하나의 ranking으로 결합한다. 각 retrieval 방식이 반환한 상위 결과를 이용해 최종 순위를 만든다.

    여기에서 후보 수를 너무 작게 잡으면 한 retrieval 방식에서만 발견할 수 있었던 좋은 문서를 초반에 놓칠 가능성을 생각할 수 있다.

    반대로 각 retrieval에서 아주 많은 후보를 가져와 전부 LLM에 전달하는 것도 비효율적이다.

    결국 이 경우에도:

    충분한 후보를 확보한다.

    LLM에게 전부 보여준다.

    는 같은 이야기가 아니었다.

    Retrieval 단계와 Context 단계 사이에 선택 과정이 하나 더 필요할 수 있다는 생각으로 이어졌다.


    그리고 결국 비용 문제가 따라왔다

    이전 글에서 LLM API 비용을 생각하면서 RAG Context가 입력 토큰과 직접 연결될 수 있다는 점을 정리했다.

    Top K 문제도 여기와 연결된다.

    예를 들어 책 한 권마다:

    title
    author
    keywords
    description
    

    을 LLM에 전달한다고 생각해보자.

    책 세 권이면 description도 세 개다.

    열 권이면 열 개다.

    검색 결과를 더 많이 가져오는 것 자체는 Elasticsearch의 문제지만, 그 문서 내용을 모두 Prompt에 넣기 시작하는 순간 LLM 입력량의 문제가 된다.

    Top K 증가
        ↓
    Context 문서 증가
        ↓
    Prompt 증가
        ↓
    입력 토큰 증가
    

    따라서 Top K를 늘렸을 때 답변 품질은 아주 조금 좋아지는데 입력량만 크게 증가한다면 운영 측면에서는 좋은 설정이라고 보기 어려울 수 있다.

    이전에는 이걸 단순히 비용 문제라고 생각했다.

    그런데 조금 더 생각해보니 비용뿐 아니라 좋은 검색 결과를 얼마나 효율적으로 전달하는가에 관한 문제였다.


    Context Window가 크다고 해서 그만큼 채우는 것이 목표는 아니었다

    모델이 긴 Context를 받을 수 있다는 사실도 처음에는 헷갈리기 쉬웠다.

    Context Window가 충분히 크다면 검색 문서 열 개나 스무 개를 넣어도 기술적으로 입력할 수 있을 수 있다.

    그러면:

    들어갈 공간이 있는데 왜 줄여야 하지?

    라는 생각이 든다.

    하지만 Context Window는 사용 가능한 최대 공간이지 반드시 채워야 하는 목표량은 아니다.

    예를 들어 방이 넓다고 해서 회의에 필요 없는 자료까지 책상 위에 전부 펼쳐놓는 것이 회의를 더 잘하게 만드는 것은 아니다.

    오히려 중요한 자료를 찾기 어려워질 수 있다.

    나는 RAG Context도 비슷한 관점으로 보는 편이 이해하기 쉬웠다.

    모델이 읽을 수 있다는 것과 모델에게 반드시 읽혀야 한다는 것은 다르다.


    실제로 테스트하려면 “답변이 좋아 보인다”만 봐서는 부족했다

    그렇다면 Top K를 얼마나 사용해야 할까.

    결국 직접 비교해야 한다.

    예전 같으면 검색 결과를 몇 번 눈으로 보고:

    Top 5 정도가 괜찮아 보인다.

    고 끝냈을 수도 있다.

    하지만 이런 판단은 검색어가 바뀌면 쉽게 달라질 수 있다.

    그래서 지금 다시 실험한다면 먼저 실제 질문을 고정할 것 같다.

    예를 들어 도서 추천 질문 30개를 만든다.

    Python 초보자 책
    
    직장 스트레스에 도움이 될 책
    
    투자를 처음 공부하는 책
    
    초등학생이 우주에 관심을 갖게 할 책
    ...
    

    그리고 각 질문에서 관련성이 있다고 판단하는 도서를 미리 정한다.

    그다음 Retrieval 조건은 동일하게 두고 Context 문서 수만 바꾼다.

    조건 A
    Context Top 1
    
    조건 B
    Context Top 3
    
    조건 C
    Context Top 5
    
    조건 D
    Context Top 10
    

    그 상태에서 같은 Prompt와 같은 모델로 답변을 만든다.

    이렇게 해야 최소한 Top K 외의 다른 변수를 줄일 수 있다.


    여기서 내가 보고 싶은 것은 단순 정확도 하나가 아니다

    처음에는 답변 정확도만 비교하면 된다고 생각했다.

    하지만 운영까지 생각하면 보고 싶은 값이 더 많다.

    첫 번째는 필요한 근거가 Context에 들어왔는가다.

    좋은 답을 만들기 위해 필요한 책이 아예 Retrieval에서 빠졌다면 Generation을 평가하기 어렵다.

    두 번째는 답변이 실제 Context에 근거하고 있는가다.

    관련 문서를 많이 넣었더니 오히려 엉뚱한 문서 내용을 답변에 섞기 시작한다면 Context 확대가 도움이 됐다고 말하기 어렵다.

    세 번째는 입력 토큰 증가량이다.

    Top 3에서 Top 10으로 늘렸는데 품질 개선은 거의 없고 입력량만 크게 늘었다면 의미 있는 trade-off인지 생각해야 한다.

    네 번째는 응답시간이다.

    Context 크기를 변경했을 때 실제 서비스의 첫 응답시간과 전체 생성시간이 어떻게 바뀌는지도 함께 측정하고 싶다.

    결국 실험 결과는 이런 형태가 더 도움이 된다.

    Top 1
    - Retrieval 근거
    - 답변 품질
    - Input Token
    - 응답시간
    
    Top 3
    - Retrieval 근거
    - 답변 품질
    - Input Token
    - 응답시간
    
    Top 5
    ...
    
    Top 10
    ...
    

    그렇게 봐야 “몇 개가 최고다”가 아니라 어디부터 추가 문서의 이득이 줄어드는지 볼 수 있다.


    만약 Top 3과 Top 10의 답변이 거의 같다면 무엇을 의미할까

    이 결과가 실제로 나온다면 상당히 흥미롭다.

    Top 3만으로도 답변에 필요한 핵심 근거가 이미 충분했을 가능성이 있다.

    이 경우 Top 4부터 10까지는 새로운 가치보다 중복 정보를 추가하고 있었을 수도 있다.

    그렇다면 Context를 줄이는 방향을 생각할 수 있다.

    반대로 Top 3에서는 중요한 근거가 자주 빠지고 Top 5부터 안정적으로 들어온다면 Top 5가 더 적절할 가능성을 볼 수 있다.

    여기서 중요한 것은:

    Top 5가 정답이다
    

    라는 결론이 아니다.

    내 데이터에서 Top 5부터 필요한 정보가 안정적으로 확보된다는 근거가 생겼다는 것이다.

    이 차이가 중요하다.

    다른 서비스에서는 Top 3일 수도 있고 Top 10일 수도 있다.

    문서 하나의 길이도 다르고, 질문의 복잡성도 다르고, retrieval 품질도 다르기 때문이다.


    Top K가 크다고 답변이 나빠졌다면 검색이 나쁜 것인지 LLM이 나쁜 것인지도 나눠봐야 했다

    예를 들어 Top 3보다 Top 10에서 답변이 더 이상해졌다고 하자.

    그러면:

    문서를 많이 주면 LLM이 혼란스러워진다.

    라고 바로 결론내리고 싶어진다.

    하지만 그것도 조금 빠른 판단이다.

    Top 4~10 문서를 실제로 확인해야 한다.

    만약 그 문서들이 사용자 질문과 거의 관계없는 자료라면 문제의 시작은 Context 크기 자체보다 retrieval ranking이 뒤쪽에서 빠르게 나빠지는 것일 수 있다.

    반대로 Top 10까지 모두 상당히 관련 있는데 LLM이 근거를 잘 활용하지 못한다면 Prompt 구성이나 Generation 쪽을 봐야 할 수 있다.

    즉:

    Top K 증가
    → 답변 품질 하락
    

    이라는 현상도 다시 나눠야 한다.

    후반 검색 문서가 나쁨?
    

    인지,

    Context는 좋은데 모델 활용이 나쁨?
    

    인지 봐야 한다.

    앞에서 RAG를 Retrieval → Context → Generation으로 나눴던 이유가 여기에서 다시 나타난다.


    그래서 RAG 디버깅에서 “Context에 실제로 무엇을 넣었는가”를 저장하고 싶었다

    최종 답변만 저장하면 Top K를 바꿨을 때 왜 결과가 달라졌는지 알기 어렵다.

    사용자가 같은 질문을 했더라도 당시 검색 결과가 무엇이었는지 모르면 재현하기 어려울 수 있다.

    그래서 요청마다 최소한:

    사용자 질문
    
    검색 mode
    
    Retrieval Top K
    
    검색된 문서 ID
    
    검색 순위
    
    검색 score
    
    실제 Context에 넣은 문서
    
    최종 답변
    

    정도는 연결해두고 싶다.

    이 데이터가 있으면 몇 달 뒤 다음과 같은 분석도 가능하다.

    답변 품질이 낮았던 요청들은 Top K가 작아서 필요한 자료가 빠진 경우가 많았는가?

    아니면 Top K는 충분한데 검색 순위 자체가 좋지 않았는가?

    Context에 너무 많은 중복 문서가 들어갔는가?

    이런 질문에 답할 수 있다.


    그리고 여기에서 reranking이 왜 나오는지도 이해됐다

    처음에는 reranker를 검색을 더 복잡하게 만드는 기능 정도로 봤다.

    이미 KNN으로 순위가 나왔는데 왜 또 순위를 매겨야 하는지 이해하기 어려울 수 있다.

    그런데 RAG Context를 생각하면 이유가 보였다.

    첫 단계에서는 빠르게 후보를 넓게 확보한다.

    그리고 비싼 모델을 전체 문서에 사용할 수 없으니 상위 후보에만 더 정교한 평가를 적용한다.

    Elastic의 semantic reranking도 첫 단계 retrieval이 후보를 만들고 그 후보들을 semantic similarity 모델로 다시 정렬하는 구조를 제공한다.

    개념적으로:

    빠른 Retrieval
    Top 30
    
         ↓
    
    더 정교한 Reranking
    
         ↓
    
    Top 5
    
         ↓
    
    LLM Context
    

    가 가능해진다.

    이 구조의 핵심은 모든 단계에서 같은 수의 문서를 사용하지 않는다는 것이다.

    후보를 찾을 때는 넉넉하게.

    비싼 처리는 좁게.

    LLM에는 정말 필요한 만큼만.

    이 흐름이 RAG를 운영할 때 훨씬 합리적으로 느껴졌다.


    Hybrid Search에서도 같은 생각을 적용할 수 있었다

    내 검색에서는 keyword 신호와 vector 신호를 함께 보는 방식을 사용했다.

    정확한 도서명을 입력하는 사용자와 자연어로 상황을 설명하는 사용자의 의도가 다르기 때문에 하나의 검색 방식만으로는 부족하다고 생각했기 때문이다.

    현재 Elasticsearch도 lexical retrieval과 vector retrieval 결과를 RRF로 결합해 hybrid ranking을 만들 수 있다.

    이 구조에서도 중요한 것은:

    Keyword Top 5 + KNN Top 5니까 10개를 전부 LLM에 넣는다.

    가 아니다.

    두 결과 사이에 같은 문서가 있을 수도 있고 관련도가 다른 문서도 섞일 수 있다.

    먼저 최종 ranking을 만들고 필요한 후보를 고르는 것이 더 자연스럽다.

    이렇게 생각하고 나니 검색 시스템과 RAG Context 구성은 하나의 이어진 pipeline으로 보이기 시작했다.


    결국 Top K는 “많이 찾기”를 결정하는 숫자가 아니었다

    처음의 질문은 단순했다.

    검색 결과를 몇 개 넣어야 하지?

    조금 지나서는:

    좋은 문서를 놓치지 않으려면 많이 넣는 것이 안전하지 않을까?

    라고 생각했다.

    하지만 지금은 질문을 조금 다르게 하고 싶다.

    답변에 필요한 근거를 놓치지 않을 정도로 충분히 넓게 찾되, LLM에는 실제로 도움이 되는 정보만 얼마나 밀도 있게 제공할 수 있는가?

    이 질문에서는 숫자 하나로 끝나지 않는다.

    Retrieval 후보 수가 있고,

    reranking 후보 수가 있고,

    실제 Context 문서 수가 있을 수 있다.

    그리고 문서 수뿐 아니라 문서 길이도 중요하다.

    어떤 필드를 Context로 사용하는지도 중요하다.

    중복 문서도 고려해야 한다.


    실제 도서 서비스라면 다음 실험을 먼저 하고 싶다

    지금 다시 테스트할 수 있다면 20~30개의 자연어 검색 질문을 고정할 것이다.

    그리고 같은 질문을 다음 조건에서 실행한다.

    Context Top 1
    Context Top 3
    Context Top 5
    Context Top 10
    

    검색 엔진과 모델, Prompt는 그대로 둔다.

    그리고 각 조건마다 다음을 기록한다.

    관련 도서가 Context에 포함됐는가.

    답변에서 실제 그 근거를 사용했는가.

    검색되지 않은 책을 만들어내지는 않았는가.

    입력 토큰은 얼마나 사용됐는가.

    응답시간은 얼마나 걸렸는가.

    답변이 불필요하게 길어지지는 않았는가.

    이 데이터를 쌓으면 지금까지 감으로 설정했던 Top K를 실제 서비스의 근거 있는 설정으로 바꿀 수 있을 것 같다.


    마무리

    RAG를 처음 만들 때는 정보를 많이 넣는 것이 안전하다고 생각했다.

    검색 결과 한 개보다는 세 개가 좋고, 세 개보다는 다섯 개가 좋다면 열 개는 더 좋을 것처럼 보였다.

    그런데 검색과 생성 사이의 전체 흐름을 따라가면서 생각이 바뀌었다.

    Top K를 늘리면 좋은 문서를 놓칠 가능성을 줄일 수 있다.

    하지만 동시에 관련성이 낮은 문서와 중복 정보가 Context에 들어올 가능성도 커진다.

    Context가 길어지면 LLM이 처리해야 하는 입력도 증가한다.

    그리고 Retrieval 단계에서 충분히 많은 후보가 필요하다고 해서 그 후보를 모두 LLM에 보여줘야 하는 것은 아니다.

    Elasticsearch도 현재 첫 단계 후보 검색, RRF를 이용한 여러 retrieval 결과의 결합, semantic reranking처럼 여러 단계로 검색 결과를 좁히고 재정렬할 수 있는 구조를 제공한다.

    그래서 지금은 RAG의 Top K를 하나의 숫자로만 생각하지 않는다.

    Retrieval에서 얼마나 넓게 찾을까?
    
    ↓
    
    그중 무엇이 정말 관련 있는가?
    
    ↓
    
    어떤 문서를 Context로 사용할까?
    
    ↓
    
    LLM에게 실제로 필요한 정보는 얼마인가?
    

    로 나눠서 본다.

    결국 목표는 가장 많은 문서를 LLM에 전달하는 것이 아니다.

    사용자가 질문한 내용에 답하기 위해 필요한 근거는 놓치지 않으면서, 불필요한 내용은 최대한 줄인 Context를 만드는 것이다.

    그리고 그것이 제대로 됐는지는 느낌으로 판단하기보다 동일한 질문 세트를 가지고 Top 1·3·5·10을 실제로 비교해봐야 한다.

    그 결과가 있어야 비로소:

    우리 서비스에서는 왜 이 정도의 Context가 필요한가?

    라는 질문에 답할 수 있다.

    나는 이제 그 설명이 가능한 숫자를 찾는 것이 단순히 큰 Top K를 사용하는 것보다 훨씬 중요한 RAG 튜닝이라고 생각한다.