간단하고 효과적인 RAG 검색 전략: 희소 + 고밀도 하이브리드 검색 및 재배치, '큐 캐싱'을 사용해 텍스트 청크에 대한 전체 문서 관련 컨텍스트를 생성합니다.

특정 시나리오에서 AI 모델이 유용하게 사용되려면 일반적으로 배경 지식에 액세스할 수 있어야 합니다. 예를 들어 고객 지원 챗봇은 특정 비즈니스에 대한 이해가 필요하고, 법률 분석 챗봇은 수많은 과거 사례에 액세스할 수 있어야 합니다.
개발자는 지식 기반에서 관련 정보를 검색하고 이를 사용자 프롬프트에 첨부하여 모델의 응답성을 크게 향상시키는 방법인 검색 증강 생성(RAG)을 사용하여 AI 모델의 지식을 보강하는 경우가 많습니다. 문제는 기존의 RAG 프로그램에서 정보를 인코딩할 때 컨텍스트가 손실되어 시스템이 지식창고에서 관련 정보를 검색할 수 없는 경우가 종종 있습니다.
이 백서에서는 RAG의 검색 단계를 크게 개선할 수 있는 접근 방식에 대해 설명합니다. 이 접근 방식은 컨텍스트 검색이라고 불리며 컨텍스트 임베딩과 컨텍스트 BM25라는 두 가지 하위 기술을 사용합니다. 이 접근 방식은 검색 실패 횟수를 491 TP3T, 재랭크와 결합하면 671 TP3T까지 줄여주며, 이러한 개선은 검색 정확도를 크게 높여 다운스트림 작업의 성능 향상으로 직결됩니다.
본질은 의미적으로 유사한 결과와 단어 빈도가 유사한 결과가 혼합되어 있으며, 때로는 의미적 결과가 실제 의도를 나타내지 않는 경우도 있습니다. 본문 끝에 제공된 링크를 읽어보면 이 "오래된" 전략이 출시된 지 2년이 지났으며, 이 방법은 매우 복잡한 RAG 전략에 빠지거나 임베딩 + 재배열만 사용하는 등 여전히 거의 사용되지 않고 있습니다.
이 글은 '캐시 힌트'를 사용하여 문서의 전체 컨텍스트에 맞는 텍스트 블록의 컨텍스트를 저렴한 비용으로 생성하는 기존 전략을 약간 개선한 것입니다. 작은 변화이지만 그 결과는 인상적입니다!
다음과 같이 할 수 있습니다. 샘플 코드 활용 Claude 나만의 문맥 검색 솔루션을 배포하세요.
긴 팁의 간단한 사용에 대한 참고 사항
때로는 가장 간단한 해결책이 가장 좋은 해결책이기도 합니다. 지식창고가 200,000토큰(약 500페이지 분량) 미만인 경우에는 모델에 제공되는 프롬프트에 전체 지식창고를 직접 포함할 수 있으므로 RAG나 이와 유사한 방법을 사용할 필요가 없습니다.
몇 주 전, 우리는 Claude를 위해 출시했습니다. 큐 캐시새로운 API와 더불어 이 접근 방식의 속도를 크게 높이고 비용도 절감했습니다. 이제 개발자는 API 호출 간에 자주 사용하는 힌트를 캐시하여 지연 시간을 2배 이상 줄이고 비용을 최대 90%까지 절감할 수 있습니다. 힌트 캐시 샘플 코드 (작동 방식 이해).
하지만 지식창고가 커지면 확장성이 뛰어난 솔루션이 필요하게 되는데, 바로 여기에 문맥 검색이 등장합니다. 이러한 배경 지식을 정리하고 본론으로 들어가 보겠습니다.
RAG 기본 사항: 더 큰 지식창고로 확장하기
RAG는 컨텍스트 창에 맞지 않는 대규모 지식창고를 위한 일반적인 솔루션으로, 다음 단계에 따라 지식창고를 전처리합니다:
- 지식창고(문서 "말뭉치")를 보통 수백 개 이하의 작은 텍스트 조각으로 분해(지나치게 긴 텍스트 블록은 더 많은 의미를 표현, 즉 의미론적으로 너무 풍부함).
- 세그먼트는 임베딩 모델을 사용하여 의미를 인코딩하는 벡터 임베딩으로 변환됩니다;
- 이러한 임베딩을 벡터 데이터베이스에 저장하여 의미적 유사성을 기준으로 검색할 수 있습니다.
런타임에 사용자가 모델에 쿼리를 입력하면 벡터 데이터베이스는 쿼리의 의미적 유사성을 기반으로 가장 관련성이 높은 조각을 찾습니다. 그런 다음 가장 관련성이 높은 조각이 생성 모델에 전송되는 프롬프트에 추가됩니다(더 큰 모델 참조의 컨텍스트로 질문에 대한 답변).
임베딩 모델은 의미 관계를 잘 포착하지만, 중요한 정확한 일치 항목을 놓칠 수 있습니다. 다행히도 이러한 경우 오래된 기술이 도움이 될 수 있습니다. BM25는 어휘 일치를 통해 정확한 단어 또는 구문 일치를 찾아내는 순위 지정 기능입니다. 고유 식별자나 전문 용어가 포함된 쿼리에 특히 효과적입니다.
BM25 문서 모음에서 단어의 중요도를 측정하는 TF-IDF(단어 빈도-역 문서 빈도) 개념을 기반으로 개선된 BM25는 문서의 길이를 고려하고 단어 빈도에 포화 함수를 적용하여 일반적인 단어가 결과를 지배하는 것을 방지합니다.
시맨틱 임베딩이 실패할 때 BM25가 작동하는 방식은 다음과 같습니다. 사용자가 기술 지원 데이터베이스에 "오류 코드 TS-999"를 쿼리한다고 가정해 보겠습니다. (벡터) 임베딩 모델은 오류 코드에 대한 일반적인 콘텐츠를 찾을 수 있지만 정확한 "TS-999" 일치 항목을 놓칠 수 있습니다. 대신 BM25는 관련 문서를 식별하기 위해 특정 텍스트 문자열을 찾습니다.
임베딩과 BM25 기술을 결합하여 RAG 프로그램은 다음과 같이 가장 관련성이 높은 조각을 보다 정확하게 검색할 수 있습니다:
- 지식창고(문서 "코퍼스")는 보통 수백 개 이하의 작은 텍스트 조각으로 나뉘어져 있습니다;
- 이러한 세그먼트에 대한 TF-IDF 인코딩 및 시맨틱(벡터) 임베딩을 생성합니다;
- BM25를 사용하여 정확히 일치하는 최적의 조각을 찾습니다;
- (벡터) 임베딩을 사용하여 의미적 유사성이 가장 높은 세그먼트를 찾습니다;
- (3)과 (4)의 결과는 정렬 융합 기법(예: 전용 재주문 모델 Rerank 3.5)을 사용하여 병합 및 강조 해제됩니다.
- 첫 번째 K 세그먼트를 프롬프트에 추가하여 응답을 생성합니다.
BM25와 임베딩 모델을 결합함으로써 기존 RAG 시스템은 정확한 용어 매칭과 더 넓은 의미론적 이해 사이에서 균형을 유지하여 보다 포괄적이고 정확한 결과를 제공할 수 있습니다.

임베딩과 BM25(Best Match 25)를 결합하여 정보를 검색하는 표준 검색 증강 생성(RAG) 시스템으로, 단어의 중요도를 측정하여 BM25의 기초가 되는 TF-IDF(단어 빈도 역문서 빈도)를 사용합니다.
이 접근 방식을 사용하면 저렴한 비용으로 단일 프롬프트에서 수용할 수 있는 것보다 훨씬 더 큰 규모의 지식창고로 확장할 수 있습니다. 하지만 이러한 기존 RAG 시스템에는 종종 컨텍스트를 깨뜨리는 중대한 한계가 있습니다.
합리적인 디자인을 만들기 위해 검색 체계를 기반으로 여기에서 말하기는 아직 잘린 텍스트 블록에 대해 말하지 않았으며, 잘린 텍스트 블록은 동일한 내용을 표현하는 것이며, 절대로 잘리지 않아야하지만 위의 RAG 체계불가피하게 문맥이 잘립니다.. 이것은 간단하면서도 복잡한 문제입니다. 이 글의 요점을 살펴 보겠습니다.
기존 RAG의 상황별 어려움
기존 RAG에서는 효율적인 검색을 위해 문서를 작은 덩어리로 분할하는 경우가 많습니다. 이 접근 방식은 많은 애플리케이션 시나리오에 적합하지만 개별 청크에 충분한 컨텍스트가 부족할 경우 문제가 발생할 수 있습니다.
예를 들어 지식창고에 재무 정보(예: 미국 증권거래위원회 보고서)가 포함되어 있는데 다음과 같은 질문을 받는다고 가정해 보겠습니다:"2023년 2분기 ACME Corporation의 매출 성장률은 얼마인가요?"
관련 블록에는 다음과 같은 텍스트가 포함될 수 있습니다:"회사의 매출은 전 분기 대비 31조 3,000억 원 증가했습니다." 그러나 블록 자체에 특정 회사나 관련 기간이 명시적으로 언급되어 있지 않아 정확한 정보를 검색하거나 효과적으로 사용하기가 어렵습니다.
문맥 검색 소개
컨텍스트 검색은 각 블록에 특정 블록을 추가하여 수행됩니다.해석적 컨텍스트("컨텍스트 임베딩") 및 BM25 인덱스("컨텍스트 BM25")를 생성하면 이 문제를 해결할 수 있습니다.
SEC 보고서 수집 예제로 돌아가 보겠습니다. 다음은 블록이 변환되는 방법의 예입니다:
original_chunk = "该公司的收入比上一季度增长了 3%。"
contextualized_chunk = "该块来自一份关于 ACME 公司 2023 年第二季度表现的 SEC 报告;上一季度的收入为 3.14 亿美元。该公司的收入比上一季度增长了 3%。"
과거에 검색을 개선하기 위해 문맥을 사용하는 다른 여러 가지 방법이 제안되었다는 점에 주목할 필요가 있습니다. 다른 제안은 다음과 같습니다:블록에 일반 문서 요약 추가하기(실험 결과 이득이 매우 제한적인 것으로 나타났습니다),가상의 문서 임베딩 노래로 응답 추상 기반 인덱싱(평가한 결과 성능이 낮은 것으로 나타났습니다). 이러한 방법은 이 백서에서 제안한 방법과는 다릅니다.
컨텍스트 품질을 개선하는 많은 방법이 실험적으로 효과가 제한적인 것으로 나타났으며, 위에서 언급한 상대적으로 가장 좋은 방법도 여전히 의문의 여지가 있습니다.이 변환 프로세스에 설명 컨텍스트를 추가하면 정보가 다소 손실될 수 있기 때문입니다..
전체 단락을 텍스트 블록으로 나누고 전체 단락의 내용에 여러 수준의 제목을 추가하더라도 위의 예에서 꿈이라고 한 것처럼 문맥에서 벗어난 이 단락만으로는 지식을 정확하게 전달하지 못할 수 있습니다.
이 방법은 텍스트 블록의 콘텐츠가 단독으로 존재할 때 문맥적 배경이 부족하면 콘텐츠가 고립되어 의미가 없는 문제가 발생하는 문제를 효과적으로 해결합니다.
문맥 검색 활성화
물론 지식창고에 있는 수천, 수백만 개의 블록에 수동으로 주석을 다는 것은 너무 많은 작업입니다. 문맥 검색을 가능하게 하기 위해 Claude를 사용했고, 전체 문서의 문맥을 기반으로 간결한 블록별 문맥을 제공하도록 모델에 지시하는 힌트를 작성했습니다. 다음은 각 블록에 대한 컨텍스트를 생성하기 위해 Claude 3 하이쿠의 힌트를 사용한 방법입니다:
<document>
{{WHOLE_DOCUMENT}}
</document>
这是我们希望置于整个文档中的块
<chunk>
{{CHUNK_CONTENT}}
</chunk>
请提供一个简短且简明的上下文,以便将该块置于整个文档的上下文中,从而改进块的搜索检索。仅回答简洁的上下文,不要包含其他内容。
생성된 컨텍스트 텍스트는 일반적으로 50-100 토큰이며, 임베딩 전과 BM25 인덱스를 생성하기 전에 블록에 추가됩니다.
이 큐 실행은 텍스트 블록에 해당하는 전체 문서를 참조해야 합니다(500페이지를 넘지 않아야 하죠?). 를 큐 캐시로 사용하여 전체 문서를 기준으로 텍스트 블록과 관련된 컨텍스트를 정확하게 생성해야 합니다.
이것은 클로드의 캐싱 능력에 의존하며, 입력을 캐시하라는 프롬프트로서 전체 문서는 매번 지불 할 필요가 없으며 캐싱, 한 번만 지불하면되므로 전제 조건을 달성하기위한 프로그램은 다음과 같습니다.대형 모델로 긴 문서 캐싱 가능DeepSeek와 같은 모델도 비슷한 기능을 제공합니다.
다음은 실제 전처리 과정입니다:

문맥 검색은 검색 정확도를 향상시키는 전처리 기술입니다.
문맥 검색을 사용하는 데 관심이 있으시면 다음 도움말을 참조하세요. 운영 매뉴얼 시작.
힌트 캐싱으로 컨텍스트 검색 비용 절감하기
앞서 언급한 특별한 힌트 캐싱 기능 덕분에 저렴한 비용으로 Claude 컨텍스트를 통한 검색을 수행할 수 있습니다. 힌트 캐싱을 사용하면 각 블록에 대한 참조 문서를 전달할 필요가 없습니다. 문서를 캐시에 한 번만 로드한 다음 이전에 캐시된 콘텐츠를 참조하기만 하면 됩니다. 블록당 800 토큰, 문서당 8k 토큰, 컨텍스트 인스트럭션당 50 토큰, 블록 컨텍스트당 100 토큰이라고 가정하면컨텍스트화된 블록을 생성하는 일회성 비용은 문서 토큰 백만 개당 $1.02입니다..
방법론
다양한 지식 영역(코드베이스, 소설, ArXiv 논문, 과학 논문), 임베딩 모델, 검색 전략 및 평가 지표에 대한 실험을 수행했습니다. 실험을 수행한 영역은 다음과 같습니다. 부록 II 각 도메인에 사용한 질문과 답변의 몇 가지 예가 아래에 나열되어 있습니다.
아래 그림은 가장 성능이 좋은 임베딩 구성(Gemini Text 004)을 사용하고 처음 20개의 스니펫을 검색할 때 모든 지식 영역의 평균 성능을 보여줍니다. 평가 지표로 1 마이너스 recall@20을 사용했는데, 이는 처음 20개의 스니펫에서 검색에 실패한 관련 문서의 비율을 측정하는 것입니다. 전체 결과는 부록에서 확인할 수 있습니다. 문맥화는 평가한 모든 임베디드 소스 조합에서 성능을 향상시켰습니다.
성능 향상
실험을 통해 알 수 있습니다:
- 컨텍스트 임베딩은 처음 20개 조각의 검색 실패율을 35% 감소시켰습니다.(5.7% → 3.7%).
- 문맥 임베딩과 문맥 BM25를 결합하면 처음 20개 조각의 검색 실패율이 49% 감소했습니다.(5.7% → 2.9%).

문맥 임베딩과 문맥 BM25를 결합하면 처음 20개 조각의 검색 실패율이 49% 감소했습니다.
구현 고려 사항
문맥 검색을 구현할 때는 다음 사항을 염두에 두어야 합니다:
- 조각 경계: 문서가 어떻게 조각으로 분할될지 고려하세요. 조각 크기, 경계 및 겹침의 선택은 검색 성능 ^1^에 영향을 줄 수 있습니다.
- 모델 임베딩: 문맥 검색은 테스트한 모든 임베딩 모델의 성능을 향상시키지만, 특정 모델의 경우 더 많은 이점을 얻을 수 있습니다. 그 결과는 다음과 같습니다. 쌍둥이자리 노래로 응답 Voyage 임베딩은 특히 효과적입니다.
- 사용자 지정 문맥 단서: 제공하는 일반적인 프롬프트도 잘 작동하지만 특정 도메인이나 사용 사례에 맞게 프롬프트를 사용자 지정하면 더 나은 결과를 얻을 수 있습니다(예: 지식창고에 다른 문서에 정의되어 있는 주요 용어의 용어집을 포함시키는 등).
- 클립 수입니다: 컨텍스트 창에 더 많은 조각을 추가하면 관련 정보를 포함할 확률이 높아집니다. 그러나 너무 많은 정보는 모델의 주의를 분산시킬 수 있으므로 그 수를 조절해야 합니다. 5개, 10개, 20개의 조각을 사용해 본 결과 20개의 조각을 사용하는 것이 가장 좋은 결과를 보였지만(자세한 내용은 부록 참조), 사용 사례에 따라 실험해 보는 것이 좋습니다.
항상 평가를 실행합니다: 문맥에 맞는 스니펫을 전달하고 문맥과 스니펫을 구분하여 응답 생성을 개선할 수 있습니다.
재정렬을 사용하여 성능 향상
마지막 단계에서는 문맥 검색을 다른 기술과 결합하여 성능을 더욱 향상시킬 수 있습니다. 기존의 RAG(검색 증강 세대)에서는 AI 시스템이 지식 기반에서 잠재적으로 관련성이 있는 정보를 검색합니다. 대규모 지식 베이스의 경우, 초기 검색은 일반적으로 관련성과 중요도가 다양한 수많은 조각(때로는 수백 개에 달할 수도 있음)을 반환합니다.
재정렬은 가장 관련성이 높은 부분만 모델에 전달되도록 하는 일반적인 필터링 기법입니다. 재정렬은 모델이 처리하는 정보의 양이 적기 때문에 비용과 지연 시간을 줄이면서 더 나은 응답을 제공합니다. 주요 단계는 다음과 같습니다:
- 가장 관련성이 높은 세그먼트를 얻기 위해 초기 검색을 수행했습니다(처음 150개를 사용했습니다);
- 처음 N개의 세그먼트와 사용자 쿼리를 재정렬 모델에 전달합니다;
- 재정렬 모델을 사용하여 큐와의 관련성 및 중요도에 따라 각 클립에 점수를 매긴 다음 상위 K 클립을 선택했습니다(상위 20개 사용);
- 첫 번째 K 세그먼트는 모델에 컨텍스트로 전달되어 최종 결과를 생성합니다.
문맥 검색과 재정렬을 결합하면 검색 정확도가 극대화됩니다.
성능 향상
시중에는 다양한 재주문 모델이 있습니다. 저희는 코히어 리오더 테스트를 실행했습니다. 항해 리오더도 제공됩니다.를 테스트할 시간이 없었습니다. 실험 결과 재정렬 단계를 추가하면 다양한 도메인에서 검색을 더욱 최적화할 수 있는 것으로 나타났습니다.
구체적으로 문맥 임베딩과 문맥 BM25의 순서를 바꾸면 상위 20개 조각의 검색 실패율이 671 TP3T(5.71 TP3T → 1.91 TP3T) 감소하는 것으로 나타났습니다.
컨텍스트 임베딩과 컨텍스트 BM25를 재정렬하면 처음 20개 조각의 검색 실패율이 67% 감소했습니다.
비용 및 지연 고려 사항
재주문 시 중요한 고려 사항은 지연 시간과 비용에 미치는 영향이며, 특히 많은 수의 조각을 재주문할 때 더욱 그렇습니다. 재정렬은 런타임에 추가 단계를 추가하기 때문에 재정렬자가 모든 조각을 나란히 점수화하더라도 필연적으로 약간의 지연 시간이 추가될 수밖에 없습니다. 더 많은 조각을 재주문하여 성능을 높이는 것과 더 적은 조각을 재주문하여 지연 시간과 비용을 줄이는 것 사이에는 상충 관계가 있습니다. 특정 사용 사례에 따라 다양한 설정을 실험하여 최적의 균형을 찾는 것이 좋습니다.
평결에 도달하기
위의 모든 기법(임베딩 모델, BM25 사용, 문맥 검색 사용, 재정렬기 사용, 검색된 상위 K 결과 수)의 다양한 조합을 비교하는 여러 가지 테스트를 실행하고 다양한 데이터 세트 유형에 걸쳐 실험을 진행했습니다. 다음은 그 결과를 요약한 것입니다:
- 임베딩 + BM25는 임베딩만 사용하는 것보다 낫습니다;
- 항해 및 쌍둥이자리 는 테스트에서 가장 효과가 좋았던 임베딩 모델입니다;
- 처음 20개의 세그먼트를 모델에 전달하는 것이 처음 10개 또는 5개만 전달하는 것보다 더 효과적입니다;
- 세그먼트에 컨텍스트를 추가하면 검색 정확도가 크게 향상됩니다;
- 재주문하는 것이 재주문하지 않는 것보다 낫습니다;
- 이러한 모든 장점은 중첩될 수 있습니다: 성능 향상을 극대화하려면 컨텍스트 임베딩(Voyage 또는 Gemini에서), 컨텍스트 BM25, 단계 재정렬, 프롬프트에 20개의 스니펫 추가를 조합하여 사용할 수 있습니다.
지식창고를 사용하는 모든 개발자에게는 실무 매뉴얼 이러한 방법을 실험해보고 새로운 차원의 성능을 경험해 보세요.
부록 I
아래는 데이터 세트, 임베드된 공급자, 임베딩과 함께 사용된 BM25, 문맥 검색 사용, 재정렬 사용에 대한 검색 @ 20 결과의 세부 분석입니다.
검색 횟수 @ 10 및 @ 5에 대한 분석과 각 데이터 집합에 대한 샘플 질문 및 답변은 다음을 참조하세요. 부록 II.
데이터 세트 및 임베디드 공급자 결과에 대해 1에서 리콜 @ 20을 뺀 값입니다.
각주
© 저작권 정책
기사 저작권 AI 공유 서클 모두 무단 복제하지 마세요.
관련 문서
댓글 없음...