AI/LLM

[LLM] RAG

죵욜이 2025. 2. 27. 23:40

RAG 란?

RAG 은 정보 검색생성 모델을 결합하여, 더 정확하고 풍부한 답변을 제공하는 AI 모델의 접근 방식입니다.

이 방식은 정보 검색(retrieval)과 텍스트 생성(generation)을 결합하여,

사용자가 질문할 때 모델이 외부의 문서나 데이터베이스에서 필요한 정보를 검색하고,

그 정보를 바탕으로 자연스러운 텍스트를 생성하는 방식입니다.

 

RAG 는 주로 기존의 생성형 모델들이 가지는 정보의 제한성을 해결하기 위해 만들어졌습니다.

GPT같은 모델은 훈련 데이터에 포함된 정보만을 기반으로 답변을 생성하기 때문에

그 이후에 발생한 정보나 훈련에 포함되지 않은 특정 세부 정보에 대해서는 잘못된 답변을 할 수 있습니다.


RAG 동작방식

  1. 문서 로딩
    • 문서로는 JSON, 이미지, 텍스트, CSV, PDF 등 다양한 문서가 들어갈 수 있습니다.
  2. 문서 chunking (spliting)
    • chunking은 긴 문서를 더 작고 관리하기 쉬운 부분들로 나누는 과정
    • vectorDB에 chunk단위로 적재하게 된다.
  3. embedding
    • 문자열형태의 chunk를 벡터(숫자)로 변환하는 과정
  4. 벡터 스토어
    • 이전 단계에서 생성된 임베딩 벡터들을 효율적으로 저장하고 관리하는 저장소

 

5. 리트리버 : 물어오기!

  • 저장된 벡터 데이터베이스에서 사용자의 질문과 관련된 문서(context)를 검색(물어오기)하는 검색기

 

이러면 RAG 구축은 끝이난다

 

구축해둔 RAG 을 바탕으로 챗봇을 구동하면 아래와 같이 동작하게 된다.

 

  1. 사용자가 질문하기 :
    • 사용자 : 우리 회사의 야근식대는 얼마야?
  2. Retrieval(검색) :
    • 리트리버가 사용자 질문에 대한 자료를 벡터 DB에서 검색해옴
    • 질문과 연관성이 높은 청크를 검색해서 context로 리턴한다.
  3. Augment(증강) : 프롬프트 = context(벡터DB에서 검색해온 자료) + query(사용자 질문)
prompt = ChatPromptTemplate.from_template("""
오로지 아래의 context만을 기반으로 질문에 대답하세요:
{context}
질문:
{question}
""")

prompt = ChatPromptTemplate.from_template("""
오로지 아래의 context만을 기반으로 질문에 대답하세요:
야근 식대는 2만원 입니다.
질문:
우리 회사의 야근 식대는 얼마입니까?
""")

 

4. Generation(생성) : LLM 에 완성된 프롬프트 집어넣고 답변 받기

  • 프롬프트에는 질문에 답변할 수 있는 자료 (context, 맥락)이 있으니, LLM은 이를 기반으로 환각없이 잘 대답할 수 있다
  • 무한상사 사규 챗봇 : 우리회사의 야근식대는 2만원 입니다.

코드로 보면 아래와 같다

더보기
from langchain_community.vectorstores import FAISS
from langchain_community.document_loaders import WebBaseLoader
from langchain_core.output_parsers import StrOutputParser
from langchain_core.runnables import RunnablePassthrough
from langchain_openai import OpenAIEmbeddings
from langchain_text_splitters import RecursiveCharacterTextSplitter
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain.document_loaders import PyPDFLoader


####################
####### RAG 챗봇 구축
###################

# 1. LLM 모델 불러오기
llm = ChatOpenAI(model="gpt-4o-mini")

# 2. 문서 불러오기
loader = PyPDFLoader("/content/[2024 한권으로 OK 주식과 세금].pdf")
docs = loader.load()

# 3. 문서 chunking 하기
text_splitter = RecursiveCharacterTextSplitter(chunk_size=1000, chunk_overlap=200)
splits = text_splitter.split_documents(docs)

# 4. 자른 chunk들을 embedding 하기
embeddings = OpenAIEmbeddings(model="text-embedding-ada-002")

# 5. vector store 구축하기
vectorstore = FAISS.from_documents(documents=splits, embedding=embeddings)

# 6. retriever 구축하기
retriever = vectorstore.as_retriever()

# 7. 프롬프트 템플릿 구축하기
prompt = prompt = ChatPromptTemplate.from_template("""
오로지 아래의 context만을 기반으로 질문에 대답하세요:
{context}
질문:
{question}
""")


# 8. 1~7. 요소들을 chain으로 조합하여 RAG 구축 완료
def format_docs(docs):
    return "\n\n".join(doc.page_content for doc in docs)

rag_chain = (
    {"context": retriever | format_docs, "question": RunnablePassthrough()}
    | prompt
    | llm
    | StrOutputParser()
)


####################
####### 구축한 RAG 챗봇 실행
###################

rag_chain.invoke("상장주식 대주주 기준이 50억 원 이상으로 완화되었는데 언제부터 적용되는 건가요?")

 

'AI > LLM' 카테고리의 다른 글

[LangGraph] LangGraph 란 무엇인가?  (0) 2025.03.19
[LLM] LangChain 의 유용한 기능들  (0) 2025.02.28
[LLM] LangChain (prompttemplate 과 LCEL)  (0) 2025.02.19