4️⃣RAG Paradigms

RAG의 패러다임을 아래처럼 변하고 있씁니다. 가장 기본적인 Naive RAG에서 Advanced RAG로 전환하여 현재 많은 방법론이 쏟아지고 있으며, 모든 방법을 통합하여 모듈 방식으로 실행하는 Modular RAG가 대두되고 있습니다.

RAG Paradigms

  1. Naive RAG

  2. Advanced RAG

  3. Modular RAG

1. Naive RAG

Naive RAG 파이프라인은 아래의 주요 단계로 구성됩니다:

Data Indexing

  1. 데이터 로드: 여기에는 활용할 모든 문서 또는 정보를 가져오는 작업이 포함됩니다.

  2. 데이터 분할: 큰 문서를 각각 500자 이하의 섹션과 같이 작은 조각으로 나누는 작업입니다.

  3. 데이터 임베딩: 임베딩 모델을 사용하여 데이터를 벡터 형식으로 변환하여 컴퓨터가 이해할 수 있도록 합니다.

  4. 데이터 저장: 이러한 벡터 임베딩은 벡터 데이터베이스에 저장되어 쉽게 검색할 수 있습니다.

Retrieval

사용자가 질문할 때

  1. 사용자의 입력은 먼저 데이터 인덱싱 단계와 동일한 임베딩 모델을 사용해 벡터(쿼리 벡터)로 변환됩니다.

  2. 그런 다음 이 쿼리 벡터를 벡터 데이터베이스의 모든 벡터와 대조하여 사용자의 질문에 대한 답을 포함할 수 있는 가장 유사한 벡터를 찾습니다(예: 유클리드 거리 메트릭 사용). 이 단계는 관련 지식 덩어리를 식별하는 단계입니다.

증강 및 생성

LLM 모델은 사용자의 질문과 벡터 데이터베이스에서 검색된 관련 정보를 가져와 답변을 생성합니다. 이 프로세스는 질문을 식별된 데이터와 결합하여(증강) 답변을 생성합니다(생성).

Problems with Naive RAG

Naive RAG faces challenges across all phases:

  • Retrieval — 모든 관련 청크를 검색하지 못하거나 관련 없는 청크를 검색하는 경우.

  • Augmentation — 단절되어 있거나 반복적인 정보를 포함하고 있을 수 있는 검색된 청크의 컨텍스트를 통합하는 데 어려움을 겪고 있습니다.

  • Generation — LLM은 제공된 컨텍스트(검색된 청크)에 근거하지 않은 답변을 생성하거나 검색된 관련 없는 컨텍스트를 기반으로 답변을 생성할 가능성이 있습니다.


LangChain: Naive RAG

# import libraries  
import os  
from langchain_community.document_loaders import PyPDFLoader  
from langchain.text_splitter import RecursiveCharacterTextSplitter  
from langchain.embeddings.openai import OpenAIEmbeddings  
from langchain.vectorstores import Chroma  
from langchain.prompts import ChatPromptTemplate  
from langchain.chat_models import ChatOpenAI  


OPENAI_API_KEY = os.getenv('OPENAI_API_KEY') # add your OpenAI API Key  
# for this example I used Alphabet Inc 10-K Report 2022  
# https://www.sec.gov/Archives/edgar/data/1652044/000165204423000016/goog-20221231.htm  
DOC_PATH = "../alphabet_10K_2022.pdf"  
CHROMA_PATH = "your_db_name"  



# ----- Data Indexing Process -----  
  
# load your pdf doc  
loader = PyPDFLoader(DOC_PATH)  
pages = loader.load()  
  
# split the doc into smaller chunks i.e. chunk_size=500  
text_splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)  
chunks = text_splitter.split_documents(pages)  
  
# get OpenAI Embedding model  
embeddings = OpenAIEmbeddings(openai_api_key=OPENAI_API_KEY)  
  
# embed the chunks as vectors and load them into the database  
db_chroma = Chroma.from_documents(chunks, embeddings, persist_directory=CHROMA_PATH)  



# ----- Retrieval and Generation Process -----  
  
# this is an example of a user question (query)  
query = 'what are the top risks mentioned in the document?'  
  
# retrieve context - top 5 most relevant (closests) chunks to the query vector  
# (by default Langchain is using cosine distance metric)  
docs_chroma = db_chroma.similarity_search_with_score(query, k=5)  
  
# generate an answer based on given user query and retrieved context information  
context_text = "\n\n".join([doc.page_content for doc, _score in docs_chroma])  
  
# you can use a prompt template  
PROMPT_TEMPLATE = """  
Answer the question based only on the following context:  
{context}  
Answer the question based on the above context: {question}.  
Provide a detailed answer.  
Don’t justify your answers.  
Don’t give information not mentioned in the CONTEXT INFORMATION.  
Do not say "according to the context" or "mentioned in the context" or similar.  
"""  
  
# load retrieved context and user query in the prompt template  
prompt_template = ChatPromptTemplate.from_template(PROMPT_TEMPLATE)  
prompt = prompt_template.format(context=context_text, question=query)  
  
# call LLM model to generate the answer based on the given context and query  
model = ChatOpenAI()  
response_text = model.predict(prompt)
Generated response:  
  
The top risks mentioned in the provided context are:  
1. Decline in the value of investments  
2. Lack of adoption of products and services  
3. Interference or interruption from various factors such as modifications, terrorist attacks, natural disasters, etc.  
4. Compromised trade secrets and legal and financial risks  
5. Reputational, financial, and regulatory exposure  
6. Abuse of platforms and misuse of user data  
7. Errors or vulnerabilities leading to service interruptions or failure  
8. Risks associated with international operations.  


Advanced RAG

Naive RAG가 직면한 문제를 해결하기 위해 고급 래그 전략이 개발되었습니다. 다음은 주요 고급 RAG 기술에 대한 개요입니다.

RAG 애플리케이션은 데이터 소스에서 관련 문서를 효율적으로 검색해야 합니다. 하지만 각 단계에는 여러 가지 과제가 있습니다.

  1. 문서와 쿼리의 정확한 의미론적 표현을 얻으려면 어떻게 해야 할까요?

  2. 쿼리와 문서(청크)의 의미론적 공간을 정렬할 수 있는 방법은 무엇인가요?

  3. Retriever의 출력을 LLM의 기본 설정과 어떻게 일치시킬 수 있나요?

여기에서는 검색 전, 검색 후 및 검색 후 전략에 대한 개요를 설명합니다:

Pre-Retrieval

데이터 인덱싱을 최적화하는 방법은 무엇인가요?

  • Improve Data Quality - 관련 없는 정보를 제거하고, 엔티티와 용어의 모호성을 제거하며, 사실의 정확성을 확인하고, 문맥을 유지하고, 오래된 정보를 업데이트합니다.

  • Optimize Index Structure - 청크 크기를 최적화하여 관련 맥락을 포착하거나 그래프 구조에서 정보를 추가하여 개체 간의 관계를 포착합니다.

  • Add Metadata - 날짜, 챕터, 하위 섹션, 목적 또는 기타 관련 정보를 청크에 메타데이터로 추가하여 데이터 필터링을 개선합니다.

  • Chunk Optimization- 외부 데이터 소스/문서를 사용해 RAG 파이프라인을 구축할 때, 초기 단계는 세분화된 특징을 추출하기 위해 이를 더 작은 청크로 분해하는 것입니다. 그런 다음 청크의 의미를 나타내기 위해 청크를 임베드합니다. 그러나 너무 크거나 작은 텍스트 청크를 임베드하면 최적의 결과가 나오지 않을 수 있으므로 RAG 파이프라인에서 사용하는 문서 유형에 맞게 청크 크기를 최적화해야 합니다.

Pre-Retrieval Techniques 요약:

  1. Sliding Window - 청크 간 중첩을 사용하는 청킹 방식입니다.

  2. Auto-Merging Retrieval- 초기 검색 단계에서 작은 텍스트 블록을 활용하고 이후 처리를 위해 언어 모델에 더 큰 관련 텍스트 블록을 제공합니다.

  3. Abstract Embedding - 문서 초록(또는 요약)을 기반으로 Top-K 검색의 우선순위를 지정하여 전체 문서 컨텍스트를 포괄적으로 파악할 수 있습니다.

  4. Metadata Filtering - 문서 메타데이터를 활용하여 필터링 프로세스를 개선합니다.

  5. Graph Indexing - 엔티티와 관계를 노드와 연결로 변환하여 관련성을 크게 개선합니다.

Retrieval

청크의 크기가 결정되면 다음 단계는 임베딩 모델을 사용하여 이러한 청크를 시맨틱 공간에 임베딩하는 것입니다.

검색 단계에서는 쿼리와 가장 관련성이 높은 청크를 식별하는 것이 목표입니다. 이는 쿼리와 청크 간의 유사성을 계산하여 수행됩니다. 여기에서 쿼리와 청크를 모두 임베드하는 데 사용되는 임베딩 모델을 최적화할 수 있습니다.

Domain Knowledge Fine-Tuning - 임베딩 모델이 RAG 시스템의 도메인별 정보를 정확하게 캡처하도록 하려면 미세 조정을 위해 도메인별 데이터 세트를 사용하는 것이 중요합니다. 임베딩 모델 미세 조정을 위한 데이터 세트에는 쿼리, 말뭉치 및 관련 문서가 포함되어야 합니다.

Similarity Metrics - 벡터 간의 유사성을 측정하는 여러 가지 메트릭이 있습니다. 유사도 메트릭의 선택은 최적화 문제이기도 합니다. 벡터 데이터베이스(ChromaDB, Pinecode, Weaviate...)는 여러 유사성 지표를 지원합니다. 다음은 다양한 유사도 메트릭의 몇 가지 예입니다:

  • Cosine Similarity

  • Euclidean Distance (L2)

  • Dot Product

  • L2 Squared Distance

  • Manhattan Distance

Post-Retrieval

벡터 데이터베이스에서 컨텍스트 데이터(청크)를 검색한 후, 다음 단계는 컨텍스트를 쿼리와 함께 LLM에 입력으로 병합하는 것입니다. 그러나 검색된 청크 중 일부는 반복되거나 노이즈가 있거나 관련 없는 정보를 포함할 수 있습니다. 이는 LLM이 주어진 컨텍스트를 처리하는 방식에 영향을 미칠 수 있습니다.

아래에는 이러한 문제를 극복하는 데 사용되는 몇 가지 전략이 나와 있습니다.

Reranking- 검색된 정보의 순위를 재조정하여 가장 관련성이 높은 콘텐츠의 우선순위를 먼저 정합니다. LLM은 추가 컨텍스트가 도입되면 성능이 저하되는 경우가 많은데, 재랭크는 검색된 청크의 순위를 다시 매기고 가장 관련성이 높은 상위 K 청크를 식별하여 LLM에서 컨텍스트로 사용함으로써 이 문제를 해결합니다. LlamaIndex, Langchain, HayStack과 같은 라이브러리는 다양한 리랭커를 제공합니다.

Prompt Compression - 검색된 정보가 노이즈가 많을 수 있으므로 관련 없는 문맥을 압축하고 문맥 길이를 줄인 후 LLM에 제시하는 것이 중요합니다. 작은 언어 모델을 사용하여 프롬프트 상호 정보 또는 난해성을 계산하여 요소의 중요성을 추정하세요. 문맥이 긴 경우에는 요약 기법을 사용하세요.


LangChain: Advanced RAG Techniques

Reference: https://python.langchain.com/docs/modules/data_connection/retrievers/

  1. ParentDocumentRetriever

  2. . MultiQueryRetriever

  3. ContextualCompressionRetriever

  4. Ensemble Retriever

  5. Self-Querying retriever

  6. TimeWeightedVectorStoreRetriever

  7. Vector store-backed retriever

  8. WebResearchRetriever

import os
from langchain.embeddings.openai import OpenAIEmbeddings

env_vars = {
    "OPENAI_API_KEY": "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",
}

def pretty_print_docs(docs):
    print(f"\n{'-' * 100}\n".join([f"Document {i+1}:\n" + d.page_content for i, d in enumerate(docs)]))

for key, value in env_vars.items():
    os.environ[key] = value

embedding = OpenAIEmbeddings(chunk_size=1 )

0. Introduction: Vector Similarity

from langchain.text_splitter import RecursiveCharacterTextSplitter
from langchain.vectorstores import Chroma
from langchain.schema import Document

# Load blog post
from langchain.document_loaders import TextLoader

loader = TextLoader("./dogs.txt")
data = loader.load()
loader = TextLoader("./restaurant.txt")
data2 = loader.load()

docs = data + data2

#text_splitter = RecursiveCharacterTextSplitter(chunk_size=120, chunk_overlap=10)
#docs = text_splitter.split_documents(data)
vector1 = embedding.embed_query("How is the whether??")
vector2 = embedding.embed_query("What is the Name of the Dogschool?")
vector3 = embedding.embed_query("What food do you offer?")

data_vectors = [embedding.embed_query(doc.page_content) for doc in docs]
print(len(data_vectors))
2
from sklearn.metrics.pairwise import cosine_similarity
import matplotlib.pyplot as plt
import numpy as np

cosine_sims_1 = [cosine_similarity([vector1], [data_vector])[0][0] for data_vector in data_vectors]
cosine_sims_2 = [cosine_similarity([vector2], [data_vector])[0][0] for data_vector in data_vectors]
cosine_sims_3 = [cosine_similarity([vector3], [data_vector])[0][0] for data_vector in data_vectors]

x = np.arange(len(data_vectors))

plt.scatter(x, cosine_sims_1, label='Weather', alpha=0.7)
plt.scatter(x, cosine_sims_2, label='Dogschool', alpha=0.7)
plt.scatter(x, cosine_sims_3, label='Restaurant', alpha=0.7)

plt.ylabel('Cosine Similarity')
plt.title('Consine Similarity between query and data vectors')
plt.legend()

plt.show()

![[스크린샷 2023-12-20 오후 6.03.15.png]]


1. ParentDocumentRetriever

  1. 문서 분할의 이중 목적:

    • 작은 문서를 원하는 이유: 임베딩이 의미를 정확하게 반영하기 위함.

    • 충분히 긴 문서를 원하는 이유: 각 청크의 맥락을 유지하기 위함.

  2. ParentDocumentRetriever의 기능:

    • 작은 데이터 청크로 분할하고 저장.

    • 검색 시 작은 청크를 먼저 가져오고, 이들의 상위 문서를 반환.

  3. 상위 문서에 대한 정의:

    • 작은 청크가 유래한 문서를 의미.

    • 전체 원본 문서 또는 더 큰 청크일 수 있음.

  4. 검색 전략:

    • 전체 문서가 너무 클 경우, 원본을 먼저 큰 청크로, 그 다음 작은 청크로 분할.

    • 작은 청크 색인화, 검색 시 더 큰 청크를 검색.

from langchain.storage import InMemoryStore
from langchain.retrievers import ParentDocumentRetriever

child_splitter = RecursiveCharacterTextSplitter(chunk_size=120, chunk_overlap=20)
parent_splitter = RecursiveCharacterTextSplitter(chunk_size=400, chunk_overlap=20)
vectorstore = Chroma(
    collection_name="full_documents", embedding_function=embedding
)
store = InMemoryStore()
retriever = ParentDocumentRetriever(
    vectorstore=vectorstore,
    docstore=store,
    child_splitter=child_splitter,
    parent_splitter=parent_splitter
)
retriever.add_documents(docs, ids=None)
vectorstore.similarity_search("What is the name of the dog school?")
[Document(page_content='A1: The school is called "Canine Academy".', metadata={'doc_id': 'cff9ed71-e8d7-4232-b218-664c0b65a5cd', 'source': './dogs.txt'}),
 Document(page_content='Fiktive Hundeschule: Canine Academy\nQ1: What is the name of the dog training school?', metadata={'doc_id': 'cff9ed71-e8d7-4232-b218-664c0b65a5cd', 'source': './dogs.txt'}),
 Document(page_content='Q3: What training programs are offered at Canine Academy?', metadata={'doc_id': 'cff9ed71-e8d7-4232-b218-664c0b65a5cd', 'source': './dogs.txt'}),
 Document(page_content='Q7: Does Canine Academy provide training for service or therapy dogs?', metadata={'doc_id': '71a8ab3d-366c-4337-a742-578f02a0c5df', 'source': './dogs.txt'})]
retriever.get_relevant_documents("What is the name of the dog school?")
[Document(page_content='Fiktive Hundeschule: Canine Academy\nQ1: What is the name of the dog training school?\nA1: The school is called "Canine Academy".\n\nQ2: Where is Canine Academy located?\nA2: Canine Academy is located in the suburbs, near the community park.\n\nQ3: What training programs are offered at Canine Academy?\nA3: They offer basic obedience, agility training, and advanced behavioral courses.', metadata={'source': './dogs.txt'}),
 Document(page_content='Q6: How long do the training courses last?\nA6: The courses vary, ranging from 4-week short courses to 12-week intensive programs.\n\nQ7: Does Canine Academy provide training for service or therapy dogs?\nA7: Yes, they have specialized programs for service and therapy dog training.', metadata={'source': './dogs.txt'})]

2. MultiQueryRetriever

물론이죠. 해당 내용을 리스트 형식으로 요약하면 다음과 같습니다:

  1. 거리 기반 검색의 한계:

    • 고차원 공간에 임베드된 쿼리를 사용하여 유사 문서 검색.

    • 쿼리의 미묘한 변화나 임베딩의 부정확성으로 인해 결과가 변동될 수 있음.

  2. 멀티쿼리 리트리버의 접근 방식:

    • LLM을 활용하여 다양한 관점의 여러 쿼리를 생성.

    • 자동화된 프롬프트 튜닝 과정을 통해 문제 해결.

  3. 검색 과정과 결과:

    • 각각의 쿼리에 대해 관련 문서 집합 검색.

    • 모든 쿼리의 결과를 통합하여 더 크고 관련성 높은 문서 집합 제공.

  4. 기대되는 이점:

    • 거리 기반 검색의 한계를 극복.

    • 다양한 관점을 통해 더 풍부한 결과 세트 얻음.

from langchain.chat_models import ChatOpenAI
from langchain.retrievers.multi_query import MultiQueryRetriever

llm = ChatOpenAI(
        temperature=0,
        max_tokens=800,
        model_kwargs={"top_p": 0, "frequency_penalty": 0, "presence_penalty": 0},
    )


retriever = MultiQueryRetriever.from_llm(
    retriever=vectorstore.as_retriever(), llm=llm
)
unique_docs = retriever.get_relevant_documents("What is the name of the dog school?")
len(unique_docs)
4
from typing import List

from langchain.chains import LLMChain
from langchain.output_parsers import PydanticOutputParser
from langchain.prompts import PromptTemplate
from pydantic import BaseModel, Field


class LineList(BaseModel):
    lines: List[str] = Field(description="Lines of text")


class LineListOutputParser(PydanticOutputParser):
    def __init__(self) -> None:
        super().__init__(pydantic_object=LineList)

    def parse(self, text: str) -> LineList:
        lines = text.strip().split("\n")
        return LineList(lines=lines)


output_parser = LineListOutputParser()

QUERY_PROMPT = PromptTemplate(
    input_variables=["question"],
    template="""You are an AI language model assistant. Your task is to generate five
    different versions of the given user question to retrieve relevant documents from a vector
    database. By generating multiple perspectives on the user question, your goal is to help
    the user overcome some of the limitations of the distance-based similarity search.
    Provide these alternative questions separated by newlines.
    Original question: {question}""",
)

llm_chain = LLMChain(llm=llm, prompt=QUERY_PROMPT, output_parser=output_parser)
llm_chain.invoke("What is the name of the dog school?")
{'question': 'What is the name of the dog school?',
 'text': LineList(lines=['1. Can you tell me the name of the dog training center?', '2. What is the official name of the dog school?', '3. Do you know the specific name of the dog school?', '4. Could you provide me with the name of the canine education institution?', "5. I'm looking for the name of the dog school, can you assist me with that?"])}
question = "What is the name of the dog school?"

3. ContextualCompressionRetriever

  1. 검색 시스템의 문제:

    • 데이터 수집 시 특정 쿼리를 예측할 수 없음.

    • 관련성 높은 정보가 관련 없는 텍스트가 많은 문서에 묻힐 수 있음.

    • 전체 문서를 전달하면 비용이 많이 드는 LLM 호출과 응답 품질 저하가 발생할 수 있음.

  2. 컨텍스트 압축의 목적:

    • 검색된 문서를 그대로 반환하는 대신 압축하여 관련 정보만 반환.

    • '압축'은 개별 문서 내용 압축 및 문서 일괄 필터링을 포함.

  3. 컨텍스트 압축 리트리버의 구성 요소:

    • 기본 리트리버: 쿼리를 처리함.

    • 문서 압축기: 문서 내용을 줄이거나 문서를 삭제하여 압축.

  4. 작동 방식:

    • 쿼리를 기본 리트리버로 전달.

    • 초기 문서를 가져와 문서 압축기를 통과시킴.

    • 문서 압축기는 문서 목록을 처리하여 내용을 압축하거나 삭제.

vectorstore = Chroma(
    collection_name="full_documents", embedding_function=embedding
)
vectorstore.add_documents(docs)
retriever = vectorstore.as_retriever()
retriever.get_relevant_documents(query=question)
[Document(page_content='A1: The school is called "Canine Academy".', metadata={'doc_id': 'cff9ed71-e8d7-4232-b218-664c0b65a5cd', 'source': './dogs.txt'}),
 Document(page_content='Fiktive Hundeschule: Canine Academy\nQ1: What is the name of the dog training school?', metadata={'doc_id': 'cff9ed71-e8d7-4232-b218-664c0b65a5cd', 'source': './dogs.txt'}),
 Document(page_content='Fiktive Hundeschule: Canine Academy\nQ1: What is the name of the dog training school?\nA1: The school is called "Canine Academy".\n\nQ2: Where is Canine Academy located?\nA2: Canine Academy is located in the suburbs, near the community park.\n\nQ3: What training programs are offered at Canine Academy?\nA3: They offer basic obedience, agility training, and advanced behavioral courses.\n\nQ4: Are there any special qualifications for the trainers at Canine Academy?\nA4: All trainers are certified and have years of experience in dog training and behavior.\n\nQ5: Can Canine Academy help with specific behavioral issues?\nA5: Yes, they offer personalized training sessions for issues like aggression, anxiety, and barking.\n\nQ6: How long do the training courses last?\nA6: The courses vary, ranging from 4-week short courses to 12-week intensive programs.\n\nQ7: Does Canine Academy provide training for service or therapy dogs?\nA7: Yes, they have specialized programs for service and therapy dog training.\n\nQ8: Is there a trial class or evaluation session available?\nA8: Yes, they offer a free evaluation session to assess the dog\'s needs and training level.\n\nQ9: What are the fees for the training courses at Canine Academy?\nA9: Fees vary based on the course, but they offer competitive rates and package deals.\n\nQ10: Does Canine Academy offer any support or follow-up after completion of a course?\nA10: Yes, they provide follow-up consultations and support for continued training and development.', metadata={'source': './dogs.txt'}),
 Document(page_content='Q3: What training programs are offered at Canine Academy?', metadata={'doc_id': 'cff9ed71-e8d7-4232-b218-664c0b65a5cd', 'source': './dogs.txt'})]
from langchain.retrievers import ContextualCompressionRetriever
from langchain.retrievers.document_compressors import LLMChainExtractor

compressor = LLMChainExtractor.from_llm(llm)
compression_retriever = ContextualCompressionRetriever(base_compressor=compressor, base_retriever=retriever)

compressed_docs = compression_retriever.get_relevant_documents(query=question)
pretty_print_docs(compressed_docs)
/home/kubwa/anaconda3/envs/langchain/lib/python3.9/site-packages/langchain/chains/llm.py:321: UserWarning: The predict_and_parse method is deprecated, instead pass an output parser directly to LLMChain.
  warnings.warn(
/home/kubwa/anaconda3/envs/langchain/lib/python3.9/site-packages/langchain/chains/llm.py:321: UserWarning: The predict_and_parse method is deprecated, instead pass an output parser directly to LLMChain.
  warnings.warn(
/home/kubwa/anaconda3/envs/langchain/lib/python3.9/site-packages/langchain/chains/llm.py:321: UserWarning: The predict_and_parse method is deprecated, instead pass an output parser directly to LLMChain.
  warnings.warn(
/home/kubwa/anaconda3/envs/langchain/lib/python3.9/site-packages/langchain/chains/llm.py:321: UserWarning: The predict_and_parse method is deprecated, instead pass an output parser directly to LLMChain.
  warnings.warn(


Document 1:
The school is called "Canine Academy".
----------------------------------------------------------------------------------------------------
Document 2:
Fiktive Hundeschule: Canine Academy
----------------------------------------------------------------------------------------------------
Document 3:
The school is called "Canine Academy".
----------------------------------------------------------------------------------------------------
Document 4:
Canine Academy
from langchain.embeddings import OpenAIEmbeddings
from langchain.retrievers.document_compressors import EmbeddingsFilter

embeddings_filter = EmbeddingsFilter(embeddings=embedding, similarity_threshold=0.5)
compression_retriever = ContextualCompressionRetriever(base_compressor=embeddings_filter, base_retriever=retriever)

compressed_docs = compression_retriever.get_relevant_documents(query=question)
pretty_print_docs(compressed_docs)
Document 1:
A1: The school is called "Canine Academy".
----------------------------------------------------------------------------------------------------
Document 2:
Fiktive Hundeschule: Canine Academy
Q1: What is the name of the dog training school?
----------------------------------------------------------------------------------------------------
Document 3:
Fiktive Hundeschule: Canine Academy
Q1: What is the name of the dog training school?
A1: The school is called "Canine Academy".

Q2: Where is Canine Academy located?
A2: Canine Academy is located in the suburbs, near the community park.

Q3: What training programs are offered at Canine Academy?
A3: They offer basic obedience, agility training, and advanced behavioral courses.

Q4: Are there any special qualifications for the trainers at Canine Academy?
A4: All trainers are certified and have years of experience in dog training and behavior.

Q5: Can Canine Academy help with specific behavioral issues?
A5: Yes, they offer personalized training sessions for issues like aggression, anxiety, and barking.

Q6: How long do the training courses last?
A6: The courses vary, ranging from 4-week short courses to 12-week intensive programs.

Q7: Does Canine Academy provide training for service or therapy dogs?
A7: Yes, they have specialized programs for service and therapy dog training.

Q8: Is there a trial class or evaluation session available?
A8: Yes, they offer a free evaluation session to assess the dog's needs and training level.

Q9: What are the fees for the training courses at Canine Academy?
A9: Fees vary based on the course, but they offer competitive rates and package deals.

Q10: Does Canine Academy offer any support or follow-up after completion of a course?
A10: Yes, they provide follow-up consultations and support for continued training and development.
----------------------------------------------------------------------------------------------------
Document 4:
Q3: What training programs are offered at Canine Academy?
from langchain.document_transformers import EmbeddingsRedundantFilter
from langchain.retrievers.document_compressors import DocumentCompressorPipeline
from langchain.text_splitter import CharacterTextSplitter

splitter = CharacterTextSplitter(chunk_size=300, chunk_overlap=0, separator=". ")
redundant_filter = EmbeddingsRedundantFilter(embeddings=embedding)
relevant_filter = EmbeddingsFilter(embeddings=embedding, similarity_threshold=0.76)
pipeline_compressor = DocumentCompressorPipeline(
    transformers=[splitter, redundant_filter, relevant_filter]
)

compression_retriever = ContextualCompressionRetriever(base_compressor=pipeline_compressor, base_retriever=retriever)

compressed_docs = compression_retriever.get_relevant_documents(query=question)
pretty_print_docs(compressed_docs)
Document 1:
A1: The school is called "Canine Academy".
----------------------------------------------------------------------------------------------------
Document 2:
Fiktive Hundeschule: Canine Academy
Q1: What is the name of the dog training school?
----------------------------------------------------------------------------------------------------
Document 3:
Fiktive Hundeschule: Canine Academy
Q1: What is the name of the dog training school?
A1: The school is called "Canine Academy".

Q2: Where is Canine Academy located?
A2: Canine Academy is located in the suburbs, near the community park.

Q3: What training programs are offered at Canine Academy?
A3: They offer basic obedience, agility training, and advanced behavioral courses.

Q4: Are there any special qualifications for the trainers at Canine Academy?
A4: All trainers are certified and have years of experience in dog training and behavior.

Q5: Can Canine Academy help with specific behavioral issues?
A5: Yes, they offer personalized training sessions for issues like aggression, anxiety, and barking.

Q6: How long do the training courses last?
A6: The courses vary, ranging from 4-week short courses to 12-week intensive programs.

Q7: Does Canine Academy provide training for service or therapy dogs?
A7: Yes, they have specialized programs for service and therapy dog training.

Q8: Is there a trial class or evaluation session available?
A8: Yes, they offer a free evaluation session to assess the dog's needs and training level.

Q9: What are the fees for the training courses at Canine Academy?
A9: Fees vary based on the course, but they offer competitive rates and package deals.

Q10: Does Canine Academy offer any support or follow-up after completion of a course?
A10: Yes, they provide follow-up consultations and support for continued training and development.
----------------------------------------------------------------------------------------------------
Document 4:
Q3: What training programs are offered at Canine Academy?

4. Ensemble Retriever

  1. 앙상블 리트리버의 구조:

    • 여러 리트리버의 get_relevant_documents() 결과를 결합.

    • 상호 순위 융합 알고리즘을 사용하여 결과 재순위화.

  2. 성능 향상:

    • 서로 다른 알고리즘의 강점을 활용하여 단일 알고리즘보다 우수한 성능 달성.

  3. 일반적인 패턴:

    • BM25와 같은 스파스 리트리버와 밀도 리트리버(예: 임베딩 유사도)의 결합.

    • 이러한 결합을 '하이브리드 검색'이라고 명명.

  4. 각 리트리버의 강점:

    • 스파스 리트리버: 키워드를 기반으로 관련 문서 검색에 효과적.

    • 밀도 리트리버: 의미적 유사성을 기반으로 관련 문서 검색에 효과적.

#%pip install rank_bm25
from langchain.retrievers import BM25Retriever, EnsembleRetriever


bm25_retriever = BM25Retriever.from_documents(docs)
bm25_retriever.k = 2

chroma_vectorstore = Chroma.from_documents(docs, embedding)
chroma_retriever = chroma_vectorstore.as_retriever()

ensemble_retriever = EnsembleRetriever(
    retrievers=[bm25_retriever, chroma_retriever], weights=[0.5, 0.5]
)
docs = ensemble_retriever.get_relevant_documents(query=question)
docs
Number of requested results 4 is greater than number of elements in index 2, updating n_results = 2





[Document(page_content='Fiktive Hundeschule: Canine Academy\nQ1: What is the name of the dog training school?\nA1: The school is called "Canine Academy".\n\nQ2: Where is Canine Academy located?\nA2: Canine Academy is located in the suburbs, near the community park.\n\nQ3: What training programs are offered at Canine Academy?\nA3: They offer basic obedience, agility training, and advanced behavioral courses.\n\nQ4: Are there any special qualifications for the trainers at Canine Academy?\nA4: All trainers are certified and have years of experience in dog training and behavior.\n\nQ5: Can Canine Academy help with specific behavioral issues?\nA5: Yes, they offer personalized training sessions for issues like aggression, anxiety, and barking.\n\nQ6: How long do the training courses last?\nA6: The courses vary, ranging from 4-week short courses to 12-week intensive programs.\n\nQ7: Does Canine Academy provide training for service or therapy dogs?\nA7: Yes, they have specialized programs for service and therapy dog training.\n\nQ8: Is there a trial class or evaluation session available?\nA8: Yes, they offer a free evaluation session to assess the dog\'s needs and training level.\n\nQ9: What are the fees for the training courses at Canine Academy?\nA9: Fees vary based on the course, but they offer competitive rates and package deals.\n\nQ10: Does Canine Academy offer any support or follow-up after completion of a course?\nA10: Yes, they provide follow-up consultations and support for continued training and development.', metadata={'source': './dogs.txt'}),
 Document(page_content='Fiktives Restaurant: Gourmet\'s Delight\nQ1: What is the name of the restaurant?\nA1: The restaurant is named "Gourmet\'s Delight".\n\nQ2: Where is Gourmet\'s Delight located?\nA2: It is located in the heart of downtown, on Maple Street.\n\nQ3: What type of cuisine does Gourmet\'s Delight offer?\nA3: Gourmet\'s Delight specializes in a fusion of Mediterranean and Asian cuisine.\n\nQ4: Is the restaurant vegetarian-friendly?\nA4: Yes, there is a wide range of vegetarian and vegan options available.\n\nQ5: Does Gourmet\'s Delight accept reservations?\nA5: Yes, guests are encouraged to make reservations, especially on weekends.\n\nQ6: Are there any special dishes that are recommended at Gourmet\'s Delight?\nA6: The signature dish is the \'Medit-Asian Fusion Platter\' which includes a variety of specialties.\n\nQ7: What are the operating hours of the restaurant?\nA7: The restaurant is open from 11:00 AM to 10:00 PM, Monday through Sunday.\n\nQ8: Does Gourmet\'s Delight offer any special promotions?\nA8: Yes, there are happy hour discounts from 4:00 PM to 6:00 PM on weekdays.\n\nQ9: Can Gourmet\'s Delight accommodate large parties or events?\nA9: Yes, the restaurant has a private dining area that can be reserved for events and parties.', metadata={'source': './restaurant.txt'})]

5. Self-Querying retriever

  1. 자체 쿼리 리트리버의 기능:

    • 스스로 쿼리할 수 있는 기능이 내장된 리트리버.

    • 자연어 쿼리를 받아 구조화된 쿼리를 작성.

    • 작성된 구조화된 쿼리를 기본 VectorStore에 적용.

  2. 리트리버의 작업 과정:

    • 사용자 입력 쿼리를 통해 저장된 문서의 콘텐츠와 의미적 유사성 비교.

    • 저장된 문서의 메타데이터에 대한 사용자 쿼리에서 필터 추출 및 실행.

  3. 쿼리 생성자의 중요성:

    • 쿼리 생성자는 셀프 쿼리 리트리버의 핵심 요소.

    • 프롬프트, 예제, 속성 설명 조정이 필요.

    • 구체화 과정 예제를 볼 수 있는 쿡북 제공.

  4. 구조화된 쿼리 번역기의 역할:

    • 일반 StructuredQuery 객체를 메타데이터 필터로 변환.

    • 사용 중인 벡터 저장소의 구문에 맞게 번역.

    • LangChain에 다양한 번역기 내장.

from langchain.schema import Document
from langchain.vectorstores import Chroma

docs = [
    Document(
        page_content="Bello-Basistraining offers a comprehensive foundation for dog obedience, focusing on basic commands and socialization.",
        metadata={"type": "Basic Training", "feature": "Foundational Skills", "price": "Affordable"},
    ),
    Document(
        page_content="Pfote-Agilitykurs provides a fun and energetic way to keep dogs fit and mentally stimulated through obstacle courses.",
        metadata={"type": "Agility Training", "feature": "Physical Fitness", "price": "Moderate"},
    ),
    Document(
        page_content="Wuff-Verhaltensberatung specializes in addressing behavioral issues, offering tailored strategies for each dog.",
        metadata={"type": "Behavioral Consultation", "feature": "Customized Solutions", "price": "Premium"},
    ),
    Document(
        page_content="Schwanzwedeln-Therapiehundausbildung prepares dogs for roles in therapeutic and support settings, focusing on empathy and gentleness.",
        metadata={"type": "Therapy Dog Training", "feature": "Emotional Support", "price": "High"},
    ),
    Document(
        page_content="Schnüffler-Suchhundetraining trains dogs in scent detection, useful for search and rescue operations.",
        metadata={"type": "Search and Rescue Training", "feature": "Advanced Skills", "price": "Variable"},
    ),
    Document(
        page_content="Hunde-Haftpflichtversicherung offers comprehensive coverage for potential damages or injuries caused by your dog.",
        metadata={"type": "Dog Liability Insurance", "feature": "Financial Protection", "price": "Varies"},
    ),
]

vectorstore = Chroma.from_documents(docs, embedding)
#%pip install lark
from langchain.vectorstores import Chroma
from langchain.chains.query_constructor.base import AttributeInfo
from langchain.retrievers.self_query.base import SelfQueryRetriever

metadata_field_info = [
    AttributeInfo(
        name="type",
        description="The type of dog training service (e.g., Basic Training, Agility Training, Behavioral Consultation)",
        type="string",
    ),
    AttributeInfo(
        name="feature",
        description="Special features or benefits of the service",
        type="string",
    ),
    AttributeInfo(
        name="price",
        description="Price category of the service (e.g., Affordable, Moderate, Premium)",
        type="string",
    ),
]

document_content_description = "Description of a dog training service"
retriever = SelfQueryRetriever.from_llm(
    llm,
    vectorstore,
    document_content_description,
    metadata_field_info,
)
retriever.invoke("What Premium priced trainings do you offer?")
[Document(page_content='Wuff-Verhaltensberatung specializes in addressing behavioral issues, offering tailored strategies for each dog.', metadata={'feature': 'Customized Solutions', 'price': 'Premium', 'type': 'Behavioral Consultation'})]

6. TimeWeightedVectorStoreRetriever

  1. 조합의 사용:

    • 이 리트리버는 의미적 유사성과 시간 감쇠를 결합하여 사용합니다.

  2. 점수 매기기 알고리즘: $semantic_similarity + (1.0 - decay_rate)^{hours_passed}$

    • 경과된 시간은 리트리버 객체가 생성된 후가 아니라 마지막으로 액세스된 후의 시간을 기준으로 합니다.

  3. 객체 관리:

    • 자주 액세스되는 객체는 "최신" 상태로 유지됩니다.

import faiss

from datetime import datetime, timedelta
from langchain.docstore import InMemoryDocstore
from langchain.embeddings import OpenAIEmbeddings
from langchain.retrievers import TimeWeightedVectorStoreRetriever
from langchain.schema import Document
from langchain.vectorstores import FAISS
# decay_rate = .0000000000000000000000001
decay_rate = .999

embedding_size = 1536
index = faiss.IndexFlatL2(embedding_size)
vectorstore = FAISS(embedding, index, InMemoryDocstore({}), {})
retriever = TimeWeightedVectorStoreRetriever(vectorstore=vectorstore, decay_rate=decay_rate, k=1)
yesterday = datetime.now() - timedelta(days=1)
retriever.add_documents([Document(page_content="hello world", metadata={"last_accessed_at": yesterday})])
retriever.add_documents([Document(page_content="hello foo")])
['d0cc6c05-88d4-4d62-a667-29b4cf9ab54f']
retriever.get_relevant_documents("hello world")
[Document(page_content='hello foo', metadata={'last_accessed_at': datetime.datetime(2023, 12, 20, 16, 12, 25, 440607), 'created_at': datetime.datetime(2023, 12, 20, 16, 12, 24, 242085), 'buffer_idx': 1})]

7. Vector store-backed retriever

  1. 벡터 저장소 리트리버의 정의:

    • 벡터 저장소를 사용하여 문서를 검색하는 리트리버.

    • 벡터 저장소 클래스를 경량 래퍼로 감싸 리트리버 인터페이스에 맞게 구성.

  2. 검색 방법:

    • 유사성 검색 및 벡터 저장소가 구현한 기타 검색 방법 사용.

    • MMR 등의 검색 방법으로 벡터 저장소의 텍스트 쿼리.

  3. 기본 검색 방식:

    • 기본적으로 유사도 검색 사용.

    • 최대 한계 관련성 검색 지원 시, 검색 유형으로 지정 가능.

  4. 임계값 설정:

    • 유사도 점수 임계값 설정 가능.

    • 임계값보다 높은 점수를 받은 문서만 반환.

  5. 검색 설정 옵션:

    • 검색 시 사용할 k값과 같은 검색 키워드를 지정할 수 있음.

from langchain.document_loaders import TextLoader

loader = TextLoader('dogs.txt')
from langchain.text_splitter import CharacterTextSplitter
from langchain.vectorstores import FAISS
from langchain.embeddings import OpenAIEmbeddings

documents = loader.load()
text_splitter = CharacterTextSplitter(chunk_size=1000, chunk_overlap=0)
texts = text_splitter.split_documents(documents)
embeddings = OpenAIEmbeddings()
db = FAISS.from_documents(texts, embeddings)
retriever = db.as_retriever()

docs = retriever.get_relevant_documents("What is the name of the dog school?")
# Maximum marginal relevance retrieval
retriever = db.as_retriever(search_type="mmr")

docs = retriever.get_relevant_documents("What is the name of the dog school?")
# Similarity score threshold retrieval
retriever = db.as_retriever(search_type="similarity_score_threshold", search_kwargs={"score_threshold": .5})

docs = retriever.get_relevant_documents("What is the name of the dog school?")
# Specifying top k
retriever = db.as_retriever(search_kwargs={"k": 1})

docs = retriever.get_relevant_documents("What is the name of the dog school?")
len(docs)
1

8. WebResearchRetriever

  1. 검색어 입력 시 리트리버의 실행 과정:

    • 검색어를 기반으로 일련의 관련 Google 검색을 수행

  2. 검색 과정:

    • 각 검색어에 대해 별도의 검색을 실행

  3. 결과 처리:

    • 모든 검색 결과의 URL을 로드

  4. 최종 검색 단계:

    • 통합된 페이지 콘텐츠에 쿼리를 임베드하여 유사도 검색을 수행

from langchain.retrievers.web_research import WebResearchRetriever

import os

from langchain.chat_models.openai import ChatOpenAI
from langchain.embeddings import OpenAIEmbeddings
from langchain.utilities import GoogleSearchAPIWrapper
from langchain.vectorstores import Chroma

# Vectorstore
vectorstore = Chroma(
    embedding_function=OpenAIEmbeddings(), persist_directory="./chroma_db_oai"
)

# LLM
llm = ChatOpenAI(temperature=0)

# Search
os.environ["GOOGLE_CSE_ID"] = "xxx"
os.environ["GOOGLE_API_KEY"] = "xxx"
search = GoogleSearchAPIWrapper()
# Initialize
web_research_retriever = WebResearchRetriever.from_llm(
    vectorstore=vectorstore,
    llm=llm,
    search=search,
)
#Run with citations

from langchain.chains import RetrievalQAWithSourcesChain

user_input = "How do LLM Powered Autonomous Agents work?"
qa_chain = RetrievalQAWithSourcesChain.from_chain_type(
    llm, retriever=web_research_retriever
)
result = qa_chain({"question": user_input})
result
# Run
import logging

logging.basicConfig()
logging.getLogger("langchain.retrievers.web_research").setLevel(logging.INFO)
user_input = "What is Task Decomposition in LLM Powered Autonomous Agents?"
docs = web_research_retriever.get_relevant_documents(user_input)
# Generate answer using retrieved docs

from langchain.chains.question_answering import load_qa_chain

chain = load_qa_chain(llm, chain_type="stuff")
output = chain(
    {"input_documents": docs, "question": user_input}, return_only_outputs=True
)
output["output_text"]


3. Modular RAG

모듈형 RAG는 고급 RAG의 다양한 모듈과 기술을 통합하여 전반적인 RAG 시스템을 개선합니다. 예를 들어, 유사도 검색을 위한 검색 모듈을 통합하고 retrieval에 미세 조정 접근 방식을 적용하는 것입니다. 모듈형 RAG는 RAG 애플리케이션을 구축할 때 표준 패러다임이 되었습니다. 모듈의 몇 가지 예

  1. Search Module- 검색 모듈은 벡터 데이터베이스에서 컨텍스트를 검색하는 것 외에도 검색 엔진, 표 형식 데이터, 지식 그래프 등과 같은 다른 소스에서 데이터를 통합합니다.

  2. Memory Module- LLM이 벡터 데이터베이스에서 검색된 청크뿐만 아니라 시스템 메모리에 저장된 이전 쿼리 및 답변도 참조할 수 있는 메모리 구성 요소를 RAG 시스템에 추가합니다.

  3. Fusion - 원본 쿼리와 확장 쿼리의 병렬 벡터 검색, 지능형 재랭킹을 통한 결과 최적화, 최상의 결과를 새 쿼리와 페어링하는 작업을 포함합니다.

  4. Routing - 쿼리 라우팅은 요약, 특정 데이터베이스 검색 등 사용자의 쿼리에 대한 후속 작업을 결정합니다.

모듈식 RAG은 고급 RAG의 발전된 형태로, 기존의 RAG 프레임워크에서 한 단계 더 나아가 다양한 모듈과 기능을 통합하여 더 큰 다양성과 유연성을 제공합니다. 이 접근 방식은 RAG 시스템을 다양한 시나리오와 요구 사항에 맞게 조정할 수 있도록 하는 여러 새로운 모듈과 패턴을 포함하고 있습니다.

새로운 모듈들(New Modules)

  1. 검색 모듈(Search Module)

기본 및 고급 RAG의 유사성 검색과 달리, 검색 모듈은 특정 시나리오에 맞춰 LLM이 생성한 코드나 SQL, 사용자 도구 등을 사용하여 직접 검색을 수행하는 모듈입니다. 이러한 검색 모듈을 사용하는 경우, 외부 검색 엔진이나 텍스트 데이터, 테이블 데이터 또는 지식 그래프 등을 데이터 소스로 사용할 수 있습니다.

  1. 메모리 모듈(Memory Module)

LLM 자체의 메모리 기능을 사용하여 검색을 개선(guide)하며, 현재 입력과 가장 유사한 기억을 찾는 모듈입니다. 예를 들어, Self-mem 방법론은 검색 강화 생성기(Retrieval-Enhanced Generator)를 반복적으로 사용하여 사용자의 질문(original question)과 이중 질문(dual question)을 결합한 무제한 메모리 풀(unbounded memory pool)을 생성합니다. 이러한 과정을 통하여 추론 과정을 향상시킵니다.

  1. 추가 생성 모듈(Extra Generation Module)

검색된 내용의 중복 및 잡음 문제에 대응하기 위한 모듈로, LLM을 활용하여 검색을 위한 문서를 별도로 생성합니다. 사용자의 질문을 데이터 소스에서 직접 검색하는 것보다, 이렇게 LLM에 의해 생성된 콘텐를 사용하였을 때 관련 정보를 더 많이 포함할 가능성이 높습니다.

  1. 태스크 적응 모듈(Task Adaptable Module)

다양한 다운스트림(downstream) 작업에 적응할 수 있도록 조정하는 모듈입니다. 각 세부 작업과 모델의 범용성을 강화하는 것을 목표로, 필요한 제로샷 프롬프트를 검색하여 사용(UPRISE 방법)하거나, 제로샷 쿼리를 생성하는 LLM을 별도로 사용(PROMPTAGATOR 방법)하기도 합니다.

  1. 정렬 모듈(Alignment Module)

질의와 텍스트 간의 정렬 문제를 해결하기 위해 검색기에 별도의 학습 가능한 어댑터를 추가하는 모듈입니다. PRCA, AAR, RRR 등의 방법론들이 있으며, 이를 통해 검색된 정보를 최적화하고 RAG의 효과를 향상시키는 것이 목적입니다.

  1. 검증 모듈(Validation Module)

검색된 정보의 신뢰성을 평가하기 위해 도입되었으며, 실제 문서와 질의 간의 관련성을 평가하는 모듈입니다. 이 모듈은 RAG의 강건성(robustness)을 향상시키는 것이 목표입니다.

새로운 패턴들(New Patterns)

  1. 모듈 추가 또는 교체(Adding or Replacing Modules)

기존의 검색-읽기(RR; Retrieval-Read) 구조를 유지하면서 특정 기능을 향상시키기 위해 추가 모듈을 도입합니다. 예를 들어, 재작성-검색-읽기(RRR; Rewrite-Retrieve-Read) 프로세스를 통해 검색 쿼리를 조작하고, 읽기 모듈의 하위 작업 성능을 향상시킬 수 있습니다.

  1. 모듈 간 조직적 흐름 조정(Adjusting the Flow between Modules)

언어 모델과 검색 모델 간의 상호작용을 강화하기 위해 모듈 간 조직적 흐름을 조정합니다. 이는 특정 문제 맥락에 기반하여 모듈 내에서의 대체 또는 재구성을 가능하게 합니다.

Last updated