[AI] RetrievalQA is deprecated !!!

늘 공부하는 괴짜·2025년 6월 25일
0

AI : Langchain (RAG)

목록 보기
33/38

1. Langchain 자료 뒤져보다가 두둥~

Langchain으로 RAG를 아주 쉽게 구현하게 도와주는 RetrievalQA 가 이제 가신다고 한다...

2. 대응

아주 친절하게도 Langchain 은 그 대안을 제공하는데 그에 맞춰서 구현해 봤다.

2-1. create_stuff_documents_chain, create_retrieval_chain

뭔가 한방에 체이닝 하는 느낌이 아니라 아쉽긴 한데 아예 create_retrieval_chain 을 따로 만들어놔서 직관적이긴 하다.

# 수정 전
qa_chain = RetrievalQA.from_chain_type(
    llm, # llama3.2:1b
    retriever=chroma_database.as_retriever(),
    chain_type_kwargs={"prompt": prompt}
)


# 수정 후
# llm 과 프롬프트 엮기
llm_prompt_chain = create_stuff_documents_chain(
    llm, 
    retrieval_qa_chat_prompt
)

# llm + 프롬프트 + retriever 엮기
retrieval_chain = create_retrieval_chain(retriever, llm_prompt_chain)

3. 전체 소스

3-1. basic_retriever.py

나는 배달앱을 싫어한다. 그냥 아무 뉴스나 긁어온것이다.

from langchain.vectorstores import FAISS
from langchain.embeddings import HuggingFaceEmbeddings
from langchain.schema import Document

def getRetriever():

    # 1. 일반 텍스트 리스트
    texts = [
        """
        김동연 경기도지사가 “도민 여러분들께서는 장바구니 물가 걱정 좀 덜었으면 한다”고 말했다.
        김 지사는 지난 21일 오산 오색시장에서 열린 ‘2025 경기 살리기 통큰세일’ 개막식에서 “경기도가 통 크게 준비했다. 작년 40억 예산을 올해 100억으로 2.5배 늘렸다”고 설명하면서 이같이 밝혔다.
        경기 살리기 통큰세일은 경기지역 400여 개 전통시장과 골목상권이 참여하는 소비촉진행사로, 이날부터 9일간 대장정에 돌입했다.
        통큰세일은 경기지역 소비를 촉진하고 지역 내 경제 선순환을 유도하기 위해 경기도와 경기도시장상권진흥원이 지난해부터 추진해 온 프로젝트다.
        특히 올해는 상권별 행사기간을 통일하고, 상반기와 하반기에 두 번 추진하는 것으로 정례화해 도민 혼선 없이 집중 효과를 낼 수 있도록 기획됐다.
        김 지사는 “(참여)시장도 2배 이상 늘려서 경기도의 전통시장과 골목상권 다 합쳐서 400곳 넘는 곳 전부 혜택 볼 수 있도록 했다”며 “통큰세일을 계기로 지금 가장 어려움을 겪고 있는 소상공인, 자영업자 또 골목상권 계시는 많은 분들 힘내시기 바란다. 시장이 활기차게 돌아가고 장사가 잘 돼서 상권이 다시 살아나기를 바란다”고 말했다. 이어 “최대 20%까지 할인(환급) 행사까지 하니까 (도민들은) 마음껏 이용해 주시기 바란다”고 덧붙였다.
        김 지사는 개막식 후 시장을 돌며 온누리상품권과 현금으로 과일과 채소 등 15만원가량 장을 봤다. 이 과정에서 통큰세일 혜택으로 온누리상품권 2만원을 환급받아 인근 가게에서 수박 한 통을 구매하고 현장을 떠났다.
        올해 통큰세일은 사업비를 전년 대비 2.5배(40억→100억원) 확대해 도내 400여 개 전통시장과 골목상권에서 29일까지 동시에 진행된다. 경기지역화폐와 온누리상품권 등을 활용한 최대 20% 페이백(1일 1인 최대 3만원)을 중심으로 구성됐다. ‘배달특급’ ‘먹깨비’ ‘땡겨요’ 등 공공배달앱도 할인쿠폰을 발행하는 등 참여해 음식업 소상공인의 매출 증대도 도모한다.        
        """
    ]

    # 2. 텍스트를 Document로 래핑
    docs = [Document(page_content=t) for t in texts]

    # 3. 임베딩 모델 선택 (HuggingFace 등)
    embedding_model = HuggingFaceEmbeddings(model_name="sentence-transformers/all-MiniLM-L6-v2")

    # 4. 벡터 스토어 생성 (로컬 저장 없이 메모리에서만)
    vectorstore = FAISS.from_documents(docs, embedding_model)

    # 5. retriever 로 변환
    retriever = vectorstore.as_retriever()

    return retriever

3-2. 실행 파일

from langchain_ollama import ChatOllama
from langchain_core.prompts import ChatPromptTemplate
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain.chains import create_retrieval_chain
from langchain import hub
from basic_retriever import getRetriever

# 프롬프트 갖다쓰기.
retrieval_qa_chat_prompt = hub.pull("langchain-ai/retrieval-qa-chat")

# ChatOllama 
llm = ChatOllama(
    model = "exaone3.5:32b",
    temperature = 0.8,
    num_predict = 256
)

# 데이터
retriever = getRetriever()

# llm 과 프롬프트 엮기
llm_prompt_chain = create_stuff_documents_chain(
    llm, 
    retrieval_qa_chat_prompt
)

# llm + 프롬프트 + retriever 엮기
retrieval_chain = create_retrieval_chain(retriever, llm_prompt_chain)

# 질의
result = retrieval_chain.invoke({"input": "공공배달앱으로는 무엇이 있는가?"})

# 결과
print(result["answer"])

4. 결과

5. 근데...

langchain-ai/retrieval-qa-chat 이 모든 llm 에게 허용되진 않는다. (by ChatGpt)

6. 프롬프트를 수동 제어하면?

허깅페이스의 tokenizer.apply_chat_template 와 비슷하게 프롬프트를 만들어 보자. 얼핏 보면 Langchain 이 훨씬 깔끔하고 정갈한 느낌이 있다.

from langchain_ollama import ChatOllama
from langchain_core.prompts import ChatPromptTemplate
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain.chains import create_retrieval_chain
from langchain import hub
from basic_retriever import getRetriever

# 프롬프트 갖다쓰기.
# retrieval_qa_chat_prompt = hub.pull("langchain-ai/retrieval-qa-chat")
template = """<|begin_of_text|><|start_header_id|>system<|end_header_id|>
당신은 친절하고 유능한 AI 비서입니다.<|eot_id|><|start_header_id|>user<|end_header_id|>
다음 정보를 참고하여 질문에 답해주세요. \n
{context} \n
질문: {input}<|eot_id|><|start_header_id|>assistant<|end_header_id|>"""

retrieval_qa_chat_prompt = ChatPromptTemplate.from_template(template)

# ChatOllama 
llm = ChatOllama(
    model = "exaone3.5:32b",
    temperature = 0.8,
    num_predict = 256
)

# 데이터
retriever = getRetriever()

# llm 과 프롬프트 엮기
llm_prompt_chain = create_stuff_documents_chain(
    llm, 
    retrieval_qa_chat_prompt,
    document_variable_name="context" # 프롬프트에 context로 전달
)

# llm + 프롬프트 + retriever 엮기
retrieval_chain = create_retrieval_chain(retriever, llm_prompt_chain)

# 질의
result = retrieval_chain.invoke({"input": "공공배달앱으로는 무엇이 있는가?"})

# 결과
print(result["answer"])
profile
인공지능이라는 옷을 입었습니다. 뭔가 멋지면서도 잘 맞습니다.

0개의 댓글