본문 바로가기
카테고리 없음

RAG 토큰 관리 - 검색 최적화, 재순위화, 컨텍스트

by BOOST YOUR INFORMATION 2026. 5. 22.

RAG 토큰 관리 (검색 최적화, 재순위화, 컨텍스트) 참조 이미지
RAG 토큰 관리

 

사내 Q&A 시스템을 처음 만들 때 저도 이 질문 앞에서 한참 멈췄습니다. 많이 넣으면 더 좋은 답이 나올 것 같은데, 실제로 해보면 꼭 그렇지만은 않더군요. 이 글은 그 시행착오를 정리한 기록이자, 제가 직접 부딪히면서 생긴 비판적 시각을 함께 담은 글입니다.

검색 결과를 많이 넣으면 정말 더 좋아질까요

처음에 저는 top_k=10으로 설정해 검색된 문서 청크 10개를 모두 컨텍스트에 넣었습니다. 청크란 긴 문서를 LLM이 처리할 수 있도록 일정 크기로 잘라낸 조각입니다. 답변이 길고 풍성해 보이니 잘 되는 것 같았습니다. 적어도 그렇게 느꼈습니다.

그런데 실제 사용자 피드백을 받아보니 상황이 달랐습니다. 핵심 답변이 여러 청크 사이에서 희석되거나, 서로 약간씩 다른 내용을 담은 문서들이 동시에 주입되면서 모델이 모순된 답변을 내놓는 경우가 생겼습니다. 정보를 많이 줄수록 더 정확해질 거라는 직관이 완전히 빗나간 순간이었습니다.

이 문제의 원인은 어텐션 메커니즘에 있습니다. 어텐션 메커니즘이란 LLM이 입력된 텍스트에서 어떤 부분에 얼마나 집중할지를 결정하는 핵심 구조입니다. 관련 없는 청크가 많아질수록 모델의 어텐션이 분산되고, 노이즈가 섞여 정작 중요한 정보를 제대로 활용하지 못하게 됩니다.

여기서 제가 하고 싶은 말이 있습니다. 많은 RAG 튜토리얼이 top_k를 5나 10으로 그냥 고정해두고 넘어갑니다. 하지만 저는 이 숫자가 시스템 전체 품질에 미치는 영향이 얼마나 큰지 직접 겪고 나서야 제대로 이해했습니다. RAG 최적화는 엔지니어링보다 편집자의 감각에 가깝다는 생각이 든 건 이때부터였습니다. 무엇을 포함시킬 것인가보다 무엇을 제외할 것인가가 더 중요한 결정입니다.

컨텍스트 배치 순서가 답변 품질을 바꿉니다

검색 결과를 줄이는 것만으로는 부족했습니다. 어떤 순서로 넣느냐도 중요하다는 걸 알게 됐습니다.

Liu 등의 연구에 따르면 LLM은 컨텍스트 윈도우의 앞부분과 끝부분에 위치한 정보를 중간보다 훨씬 잘 활용하는 경향이 있다고 합니다. 컨텍스트 윈도우란 LLM이 한 번에 처리할 수 있는 텍스트의 최대 범위입니다. 이 현상은 "Lost in the Middle"이라는 표현으로 알려져 있으며, 중간에 배치된 정보는 사실상 묻혀버리는 경우가 많습니다.

저는 이 연구를 접한 뒤 바로 청크 배치 순서를 바꿨습니다. 코사인 유사도 기준으로 가장 관련성 높은 청크는 컨텍스트 맨 앞에, 두 번째로 중요한 청크는 맨 뒤에 배치했습니다. 코사인 유사도란 두 벡터 간의 방향 유사성을 0에서 1 사이의 수치로 나타낸 것으로, RAG에서 쿼리와 청크의 의미적 유사성을 측정하는 데 쓰입니다. 이 순서 재배치만으로도 답변 정확도가 체감상 올라갔습니다. 코드 한 줄 바꾸지 않고 얻은 개선이었기에 인상적이었습니다.

단, 솔직히 한 가지 비판을 덧붙이고 싶습니다. "Lost in the Middle" 연구는 맥락이 있고, 모든 모델과 모든 태스크에 동일하게 적용되지는 않습니다. 최근 모델들은 긴 컨텍스트 처리 능력이 점점 개선되고 있어서, 이 현상의 정도가 모델마다 다를 수 있습니다. 이 전략은 분명 효과가 있었지만, 무조건 맹신하기보다는 직접 A/B 테스트로 검증하는 것이 맞습니다. 연구 결과를 읽고 바로 적용하는 것과, 내 시스템에서 직접 확인하는 것은 다른 일입니다.

재순위화 모델을 붙이면서 달라진 것들

청크 배치 순서를 조정한 뒤에도 여전히 아쉬운 부분이 있었습니다. 1차 벡터 검색 자체가 의미적으로 유사하지만 질문의 의도와는 어긋난 문서를 올려보내는 경우가 있었거든요.

이때 도입한 것이 재순위화 단계입니다. 재순위화란 1차 검색으로 걸러낸 후보 문서들을 더 정교한 모델로 다시 평가해 순위를 재조정하는 과정입니다. 저는 Cohere Rerank와 크로스인코더 모델을 비교 테스트했습니다. 크로스인코더란 쿼리와 문서를 쌍으로 묶어 함께 입력받아 관련도를 직접 계산하는 방식으로, 양방향 어텐션을 활용하기 때문에 단순 벡터 유사도보다 정밀합니다.

top_k를 10에서 3~4로 줄이고 재순위화를 붙였을 때 답변 품질은 유지되거나 오히려 나아졌고, 토큰 사용량은 눈에 띄게 줄었습니다. 하지만 여기에도 맹점이 있습니다. 재순위화 모델 자체가 레이턴시를 추가합니다. 사내 Q&A처럼 응답 속도가 크리티컬하지 않은 서비스에서는 문제없지만, 실시간 대화 인터페이스에서는 재순위화 레이어 하나가 체감 속도를 눈에 띄게 저하시킬 수 있습니다. 비용과 속도, 두 가지를 동시에 보면서 조율해야 합니다.

현재 제 파이프라인에서 효과적이라고 확인된 설정을 정리하면 다음과 같습니다. 1차 벡터 검색은 top_k=10~20으로 후보 풀을 확보하고, Cohere Rerank 또는 크로스인코더로 재정렬한 뒤, 최종 컨텍스트 주입 단계에서 상위 3~4개 청크만 선별합니다. 배치 순서는 최고 관련 청크를 앞에, 두 번째를 끝에 놓습니다.

토큰 예산을 명시적으로 나눠 관리하는 이유

재순위화까지 도입하고 나니 자연스럽게 토큰 예산 관리가 필요해졌습니다. 컨텍스트를 줄였더니 다른 영역에 쓸 수 있는 토큰이 늘어났고, 이를 체계적으로 배분할 필요가 생겼습니다.

토큰 예산이란 LLM에 입력하고 출력하는 텍스트 전체를 토큰 단위로 계산해 각 구성 요소에 할당량을 정해두는 방식입니다. 저는 쿼리, 시스템 프롬프트, 검색 결과, 출력 이렇게 네 영역으로 나눠 명시적으로 관리하기 시작했습니다. Anthropic의 공식 가이드에서도 컨텍스트 구성 시 각 요소의 토큰 비중을 의식적으로 설계할 것을 권장합니다.

이 관리 방식이 생기고 나서 가장 달라진 점은, 시스템 프롬프트가 예상보다 많은 토큰을 잡아먹고 있다는 사실을 발견한 것입니다. 개선 여지가 어디에 있는지 숫자로 보이니 의사결정이 훨씬 명확해졌습니다. 막연히 "뭔가 비용이 많이 나오는 것 같다"는 감각에서 "시스템 프롬프트가 전체의 30%를 차지한다"는 측정값으로 바뀌면 행동이 달라집니다.

한 가지 더 짚고 싶은 건, 최적의 top_k 값은 도메인과 문서 유형에 따라 크게 달라진다는 점입니다. 단일 설정을 전체 시스템에 적용하는 건 위험합니다. 예를 들어, 짧고 명확한 FAQ 문서로 구성된 시스템과 수십 페이지짜리 기술 사양서를 다루는 시스템이 같은 top_k를 쓰면 둘 다 최적이 아닙니다. 질문 복잡도에 따라 동적으로 검색 개수를 조정하는 적응형 RAG 방식이 더 현실적인 솔루션일 수 있습니다.

이 분야는 아직 표준화된 베스트 프랙티스가 부족하고, 실험과 평가 루프를 직접 구축하는 것이 현 시점에서는 가장 확실한 접근이라고 봅니다. RAG 파이프라인을 고민 중이라면, 일단 top_k를 줄이고 재순위화를 붙이는 것부터 시작해 보시길 권합니다. 많이 넣는 게 능사가 아니라는 걸, 저는 꽤 많은 토큰 낭비를 겪고 나서야 제대로 이해했습니다.

그리고 시스템의 복잡도를 높이기 전에 평가 기준을 먼저 세우는 것이 순서입니다. 재순위화를 붙이고, 배치 순서를 바꿨는데 실제로 좋아졌는지 어떻게 측정할 것인지를 먼저 정해두지 않으면, 아무리 공들인 최적화도 자기만족에 그칠 수 있습니다. 이게 제가 이 작업을 통해 배운 가장 실용적인 교훈입니다.

 

참고


소개 및 문의 · 개인정보처리방침 · 면책조항

© 2026 ⚡ 정보 부스터 🚀