본문 바로가기
Study (Data Science)/NLP

Langchain / Retriever

by 콜라찡 2024. 5. 23.

참고 : https://wikidocs.net/234016

문맥 압축 검색기 ContextualCompressionRetriever

검색 시스템에서 직면하는 어려움 중 하나는 데이터를 시스템에 수집할 때 어떤 특정 질의를 처리해야 할지 미리 알 수 없다는 점입니다.

이는 질의와 가장 관련성이 높은 정보가 많은 양의 무관한 텍스트를 포함한 문서에 묻혀 있을 수 있음을 의미합니다.

이러한 전체 문서를 애플리케이션에 전달하면 더 비용이 많이 드는 LLM 호출과 품질이 낮은 응답으로 이어질 수 있습니다.

ContextualCompressionRetriever 은 이 문제를 해결하기 위해 고안되었습니다.

아이디어는 간단합니다. 검색된 문서를 그대로 즉시 반환하는 대신, 주어진 질의의 맥락을 사용하여 문서를 압축함으로써 관련 정보만 반환되도록 할 수 있습니다.

여기서 "압축"은 개별 문서의 내용을 압축하는 것과 문서를 전체적으로 필터링하는 것 모두를 의미합니다.

Contextual Compression Retriever를 사용하려면 다음이 필요합니다.

  • Base Retriever
  • Document Compressor

ContextualCompressionRetriever 는 질의를 base retriever에 전달하고, 초기 문서를 가져와 Document Compressor를 통과시킵니다.

Document Compressor는 문서 목록을 가져와 문서의 내용을 줄이거나 문서를 완전히 삭제하여 목록을 축소합니다.

 

 

앙상블 검색기 Ensemble Retriever

EnsembleRetriever는 여러 retriever를 입력으로 받아 get_relevant_documents() 메서드의 결과를 앙상블하고, Reciprocal Rank Fusion 알고리즘을 기반으로 결과를 재순위화합니다.

서로 다른 알고리즘의 장점을 활용함으로써, EnsembleRetriever는 단일 알고리즘보다 더 나은 성능을 달성할 수 있습니다.

가장 일반적인 패턴은 sparse retriever (예: BM25)와 dense retriever (예: embedding similarity)를 결합하는 것인데, 이는 두 retriever의 장점이 상호 보완적이기 때문입니다. 이를 "hybrid search" 라고도 합니다.

Sparse retriever는 키워드를 기반으로 관련 문서를 찾는 데 효과적이며, dense retriever는 의미적 유사성을 기반으로 관련 문서를 찾는 데 효과적입니다.

 

 

긴 문맥 재정렬 LongContextReorder -> Cohere와 비교해보기

모델의 아키텍처와 상관없이, 10개 이상의 검색된 문서를 포함할 경우 성능이 상당히 저하됩니다.

간단히 말해, 모델이 긴 컨텍스트 중간에 있는 관련 정보에 접근해야 할 때, 제공된 문서를 무시하는 경향이 있습니다.

자세한 내용은 다음 논문을 참조하세요

이 문제를 피하기 위해, 검색 후 문서의 순서를 재배열하여 성능 저하를 방지할 수 있습니다.

 

 

상위 문서 검색기 Parent Document Retriever

문서 검색과 문서 분할의 균형 잡기

문서 검색 과정에서 문서를 적절한 크기의 조각(청크)으로 나누는 것은 다음의 상충되는 두 가지 중요한 요소를 고려해야 합니다.

  1. 작은 문서를 원하는 경우: 이렇게 하면 문서의 임베딩이 그 의미를 가장 정확하게 반영할 수 있습니다. 문서가 너무 길면 임베딩이 의미를 잃어버릴 수 있습니다.
  2. 각 청크의 맥락이 유지되도록 충분히 긴 문서를 원하는 경우입니다.

ParentDocumentRetriever의 역할

이 두 요구 사항 사이의 균형을 맞추기 위해 ParentDocumentRetriever라는 도구가 사용됩니다. 이 도구는 문서를 작은 조각으로 나누고, 이 조각들을 관리합니다. 검색을 진행할 때는, 먼저 이 작은 조각들을 찾아낸 다음, 이 조각들이 속한 원본 문서(또는 더 큰 조각)의 식별자(ID)를 통해 전체적인 맥락을 파악할 수 있습니다.

여기서 '부모 문서'란, 작은 조각이 나누어진 원본 문서를 말합니다. 이는 전체 문서일 수도 있고, 비교적 큰 다른 조각일 수도 있습니다. 이 방식을 통해 문서의 의미를 정확하게 파악하면서도, 전체적인 맥락을 유지할 수 있게 됩니다.

정리

  • 문서 간의 계층 구조 활용: ParentDocumentRetriever는 문서 검색의 효율성을 높이기 위해 문서 간의 계층 구조를 활용합니다.
  • 검색 성능 향상: 관련성 높은 문서를 빠르게 찾아내며, 주어진 질문에 대한 가장 적합한 답변을 제공하는 문서를 효과적으로 찾아낼 수 있습니다. 문서를 검색할 때 자주 발생하는 두 가지 상충되는 요구 사항이 있습니다:

 

다중 쿼리 검색기 MultiQueryRetriever

거리 기반 벡터 데이터베이스 검색은 고차원 공간에서의 쿼리 임베딩(표현)과 '거리'를 기준으로 유사한 임베딩을 가진 문서를 찾는 방식입니다. 하지만 쿼리의 세부적인 차이나 임베딩이 데이터의 의미를 제대로 포착하지 못할 경우, 검색 결과가 달라질 수 있습니다. 이를 수동으로 조정하는 프롬프트 엔지니어링이나 튜닝 작업은 번거로울 수 있습니다.

이런 문제를 해결하기 위해, MultiQueryRetriever 는 주어진 사용자 입력 쿼리에 대해 다양한 관점에서 여러 쿼리를 자동으로 생성하는 LLM(Language Learning Model)을 활용해 프롬프트 튜닝 과정을 자동화합니다.

이 방식은 각각의 쿼리에 대해 관련 문서 집합을 검색하고, 모든 쿼리를 아우르는 고유한 문서들의 합집합을 추출해, 잠재적으로 관련된 더 큰 문서 집합을 얻을 수 있게 해줍니다. 여러 관점에서 동일한 질문을 생성함으로써, MultiQueryRetriever 는 거리 기반 검색의 제한을 일정 부분 극복하고, 더욱 풍부한 검색 결과를 제공할 수 있습니다.

 

 

셀프 쿼리 검색기 SelfQueryRetriever

SelfQueryRetriever 는 자체적으로 질문을 생성하고 해결할 수 있는 기능을 갖춘 검색 도구입니다. 이는 사용자가 제공한 자연어 질의를 바탕으로, query-constructing LLM chain을 사용해 구조화된 질의를 만듭니다. 그 후, 이 구조화된 질의를 기본 벡터 데이터 저장소(VectorStore)에 적용하여 검색을 수행합니다.

이 과정을 통해, SelfQueryRetriever 는 단순히 사용자의 입력 질의를 저장된 문서의 내용과 의미적으로 비교하는 것을 넘어서, 사용자의 질의에서 문서의 메타데이터에 대한 필터를 추출하고, 이 필터를 실행하여 관련된 문서를 찾을 수 있습니다. 이를 통해, 사용자의 질의에 대한 더 정확하고 관련성 높은 결과를 제공할 수 있게 됩니다.

 

 

다중 벡터저장소 검색기 MultiVectorRetriever

LangChain에서는 문서를 다양한 상황에서 효율적으로 쿼리할 수 있는 특별한 기능, 바로 MultiVectorRetriever를 제공합니다. 이 기능을 사용하면 문서를 여러 벡터로 저장하고 관리할 수 있어, 정보 검색의 정확도와 효율성을 대폭 향상시킬 수 있습니다. 오늘은 이 MultiVectorRetriever를 활용해 문서당 여러 벡터를 생성하는 몇 가지 방법을 살펴보겠습니다.

문서당 여러 벡터 생성 방법 소개

  1. 작은 청크 생성: 문서를 더 작은 단위로 나눈 후, 각 청크에 대해 별도의 임베딩을 생성합니다. 이 방식을 사용하면 문서의 특정 부분에 좀 더 세심한 주의를 기울일 수 있습니다. 이 과정은 ParentDocumentRetriever를 통해 구현할 수 있어, 세부 정보에 대한 탐색이 용이해집니다.
  2. 요약 임베딩: 각 문서의 요약을 생성하고, 이 요약으로부터 임베딩을 만듭니다. 이 요약 임베딩은 문서의 핵심 내용을 신속하게 파악하는 데 큰 도움이 됩니다. 문서 전체를 분석하는 대신 핵심적인 요약 부분만을 활용하여 효율성을 극대화할 수 있습니다.
  3. 가설 질문 활용: 각 문서에 대해 적합한 가설 질문을 만들고, 이 질문에 기반한 임베딩을 생성합니다. 특정 주제나 내용에 대해 깊이 있는 탐색을 원할 때 이 방법이 유용합니다. 가설 질문은 문서의 내용을 다양한 관점에서 접근하게 해주며, 더 광범위한 이해를 가능하게 합니다.
  4. 수동 추가 방식: 사용자가 문서 검색 시 고려해야 할 특정 질문이나 쿼리를 직접 추가할 수 있습니다. 이 방법을 통해 사용자는 검색 과정에서 보다 세밀한 제어를 할 수 있으며, 자신의 요구 사항에 맞춘 맞춤형 검색이 가능해집니다.

MultiVectorRetriever를 통해 이러한 다양한 접근 방식을 유연하게 활용함으로써, 사용자는 필요한 정보를 보다 정확하고 빠르게 찾을 수 있습니다. LangChain의 이 기능은 정보 검색 작업을 보다 효과적으로 만들어주는 훌륭한 도구입니다.

 

 

시간 가중 벡터저장소 검색기 TimeWeightedVectorStoreRetriever

TimeWeightedVectorStoreRetriever 는 의미론적 유사성과 시간에 따른 감쇠를 결합해 사용하는 검색 도구입니다. 이를 통해 문서 또는 데이터의 "신선함"  "관련성" 을 모두 고려하여 결과를 제공합니다.

스코어링 알고리즘은 다음과 같이 구성됩니다

semantic_similarity+(1.0−decay_rate)ℎ𝑜𝑢𝑟𝑠𝑝𝑎𝑠𝑠𝑒𝑑

여기서 semantic_similarity 는 문서 또는 데이터 간의 의미적 유사도를 나타내고, decay_rate 는 시간이 지남에 따라 점수가 얼마나 감소하는지를 나타내는 비율입니다. hours_passed 는 객체가 마지막으로 접근된 후부터 현재까지 경과한 시간(시간 단위)을 의미합니다.

이 방식의 주요 특징은, 객체가 마지막으로 접근된 시간을 기준으로 하여 "정보의 신선함" 을 평가한다는 점입니다. 즉, 자주 접근되는 객체는 시간이 지나도 높은 점수를 유지하며, 이를 통해 자주 사용되거나 중요하게 여겨지는 정보가 검색 결과 상위에 위치할 가능성이 높아집니다. 이런 방식은 최신성과 관련성을 모두 고려하는 동적인 검색 결과를 제공합니다.

특히, decay_rate는 리트리버의 객체가 생성된 이후가 아니라 **마지막으로 액세스된 이후 경과된 시간을 의미합니다. 즉, 자주 액세스하는 객체는 '최신'으로 유지됩니다.

728x90

댓글