langchain / / 2024. 6. 27. 06:49

[langchain] 벡터저장소 지원 검색기(VectorStore-backed Retriever)

VectorStore-backed Retriever는 문서를 검색하기 위해 벡터 저장소를 사용하는 Retriever를 말한다. Retriever 인터페이스에 대응하는 벡터 저장 클래스의 경량 래퍼 클래스이다. 벡터 저장소에서 구현되는 검색 메소드를 사용한다.

아래의 코드 예제를 한번 보자.

[main.py]

from dotenv import load_dotenv
from langchain_community.document_loaders import TextLoader

from langchain_community.vectorstores import Chroma
from langchain_openai import OpenAIEmbeddings
from langchain_text_splitters import CharacterTextSplitter

load_dotenv()

embeddings = OpenAIEmbeddings()
vector_store = Chroma(persist_directory="chroma_emb", embedding_function=embeddings)

loader = TextLoader("./data/baseball.txt")
documents = loader.load()
text_splitter = CharacterTextSplitter(chunk_size=200, chunk_overlap=0)
texts = text_splitter.split_documents(documents)
vector_store.add_documents(texts, add_to_docstore=True)

question = "박병호는 인천에서 몇 개의 홈런을 쳤나?"
retriever = vector_store.as_retriever()
docs = retriever.invoke(question)

print("====== retriever result ========")
for i, doc in enumerate(docs):
    print(f"[문서 {i}] {doc.page_content.replace('\n', ' ')}")
  • loader를 사용해서 문서를 로딩한다.
  • CharacterTextSplitter를 사용해 문서를 짜른다. (청크: 200자)
  • 문서 내용을 임베딩하고 Chroma DB에 넣는다.
  • Vector store에서 검색한다.

vector_store.as_retriever()에 invoke()를 통해 검색을 한다.

[baseball.txt 파일 내용]

이적 후 5경기 홈런 세 방. 타자친화구장인 대구 삼성라이온즈파크에서 '홈런 자신감'을 되찾은 박병호(38·삼성 라이온즈)가 또 하나의 타자친화구장 인천 SSG랜더스필드에서도 홈런 감각을 이어갈 수 있을까.

삼성은 4일부터 6일까지 인천 SSG랜더스필드에서 SSG 랜더스와 2024 신한은행 SOL 뱅크 KBO리그 원정 3연전을 치른다. 삼성은 지난 주중 3연전에서 키움 히어로즈에 1승 2패 열세 시리즈(3연전 중 2패 이상)를 기록했으나, 주말 한화 이글스와의 3연전을 싹쓸이하며 4연승을 달리고 있다.



단연 박병호의 방망이에 눈길이 간다. 지난 28일 밤 KT 위즈와 일대일 트레이드를 통해 팀을 옮긴 박병호는 이적 후 5경기에서 타율 0.389(18타수 7안타)에 3홈런을 쏘아 올리며 8타점 4득점을 쓸어 담았다. 이적 전 44경기(선발 23경기)에서 타율 0.198(101타수 20안타) 3홈런 10타점 장타율 0.307로 부진한 모습과는 딴판이다. 타자친화구장 라팍에서 부활에 성공했다.

박병호는 이번엔 원정에서 물오른 타격감을 이어가고자 한다. 이번 무대 역시 박병호에게 좋은 기억이 있는 인천이다. 박병호는 인천에서 통산 26개의 홈런을 쏘아 올렸다. 이는 원정 선수(인천 기준) 역대 3위에 해당하는 기록이다. 이범호 현 KIA 타이거즈 감독이 33개(132경기), KIA 외야수 최형우가 30개(132경기)를 쏘아 올린 가운데, 박병호와 강민호(삼성)가 이들의 뒤를 쫓고 있다.

실행결과

====== retriever result ========
[문서 0] 박병호는 이번엔 원정에서 물오른 타격감을 이어가고자 한다. 이번 무대 역시 박병호에게 좋은 기억이 있는 인천이다. 박병호는 인천에서 통산 26개의 홈런을 쏘아 올렸다. 이는 원정 선수(인천 기준) 역대 3위에 해당하는 기록이다. 이범호 현 KIA 타이거즈 감독이 33개(132경기), KIA 외야수 최형우가 30개(132경기)를 쏘아 올린 가운데, 박병호와 강민호(삼성)가 이들의 뒤를 쫓고 있다.
[문서 1] 이적 후 5경기 홈런 세 방. 타자친화구장인 대구 삼성라이온즈파크에서 '홈런 자신감'을 되찾은 박병호(38·삼성 라이온즈)가 또 하나의 타자친화구장 인천 SSG랜더스필드에서도 홈런 감각을 이어갈 수 있을까.
[문서 2] 단연 박병호의 방망이에 눈길이 간다. 지난 28일 밤 KT 위즈와 일대일 트레이드를 통해 팀을 옮긴 박병호는 이적 후 5경기에서 타율 0.389(18타수 7안타)에 3홈런을 쏘아 올리며 8타점 4득점을 쓸어 담았다. 이적 전 44경기(선발 23경기)에서 타율 0.198(101타수 20안타) 3홈런 10타점 장타율 0.307로 부진한 모습과는 딴판이다. 타자친화구장 라팍에서 부활에 성공했다.
[문서 3] 삼성은 4일부터 6일까지 인천 SSG랜더스필드에서 SSG 랜더스와 2024 신한은행 SOL 뱅크 KBO리그 원정 3연전을 치른다. 삼성은 지난 주중 3연전에서 키움 히어로즈에 1승 2패 열세 시리즈(3연전 중 2패 이상)를 기록했으나, 주말 한화 이글스와의 3연전을 싹쓸이하며 4연승을 달리고 있다.

검색어를 기준으로 유사한 문서가 검색이 되는 것을 확인할 수 있다. similarity_search_with_score와 retriever.invoke의 검색 결과가 동일한 것을 확인할 수 있다.

유사도 조회

유사도 점수를 조회하려면 아래와 같이 similarity_search_with_score를 사용해서 조회할 수 있다.

docs = vector_store.similarity_search_with_score(question)
print("====== similarity_search_with_score result ========")
for i, doc in enumerate(docs):
    print(f"[문서 {i}][{doc[1]}] {doc[0].page_content.replace('\n', ' ')}")

출력결과

====== similarity_search_with_score result ========
[문서 0][0.22894422453875166] 박병호는 이번엔 원정에서 물오른 타격감을 이어가고자 한다. 이번 무대 역시 박병호에게 좋은 기억이 있는 인천이다. 박병호는 인천에서 통산 26개의 홈런을 쏘아 올렸다. 이는 원정 선수(인천 기준) 역대 3위에 해당하는 기록이다. 이범호 현 KIA 타이거즈 감독이 33개(132경기), KIA 외야수 최형우가 30개(132경기)를 쏘아 올린 가운데, 박병호와 강민호(삼성)가 이들의 뒤를 쫓고 있다.
[문서 1][0.24920888221947562] 이적 후 5경기 홈런 세 방. 타자친화구장인 대구 삼성라이온즈파크에서 '홈런 자신감'을 되찾은 박병호(38·삼성 라이온즈)가 또 하나의 타자친화구장 인천 SSG랜더스필드에서도 홈런 감각을 이어갈 수 있을까.
[문서 2][0.2783592573897284] 단연 박병호의 방망이에 눈길이 간다. 지난 28일 밤 KT 위즈와 일대일 트레이드를 통해 팀을 옮긴 박병호는 이적 후 5경기에서 타율 0.389(18타수 7안타)에 3홈런을 쏘아 올리며 8타점 4득점을 쓸어 담았다. 이적 전 44경기(선발 23경기)에서 타율 0.198(101타수 20안타) 3홈런 10타점 장타율 0.307로 부진한 모습과는 딴판이다. 타자친화구장 라팍에서 부활에 성공했다.
[문서 3][0.40254847373802766] 삼성은 4일부터 6일까지 인천 SSG랜더스필드에서 SSG 랜더스와 2024 신한은행 SOL 뱅크 KBO리그 원정 3연전을 치른다. 삼성은 지난 주중 3연전에서 키움 히어로즈에 1승 2패 열세 시리즈(3연전 중 2패 이상)를 기록했으나, 주말 한화 이글스와의 3연전을 싹쓸이하며 4연승을 달리고 있다.

여기서 score가 낮을수록 더 유사 내용을 포함한다는 것을 나타낸다.

Maximum marginal relevance retrieval

MMR(Maximal Marginal Relevance) 방식은 쿼리에 대해 관련 항목의 관련성을 최대화하고 검색된 문서의 중복성을 최소화 하는 방법이다.

MMR을 사용하려면 아래와 같이 검색 유형을 지정한다.

retriever = vector_store.as_retriever(search_type="mmr")

Vector store에 대해 기본검색을 하는 경우와 mmr 검색을 하는 경우에 대해 비교를 해보자. 중복 문서를 만들기 위해 위의 코드(main.py)에서 임베딩을 1회 더 수행(add_documents)하고 검색을 해보자.

retriever = vector_store.as_retriever()
docs = retriever.invoke(question)

print("====== retriever result ========")
for i, doc in enumerate(docs):
    print(f"[문서 {i}] {doc.page_content.replace('\n', ' ')}")


retriever = vector_store.as_retriever(search_type="mmr")
docs = retriever.invoke(question)

print("====== retriever mmr result ========")
for i, doc in enumerate(docs):
    print(f"[문서 {i}] {doc.page_content.replace('\n', ' ')}")

실행결과

====== retriever result ========
[문서 0] 박병호는 이번엔 원정에서 물오른 타격감을 이어가고자 한다. 이번 무대 역시 박병호에게 좋은 기억이 있는 인천이다. 박병호는 인천에서 통산 26개의 홈런을 쏘아 올렸다. 이는 원정 선수(인천 기준) 역대 3위에 해당하는 기록이다. 이범호 현 KIA 타이거즈 감독이 33개(132경기), KIA 외야수 최형우가 30개(132경기)를 쏘아 올린 가운데, 박병호와 강민호(삼성)가 이들의 뒤를 쫓고 있다.
[문서 1] 박병호는 이번엔 원정에서 물오른 타격감을 이어가고자 한다. 이번 무대 역시 박병호에게 좋은 기억이 있는 인천이다. 박병호는 인천에서 통산 26개의 홈런을 쏘아 올렸다. 이는 원정 선수(인천 기준) 역대 3위에 해당하는 기록이다. 이범호 현 KIA 타이거즈 감독이 33개(132경기), KIA 외야수 최형우가 30개(132경기)를 쏘아 올린 가운데, 박병호와 강민호(삼성)가 이들의 뒤를 쫓고 있다.
[문서 2] 이적 후 5경기 홈런 세 방. 타자친화구장인 대구 삼성라이온즈파크에서 '홈런 자신감'을 되찾은 박병호(38·삼성 라이온즈)가 또 하나의 타자친화구장 인천 SSG랜더스필드에서도 홈런 감각을 이어갈 수 있을까.
[문서 3] 이적 후 5경기 홈런 세 방. 타자친화구장인 대구 삼성라이온즈파크에서 '홈런 자신감'을 되찾은 박병호(38·삼성 라이온즈)가 또 하나의 타자친화구장 인천 SSG랜더스필드에서도 홈런 감각을 이어갈 수 있을까.
Number of requested results 20 is greater than number of elements in index 8, updating n_results = 8
====== retriever mmr result ========
[문서 0] 박병호는 이번엔 원정에서 물오른 타격감을 이어가고자 한다. 이번 무대 역시 박병호에게 좋은 기억이 있는 인천이다. 박병호는 인천에서 통산 26개의 홈런을 쏘아 올렸다. 이는 원정 선수(인천 기준) 역대 3위에 해당하는 기록이다. 이범호 현 KIA 타이거즈 감독이 33개(132경기), KIA 외야수 최형우가 30개(132경기)를 쏘아 올린 가운데, 박병호와 강민호(삼성)가 이들의 뒤를 쫓고 있다.
[문서 1] 이적 후 5경기 홈런 세 방. 타자친화구장인 대구 삼성라이온즈파크에서 '홈런 자신감'을 되찾은 박병호(38·삼성 라이온즈)가 또 하나의 타자친화구장 인천 SSG랜더스필드에서도 홈런 감각을 이어갈 수 있을까.
[문서 2] 단연 박병호의 방망이에 눈길이 간다. 지난 28일 밤 KT 위즈와 일대일 트레이드를 통해 팀을 옮긴 박병호는 이적 후 5경기에서 타율 0.389(18타수 7안타)에 3홈런을 쏘아 올리며 8타점 4득점을 쓸어 담았다. 이적 전 44경기(선발 23경기)에서 타율 0.198(101타수 20안타) 3홈런 10타점 장타율 0.307로 부진한 모습과는 딴판이다. 타자친화구장 라팍에서 부활에 성공했다.
[문서 3] 삼성은 4일부터 6일까지 인천 SSG랜더스필드에서 SSG 랜더스와 2024 신한은행 SOL 뱅크 KBO리그 원정 3연전을 치른다. 삼성은 지난 주중 3연전에서 키움 히어로즈에 1승 2패 열세 시리즈(3연전 중 2패 이상)를 기록했으나, 주말 한화 이글스와의 3연전을 싹쓸이하며 4연승을 달리고 있다.

기본 vector store 검색에서는 중복된 결과가 문서에 표시되는 것을 알 수 있지만 mmr 검색에서는 중복을 제외하고 검색되는 것을 알 수 있다.

Similarity score threshold retrieval

유사도 점수가 일정값 이상인 문서만 검색되게 할 수 있다. 기본적으로 유사도가 높은 순으로 4개의 문서가 검색이 되지만 특정 유사도 이상만 검색이 되게 하는 방법이다.

retriever = vector_store.as_retriever(
    search_type="similarity_score_threshold",
    search_kwargs={"score_threshold": 0.8},
)

위와 같이 하면 검색 결과의 유사도 점수가 0.8 이상인 것만 검색이 된다.

Specifying top k

검색하려는 문서수를 제한하려고 할 때 k 인수를 사용할 수 있다.

retriever = vector_store.as_retriever(search_kwargs={"k": 1})

위와 같이 하면 검색 문서수를 1개로 제한한다.

참고

반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유