LLM & Generative AI/RAG in Practice

[LangChain RAG 구축 시리즈 Ep.19] 🧠 대화형 QA 시스템: ConversationalRetrievalChain 구성하기

ygtoken 2025. 4. 5. 21:37
728x90

이 글에서는 사용자의 이전 질문과 답변을 기억하여
자연스러운 대화 흐름을 이어갈 수 있는
ConversationalRetrievalChain을 구성해봅니다.


🎯 목표

  • ConversationalRetrievalChain 구성
  • 이전 대화 내용을 기억하여 문맥 기반 응답 생성
  • 메모리(ConversationBufferMemory)를 통해 히스토리 저장

🧠 대화형 RAG의 개념

기존 RetrievalQA는 "단일 질문-답변" 방식이라면,
ConversationalRetrievalChain질문 맥락을 기억하며 대화를 이어갑니다.

예시:

1️⃣ Q: 상품 테이블 알려줘
2️⃣ Q: 컬럼은 뭐야? ← 이전 질문 맥락이 없다면 “무슨 테이블?”로 이해 안 됨


🛠️ Step 1. 체인 구성 함수 만들기

# src/conversational_chain.py

from langchain.chains import ConversationalRetrievalChain       # 대화형 체인
from langchain.chat_models import ChatOpenAI                     # GPT 모델
from langchain.vectorstores import Chroma                        # 벡터 저장소
from langchain.embeddings import OpenAIEmbeddings                # 임베딩 모델
from langchain.memory import ConversationBufferMemory            # 메모리 객체

def create_conversational_chain(db_path: str, collection_name: str, k: int = 2):
    """
    Chroma + GPT + Memory를 활용한 Conversational RAG 체인 구성
    """

    # 1. OpenAI 임베딩 모델
    embedding = OpenAIEmbeddings()

    # 2. ChromaDB 벡터 저장소 불러오기
    vectordb = Chroma(
        persist_directory=db_path,            # 벡터 저장 위치
        embedding_function=embedding,         # 동일한 임베딩 모델
        collection_name=collection_name       # 컬렉션 이름
    )

    # 3. 검색기 생성
    retriever = vectordb.as_retriever(search_kwargs={"k": k})

    # 4. GPT 모델 정의
    llm = ChatOpenAI(
        model_name="gpt-3.5-turbo",           # GPT 모델
        temperature=0.2                       # 일관성 있게 응답
    )

    # 5. 대화 기록을 저장할 메모리 구성
    memory = ConversationBufferMemory(
        memory_key="chat_history",            # 내부적으로 사용할 히스토리 키
        return_messages=True                  # 메시지 형식으로 반환
    )

    # 6. 대화형 Retrieval 체인 구성
    chain = ConversationalRetrievalChain.from_llm(
        llm=llm,
        retriever=retriever,
        memory=memory,
        return_source_documents=True          # 참조 문서 반환 포함
    )

    return chain

💬 Step 2. 대화 흐름 테스트

# main.py

from src.conversational_chain import create_conversational_chain  # 체인 호출

# ✅ 경로 설정
db_path = "chroma_db"
collection_name = "iceberg_tables"

# ✅ 대화형 체인 생성
chat_chain = create_conversational_chain(db_path, collection_name, k=2)

# ✅ 첫 번째 질문 (주제 소개)
query1 = "상품 테이블이 뭐야?"
result1 = chat_chain.run(query1)
print("📣 응답 1:", result1)

# ✅ 두 번째 질문 (맥락 기반 질문)
query2 = "그 테이블에 컬럼 뭐 있어?"
result2 = chat_chain.run(query2)
print("📣 응답 2:", result2)

📤 출력 예시

📣 응답 1:
상품 정보를 담고 있는 테이블은 'products'입니다. 컬럼에는 product_id, product_name, category가 포함됩니다.

📣 응답 2:
products 테이블에는 product_id (long), product_name (string), category (string) 컬럼이 있습니다.

✅ 두 번째 질문에서 **“그 테이블”**이 어떤 것인지 정확히 기억하여 응답합니다.


💡 참고: Memory 유형 변경도 가능

Memory 종류 설명
ConversationBufferMemory 기본 텍스트 히스토리
ConversationSummaryMemory GPT가 요약해 저장
ConversationBufferWindowMemory 최근 N개만 유지

📎 요약 및 핵심 정리

  • ConversationalRetrievalChain은 사용자의 이전 질문과 답변을 기억하는 대화형 체인입니다.
  • ConversationBufferMemory를 통해 대화 흐름이 자연스럽게 이어집니다.
  • RAG 시스템에 기억을 더해 실사용에 가까운 QA 인터페이스를 구성할 수 있습니다.
728x90