basic semantic similarity
Maximum Marginal Relevance(MMR)
MMR은 검색 결과의 다양성을 강화하는 방법 , 의미적 유사도를 기반으로 한 임베딩 공간에서는 가장 유사한 문서를 얻는 반면 이 과정에서 다양한 정보를 놓칠 수 있다.
아이디어
including Metadata
메타데이터를 이용해 특정 범위의 문서에서만 원하는 검색 결과를 도출하는 방법
question = "what did they say about regression in the third lecture?"
docs = vectordb.similarity_search(
question,
k=3,
filter={"source":"docs/cs229_lectures/MachineLearning-Lecture03.pdf"}
)
for d in docs:
print(d.metadata)
Self Query를 이용하는 방법으로 쿼리 그 자체로 부터 메타데이터를 추론하고 싶을 때 사용된다.
SelfQueryRetriever를 이용하면되고, LLM을 이용하는 방법이다. 해당 방법으로 추출하는 것은 다음과 같다.
이 방식은 검색 과정을 간소화하고, 자동화하여 사용자가 직접 필터를 설정할 필요없이 관련성 높은 결과를 얻을 수 있도록 돕는다.
from langchain.llms import OpenAI
from langchain.retrievers.self_query.base import SelfQueryRetriever
from langchain.chains.query_constructor.base import AttributeInfo
metadata_field_info = [
AttributeInfo(
name="source",
description="The lecture the chunk is from, should be one of `docs/cs229_lectures/MachineLearning-Lecture01.pdf`, `docs/cs229_lectures/MachineLearning-Lecture02.pdf`, or `docs/cs229_lectures/MachineLearning-Lecture03.pdf`",
type="string",
),
AttributeInfo(
name="page",
description="The page from the lecture",
type="integer",
),
]
document_content_description = "Lecture notes"
llm = OpenAI(temperature=0)
retriever = SelfQueryRetriever.from_llm(
llm,
vectordb,
document_content_description,
metadata_field_info,
verbose=True
)
question = "what did they say about regression in the third lecture?"
docs = retriever.get_relevant_documents(question)
문서 압축이라고 부를 수 있다. 전체 문서를 애플리케이션을 통해 LLM으로 전달하는 것은 많은 비용을 수반한다. 또한 응답의 질 역시 떨어질 수 있다. 그래서 검색된 문단에서 가장 관련성 높은 부분만 추출하는 방법이다. 해당 접근 방식의 이점은 다음과 같다.
from langchain.retrievers import ContextualCompressionRetriever
from langchain.retrievers.document_compressors import LLMChainExtractor
def pretty_print_docs(docs):
print(f"\n{'-' * 100}\n".join([f"Document {i+1}:\n\n" + d.page_content for i, d in enumerate(docs)]))
llm = OpenAI(temperature=0)
compressor = LLMChainExtractor.from_llm(llm)
compression_retriever = ContextualCompressionRetriever(
base_compressor=compressor,
base_retriever=vectordb.as_retriever()
)
question = "어떤 과목이 통계와 관련이 있어?"
compressed_docs = compression_retriever.get_relevant_documents(question)
pretty_print_docs(compressed_docs)
Document 1:
BIZ500 경영통계분석 (Management Statistical Analysis)
나의 경우에는 다음과 같은 결과가 나오고, 위의 예시 코드의 파이프라인은 일반적으로 다음과 같다.

from langchain.chat_models import ChatOpenAI
from langchain.chains import RetrievalQA
llm = ChatOpenAI(temperature=0)
qa_chain = RetrievalQA.from_chain_type(
llm,
retriever=vectordb.as_retriever()
)
# Pass question to the qa_chain
question = "어떤 과목이 통계랑 관련이 있나요?"
result = qa_chain({"query": question})
result["result"]
해당 Chain의 가장 큰 한계는 대화 이력을 보존하는 것에 실패하는 것이다.
이를 해결하기 위해서는 메모리 개념을 도입해야 한다. 챗봇을 만드는 경우 이전 질문이나 답변을 기억하는 능력이 필요하다.
또한 의미론적 검색은 특정한 케이스에서 실패할 수 있다. 이를 극복하기 위해 다양한 검색 알고리즘을 논의했으며, 질문에 대한 답변을 생성하기 위해 검색된 문서와 사용자 질문을 LLM에 전달하는 질문 답변 시스템을 탐구했다.
출처 https://medium.com/@onkarmishra/using-langchain-for-question-answering-on-own-data-3af0a82789ed