"그건 얼마야?" — 대화가 이어지는 RAG
박수현 · (사)한국정보공학기술사회 · 2026
🎯 목표: 후속 질문("그럼 기간은?")까지 정확히 답하는 대화형 RAG 구현.
📁 참고:
7.RAG/5.conversational/5.1_followup_problem.py

🖼️ 대화이력 인지 RAG · 이력+질문→독립 질문 재작성→Retriever→context→Prompt→LLM→답변
💡 핵심은 검색 이전 단계의 질문 재작성(history-aware)이다. 이력을 검색기에 직접 주입하지 않고, 질문 자체를 독립적으로 완결시킨다.
from langchain_core.chat_history import InMemoryChatMessageHistory
from langchain_core.runnables.history import RunnableWithMessageHistory
sessions = {} # {session_id: InMemoryChatMessageHistory}
def get_session_history(session_id):
return sessions.setdefault(session_id, InMemoryChatMessageHistory())
# 세션 이력의 로드·저장을 자동화 — 호출 시 session_id 만 지정
conversational_rag = RunnableWithMessageHistory(
rag_chain, get_session_history,
input_messages_key="input",
history_messages_key="chat_history",
output_messages_key="answer")
RunnableWithMessageHistory 가 세션별 이력 자동 로드·저장InMemoryChatMessageHistory 는 휘발 → 실서비스는 Redis/DB 로 교체🔑 다중 사용자는
session_id로 격리하며, 라우트는 세션 ID 만 전달한다.
from langchain.chains import (
create_history_aware_retriever, create_retrieval_chain)
from langchain.chains.combine_documents import create_stuff_documents_chain
# ① 검색: 이력 기반 쿼리 재작성 → retriever
history_aware = create_history_aware_retriever(llm, retriever, rewrite_prompt)
# ② 답변: 검색 문서 {context} + chat_history + input
doc_chain = create_stuff_documents_chain(llm, qa_prompt)
# 두 체인 결합 — 검색·답변 양쪽이 history 를 참조
rag_chain = create_retrieval_chain(history_aware, doc_chain)
qa_prompt 에 MessagesPlaceholder("chat_history") 로 이력 자리 확보📁 전체:
7.RAG/5.conversational/5.3_full_conversational_rag.py
💡 history-aware 패턴은 질문을 독립 쿼리로 재작성하므로, 검색 정확도 측면에서 긴 이력이 불필요하다. 짧은 이력만으로 충분하다.
한도 미만이면 이력 그대로, 초과하면 오래된 대화는 요약하고 최근 N턴만 유지