Home RAG 우리가 절대 쉽게 결과물을 얻을 수 없는 이유 노트
Post
Cancel

RAG 우리가 절대 쉽게 결과물을 얻을 수 없는 이유 노트

TeddyLee님의 langchain-kr 깃허브: https://github.com/teddylee777/langchain-kr

목차

  1. 지난 1년간 (2023) 6개 기업의 10여개 프로젝트에서 얻은 RAG 경험담
  2. 마주한 도전들
  3. 실패 사례, 극복 시도
  4. Vector Store, Prompt Engineering, LLM Fine-tuning

용어정리

RAG: Retrieval Augmented Generation

RAG 프로세스

자체 정의한 RAG 프로세스 과정

1. 전처리 작업

  1. Load Document: 처리할 문서를 시스템에 불러옵
  2. Chunk(Split): 문서를 더 작고 관리하기 쉬운 조각으로 나눈다(llm은 한번에 읽을 수 있는 단어는 few thousands 이기 때문)
  3. Embedding: 이 조각들을 내용의 본질을 포착하는 숫자 표현으로 변환
  4. Store: 임베딩들을 데이터베이스에 저장

https://i.imgur.com/yUgGrWZ.png

2. 서비스 단계에서 이뤄지는 작업

  • llm 서비스 구동중인 상태에서 이뤄지는 작업
  1. 유저 질문을 받아 Embedding 처리
  2. Retrieve(발췌)
    • 실시간으로 이루어짐
  3. 프롬프트 엔지니어링후 LLM에 전달
  4. output

https://i.imgur.com/6nPNirw.png

문서 전처리

모듈

  1. Document Loader: 문서 로드
    • Langchain에서 150가지 loader 지원
  2. Text Splitter: 분할 전략
    • 10 가지 알고리즘 지원
  3. Embedding: 임베딩
    • Langchain + HuggingFace
  4. Vector Store: Vector DB
    • Semantic Search를 위해 RAG에서는 주로 VectorDB사용
    • LangChain에서 80가지 지원
  5. Retrievers: Vector DB 검색기
    • 50가지 지원

강의 목적: 위 내용을 조합하여 3억개 이상의 조합 발생 → 모든 상황 테스트 불가능 → pipeline 구성시 참고용 경험 공유

Document Loader(PDF)

  • Excel/SCV, PDF을 주로 취급
  • 보안에 유리한 PDF 형식의 문서가 많았음

LangChain의 강점: 통합된 Interface를 제공해 여러 모듈들을 바꿔가며 테스트해보기 용이함

Document Loader 선택시 고려사항

  • 텍스트를 원형 그대로 가져오는지
    • 한글, 특수문자
  • 메타데이터(metadata)의 종류
    • page_content
    • 페이지번호(page)
    • 표, 차트, 문서의 coordinates(좌표), 속성(Title, Table, Image, Text)
  • 속도

속도 vs 다양한 메타데이터 제공여부가 관건이 될것 같다

Retriever

Multi-Query Retriever

  • LLM 사용해 사용자 입력 쿼리 -> 여러 관점에서의 여러 쿼리 생성(Prompt Tuning 프로세스 자동화 효과)

  • 각 쿼리에 대해 관련 문서 집합을 검색하고 모든 쿼리에서 고유한 유니온을 사용하여 잠재적으로 관련성이 높은 문서 집합을 가져옴

  • 키워드 기반 검색 시 의미를 잘 포착하지 못하는 문제를 해결함

    ex) 질문: “Page Rank에 대해 알려줘” Multi-Query Retriever 결과:

    1. Page Rank 알고리즘의 작동 원리는 무엇인가요?
    2. Page Rank를 사용하는 이유와 그 효과에 대해 설명해주세요
    3. 구글의 Page Rank 기술에 대한 상세한 정보를 제공해줄 수 있나요?

Ensemble Retriever

배경

  • Semantic Search의 문제점
    • 유사 의미를 가지는 문서의 검색에서는 유리
    • BUT : 특정 키워드가 반드시 포함되어야 하는 검색시 유사 단어가 포함된 문서가 검색될 수 있음 ex) “비타민A 영양제 추천해줘” -> “비타민C가 풍부한 영양제는 00 영양제”, “비타민D가 부족하다면 이 영양제를 추천합니다”

‘비타민’ 때문에 유사성 발생 -> Semantic Search

위와 같은 경우 키워드 기반 검색을 사용하는 Sparse Retriever이 유리함 -> 여러 Retriever을 ensemble하자

장점:

  • 여러 Retriever을 ensemble하여 사용(Sparse Retriever + Dense Retriever의 ensemble)
  • 서로 다른 알고리즘의 강점 활용 -> 단일 Retriever 대비 성능 향상
  • ensemble하는 retriever간 weight 조절도 가능

Sparse Retriever: BM25Retriever, Dense Retriever: faiss_vectorstore.as_retriver() 사용한 예시

1
2
3
4
5
6
7
8
9
10
11
12
13
#initialize the bm25 retriever and faiss retriever
bm25_retriever = BM25Retriever from_texts(doc_list)
bm25_retriever.k = 2

embedding = OpenAIEmbeddings()
faiss_vectorstore = FAISS.from_texts(doc_list, embedding)
faiss_retriever = faiss_vectorstorem.as_retriver(search_kwargs={"k"::2})

# initialize the ensemble retriever
ensemble_retriever = EnsembleRetriever(
									   retrievers = [bm25_retriver, faiss_retriever], weights=[0.5, 0.5]
)

Long Context Reorder

  • https://arxiv.org/abs/2307.03172
  • 모델 아키텍처와 관계없이 검색된 문서를 10개 이상 포함시 상당한 성능 저하 발생
  • 긴 context 중간 정보 access해야 하는 경우, 제공된 문서를 무시하는 경향이 발생

https://i.imgur.com/5qHk0B7.png

  • 정렬 방식 : 중요도 기준 내림차순 정렬 -> 매우중요 - 덜 중요 - 중요
  • 중요한 문서 검색 결과를 상위로 재조종하여 중요한 정보를 답변에 포함하도록 유도
1
2
3
4
5
6
# 문서 재정렬:
# 관련성이 낮은 문서는 목록의 가운데에 배치
# 시작/끝에 관련성 높은 요소 배치
reordering = LongContextReorder()
reordered_docs = reordering.transform_documents(docs)

  • Multi-Vector Retriever: 여러 VectorStore의 Retriever ensemble
  • ContextualCOmpressor: 긴 길이의 문서 검색 결과 압축
  • LLMChainFilter: 문서의 검색 결과 필터링

Prompt Engineering

  • 양식에 맞춘 출력 형식이 중요한 경우(사업기획서, 보고서)
    • FewShotPromptTemplate 활용
  • LangSmith Hub에 업로드 되어 있는 완성형 Prompt을 Pull하여 사용하기
  • 별도의 .yaml 파일로 프롬프트 version관리

Chain of Density(문서요약 프롬프트)

배경

  • 요약에 포함할 정보의 “적절한” 양을 선택하는 것은 어려운 작업
  • 좋은 요약은 정보의 밀도가 높고, Entity 중심이어야 함

해결 방안

  • Chain of Density 프롬프트를 사용하여 점점 더 밀도가 높은 요약을 요청
  • 이전 Missing Entities를 추가 및 갱신하여 요약할때마다 Denser Summary 출력

방식

  1. Sparse한 요약 생성
  2. 이전의 Sparse 요약에 Missing Entity 발견
  3. Missing Entity를 추가한 Denser Summary 생성
  4. 1~3번을 5회 반복
This post is licensed under CC BY 4.0 by the author.

LangChain for LLM Application Development

LangGraph