본문 바로가기

IT, Computer

Retrieval Augmented Generation(RAG) 복습 (6) 사전을 사용해서 질문 바꾸기

반응형

 

 

목차

     

     


    썸네일


    서론

    우리가 제대로 LLM을 만들었음에도, 대답이 썩 만족스럽지 않은 경우가 있다. 물론 제대로의 제대로가 진정한 의미에서의 제대로가 아닐수도 있지만, 어느정도 검증된 모델을 향연으로 코드가 제대로 돌아가는 걸 확인한 이상 가장 떠오르는 변수는 바로 '사용자의 질문'이다. 개떡같이 물어도 찰떡같이 알아듣는다는 속담이 괜히 있는게 아니다. 그만큼 개떡같이 물어보는 사람이 많다는 것이고, 대답하는 사람은 그걸 알아듣고 찰떡같이 대답해야된다. 특히 대답해야되는 사람이 을의 입장이라면... 사용자가 개떡같이 말했을 때 잘 알아들어야된다. 이번 포스팅에서는 이러한 상황때 잘 알아들을 수 있게 dictionary를 작성하는 과정을 가질 것이다.


    어떤식으로 문제가 발생하는가

    서론에서 얘기하는 상황에 대해서 알아보도록 하자. 질문이 중요한 이유는 대답하는 과정에 질문에 해당하는 내용과 가장 유사한(코사인 유사도) 문장을 몇개 꼽는 것이 있기 때문이다. 그래서 질문이 문서에 해당하는 내요을 담고 있어야되는데, 너무 큰 범주로 말하거나 다른 동의어 유사어로 물을 수가 있다. 가령 정말 가령, db에 있는 문서가 동물에 대한 문서인데 쿼리가 "강아지는 밥을 얼만큼 줘야돼?" 밥이 사료인걸 알지라도 정확도가 떨어지는 것이다. 해당 문서에 쌀을 먹는 동물이 있다면 아마 걔 문서가 올라갈수도 있음. 아무튼 문서에 있는 내용을 끄집어 낼 수 있도록 올바르게 질문하는 것이 중요하며, 질문자는 그렇게 하지 않기에 우리가 그걸 바꿔줘야 된다.


    Dictionary를 통해 사용자의 질문 바꾸기

     아무튼 위와 같은 상황을 없애기 위해 우리는 질문을 바꿔야 되는데 그 방법이 바로 사전을 만드는 것이다. 결국 원하는 과정은 사용자의 나이브한 질문 -> 사전에 해당하면 그에 맞게 질문을 바꿔줌 ->  바꿔진 질문으로 유사도 검색이다. 우리는 지난 포스팅에서 qa_chain이 이미 만들은 상태다. 그래서 Dictionary를 사용하여 단어를 바꿔서 나온 새로운 스트링(= prompt | model | StrOutPutParser() )을 qa_chain 앞단에 놓을 것이다. 참고로 prompt | model | StrOutPutParser() 는 prompt  -> 그걸 받은(=Prompt IN) model로 만들고 -> model을 받아서(=model IN) string으로 paring하라는 선언이다. 

    from langchain_core.output_parsers import StrOutputParser, ChatPromptTemplate
    
    
    dictionary = ["밥을 나타내는 표현 -> 사료"]
    
    prompt = ChatPromptTemplate.from_template(f""" 
    질문을 토대로 사전을 참고하여 질문을 변경해주세요.
    변경할 필요가 없으면 변경하지 않아도 됩니다.
    사전: {dictionary}
    질문: {{query}}
    """)
                
    dictionary_chain = prompt | llm | StrOutputParser()

    위 코드를 진행한 뒤, query에 "강아지는 밥을 얼만큼 줘야 돼?"를 넣은 다음, dictionary_chain.invoke({"query"}: query})를 하면 강아지는 사료를 얼만큼 줘야 돼?로 바뀐다. 이제 이걸 qa_chain 앞단에 넣어보자.

     dictionary chain을 qa chain 앞단에 넣기

    dictionary chain을 qa chain의 앞단에 넣은 새로운 체인을 new_chain이라고 하자. 그러면 다음과 같이 선언하면 된다.

    new_chain = {"query": dictionary_chain} | qa_chain

    이렇게 하면 만들어진 새로운 체인을 기반으로 답변을 만들고, 그 후 new_chain.invoke({"query": query})를 선언하면 바뀌어진 질문을 토대로 답변을 생성한다.


    오늘은 dictionary를 통해서 애매한 쿼리를 문서와 관련된 쿼리로 바꾸는 과정에 대해서 알아보았다. 다음 포스팅에서는 추후 LLM 모델링을 하는 과정에서 문제가 생기면 해당 상황에 대해서 포스팅을 하도록 하겠다. 다음 포스팅을 보려면 여기로 오면 된다.