Investment-Assistant

RAG 코드 구현하기: 효율적인 정보 검색 [13]

HeyTeddy 2024. 11. 27. 16:40
반응형

최근 인공지능 모델이 생성하는 텍스트에서 '할루시네이션(Hallucination)' 문제가 빈번히 발생하고 있습니다. 이를 방지하기 위해 RAG (Retrieval-Augmented Generation) 기법이 주목받고 있습니다. 이번 포스트에서는 RAG를 구현하고, 이를 통해 어떻게 생성된 응답의 신뢰도를 높일 수 있는지 살펴보겠습니다.

RAG란 무엇인가?

RAG(Retrieval-Augmented Generation)는 검색과 생성이 결합된 AI 모델의 한 형태입니다. 단순히 대규모 언어 모델(LLM)이 질문에 답변을 생성하는 것과 달리, RAG는 다음 두 가지 단계로 동작합니다:

  1. 정보 검색 (Retrieval)
    • 모델이 질문과 관련된 정보를 외부 데이터베이스나 문서에서 검색합니다.
    • 검색 결과는 질문과 관련성이 높은 문서로 구성됩니다.
  2. 답변 생성 (Generation)
    • 검색된 문서를 바탕으로 질문에 대해 정확한 답변을 생성합니다.
    • 이 과정에서 언어 모델은 검색된 정보에 의존하므로, 할루시네이션 현상을 줄일 수 있습니다.

RAG의 주요 장점

  • 할루시네이션 방지: 외부 문서를 참조하여 답변을 생성하기 때문에, 데이터베이스에 없는 허구의 정보를 만들어내는 현상을 최소화합니다.
  • 높은 신뢰도: 모델이 질문에 답변을 생성할 때 근거를 제시할 수 있어, 결과의 신뢰도를 높입니다.
  • 확장 가능성: 외부 데이터베이스를 업데이트하거나 확장함으로써 더 많은 정보를 처리할 수 있습니다.

RAG 코드 구현

아래 코드는 RAG를 구현하기 위해 앙상블 기반 검색기를 초기 설정한 부분입니다. 이 코드는 두 가지 검색 기법인 BM25와 FAISS를 결합하여 검색 성능을 최적화합니다.

from langchain_community.retrievers import BM25Retriever
from langchain_openai import OpenAIEmbeddings
from langchain_community.vectorstores import FAISS
from langchain.retrievers import EnsembleRetriever
import config
from openai import OpenAI

client = OpenAI(api_key=config.OPENAI_API_KEY)
model = "gpt-4o"

docs = [
    "우리나라는 2022년에 코로나가 유행했다.",
    "우리나라 2024년 GDP 전망은 3.0%이다.",
    "우리나라는 2022년 국내총생산 중 연구개발 예산은 약 5%이다.",
    "삼성전자 2024년 1분기 매출액은 약 7조원으로 잠정 추정됩니다.",
    "2024년 7월 19일 삼성전자 주가는 64,500원입니다."
]

bm25_retriever = BM25Retriever.from_texts(
    docs, metadatas=[{"source": 1}]*len(docs)
)
bm25_retriever.k = 1

embedding = OpenAIEmbeddings(api_key=config.OPENAI_API_KEY)
faiss_vectorstore = FAISS.from_texts(
    docs, embedding, metadatas=[{"source": 1}] * len(docs)
)
faiss_retriever = faiss_vectorstore.as_retriever(search_kwargs={"k":1})

query = "2022년 우리나라 GDP대비 R&D 규모는?"

# ensemble
ensemble_retriever = EnsembleRetriever(
    retrievers=[bm25_retriever, faiss_retriever],
    weights=[0.2, 0.8], 
)

# 검색 함수 정의
def search(query):
    ensemble_docs = ensemble_retriever.invoke(query)
    return ensemble_docs

# GPT를 활용한 답변 생성
def chatgpt_generate(query):
    messages = [{
        "role": "system",
        "content": "You are a helpful assistant"
    },{
        "role": "user",
        "content": query
    }]
    response = client.chat.completions.create(model=model, messages=messages)
    answer = response.choices[0].message.content
    return answer

# 검색 결과를 기반으로 답변 생성
def prompt_and_generate(query, docs):
    
    prompt = f"""아래 질문을 기반으로 검색된 문서를 참고하여 질문에 대한 답변을 생성하시오.
    질문: {query}
    """

    for i in range(len(docs)):
        prompt += f"문서{i+1}: " + docs[i]
    print(prompt)
    answer = chatgpt_generate(prompt)
    return answer

query = "삼성전자의 올해 매출액은?"
retrieved = [doc.page_content for doc in search(query)]
answer = prompt_and_generate(query, retrieved)
print(answer)

답변

아래 질문을 기반으로 검색된 문서를 참고하여 질문에 대한 답변을 생성하시오.
    질문: 삼성전자의 올해 매출액은?
    문서1: 삼성전자 2024년 1분기 매출액은 약 7조원으로 잠정 추정됩니다.문서2: 2024년 7월 19일 삼성전자 주가는 64,500원입니다.
주어진 문서에서는 삼성전자의 2024년 전체 매출액에 대한 정보가 제공되지 않았습니다. 문서1은 2024년 1분기 매출액에 대한 추정치로 약 7조 원이라고 언급하고 있습니다. 전체 연도 기준의 매출액 정보는 추가적인 자료가 필요할 것으로 보입니다. 더 구체적인 연도별 매출액 정보를 확인하기 위해서는 삼성전자의 공식 재무 보고서를 참조하는 것이 좋습니다.

RAG를 통한 Hallucination 예방과 신뢰성 강화

RAG의 핵심은 "외부 데이터와의 연결"에 있습니다. 단순히 모델이 질문을 예측하는 방식이 아니라, 데이터를 바탕으로 답변을 생성하므로, 다음과 같은 문제를 효과적으로 해결합니다:

  • 할루시네이션 방지: 질문에 대한 정보가 명확하게 제공되지 않으면, 검색 단계에서 반환된 데이터를 중심으로 답변을 생성합니다.
  • 높은 정확성: 답변의 근거가 되는 문서를 제공함으로써 결과의 신뢰성을 높이고, 사용자가 답변을 검증할 수 있습니다.

결론

RAG는 검색과 생성을 결합하여 AI 시스템의 신뢰성을 높이는 혁신적인 기법입니다. 특히, BM25와 FAISS 같은 앙상블 검색기를 사용하면 더 정교한 결과를 얻을 수 있습니다.

앞으로 다양한 데이터베이스와 RAG를 결합하여 도메인에 특화된 고성능 AI 서비스를 개발할 수 있을 것입니다. 이를 통해 보다 정확하고 신뢰성 높은 답변을 제공하는 AI 시스템을 구축할 수 있습니다.

추가 정보
GitHub에 업로드된 다양한 RAG 구현 사례를 참고하거나, 본 코드를 기반으로 커스터마이징을 진행해 보세요!

반응형