환각을 줄이고 검색을 개선하는 능동적 RAG

Agentic RAG가 질의 재구성, 결과 정제, 더 큰 언어 모델 활용을 통해 환각을 줄이고 검색 성능을 향상시킬 수 있는 방법을 발견하세요. RAG 애플리케이션에 대한 더 포괄적이고 관련성 높은 응답을 얻으세요.

2025년 2월 17일

party-gif

에이전트를 통해 검색 증강 생성(RAG)의 힘을 unleash하세요. 지능형 에이전트를 도입하여 쿼리를 분석하고 검색을 개선하며 더 정확하고 포괄적인 응답을 생성함으로써 RAG 파이프라인을 향상시키고 환각을 줄이는 방법을 발견하세요. 이 블로그 게시물은 에이전트 기반 RAG를 구현하는 실용적인 가이드를 제공하여 자연어 처리 애플리케이션을 향상시킬 수 있는 도구를 제공합니다.

RAG의 환각을 해결하는 방법

정보 검색 단계는 사용자가 질문을 하는 방식에 크게 의존합니다. 질문이 잘 구성되지 않으면 지식베이스에 정보가 있더라도 정보 검색이 어려울 수 있습니다. 전통적인 RAG에서는 단일, 짧은 검색 결과를 얻지만 에이전트 기반 RAG로 이를 해결할 수 있습니다.

에이전트 기반 RAG가 어떻게 도움이 되는지 알아보기 위해 전통적인 RAG 검색 설정을 살펴보겠습니다. 사용자 질문은 정보 베이스에서 가장 관련성 높은 청크를 찾는 의미 기반 유사성 검색을 통과합니다. 그런데 질문 자체가 적절하게 구성되지 않으면 어떻게 될까요? 그런 경우 RAG 파이프라인은 환각을 일으킬 가능성이 높아, 답변을 만들어내거나 언어 모델이 정보를 찾지 못했다고 사용자에게 알릴 것입니다. 지식베이스에 정보가 있음에도 말이죠.

이를 해결하기 위해 RAG 파이프라인에 에이전트를 도입하고 초기 질문뿐만 아니라 RAG 파이프라인에서 생성된 응답도 분석할 수 있는 능력을 부여할 수 있습니다. 일반적인 과정은 다음과 같습니다:

  1. 초기 질문이 에이전트를 통과합니다.
  2. 에이전트가 초기 질문을 재구성합니다.
  3. 정제된 질문이 지식베이스를 통과하고 의미 기반 유사성 검색을 수행하여 가장 관련성 높은 문서를 검색합니다.
  4. 관련 문서를 언어 모델에 전달하기 전에 에이전트가 해당 문서 또는 청크를 다시 분석하고 검색된 문서로는 질문에 답할 수 없다고 판단하면 질문을 더 정제합니다.
  5. 정제된 질문을 기반으로 프로세스를 반복하여 에이전트가 검색된 문서와 재구성된 질문에 만족할 때까지 진행합니다.
  6. 최종 컨텍스트가 언어 모델에 전달되어 답변이 생성됩니다.

이 경우 에이전트는 계획, 분석, 실행을 통해 RAG 파이프라인에 에이전트 루프를 구현할 수 있습니다. Crew AI, AutoGPT, LangChain의 LangGraph 등의 프레임워크를 사용할 수 있습니다. 이 비디오에서는 Transformers 패키지 내의 Transformers Agents라는 덜 알려진 기능을 사용하여 에이전트를 만들 것입니다.

에이전트 기반 RAG 파이프라인 구축하기

정보 검색 단계는 사용자가 질문을 하는 방식에 크게 의존합니다. 질문이 잘 구성되지 않으면 지식베이스에 정보가 있더라도 정보 검색이 어려울 수 있습니다. 전통적인 RAG에서는 단일, 짧은 검색 결과를 얻지만 에이전트 기반 RAG로 이를 해결할 수 있습니다.

에이전트 기반 RAG가 어떻게 도움이 되는지 알아보기 위해 전통적인 RAG 검색 설정을 살펴보겠습니다. 사용자 질문은 정보 베이스에서 가장 관련성 높은 청크를 찾는 의미 기반 유사성 검색을 통과합니다. 그런데 질문 자체가 적절하게 구성되지 않으면 어떻게 될까요? 그런 경우 RAG 파이프라인은 환각을 일으킬 가능성이 높아, 답변을 만들어내거나 LLM이 정보를 찾지 못했다고 사용자에게 알릴 것입니다. 지식베이스에 정보가 있음에도 말이죠.

이를 해결하기 위해 RAG 파이프라인에 에이전트를 도입하고 초기 질문뿐만 아니라 RAG 파이프라인에서 생성된 응답도 분석할 수 있는 능력을 부여할 수 있습니다. 일반적인 과정은 다음과 같습니다:

  1. 초기 질문이 에이전트를 통과합니다.
  2. 에이전트가 초기 질문을 재구성합니다.
  3. 정제된 질문이 지식베이스를 통과하고 의미 기반 유사성 검색을 수행하여 가장 관련성 높은 문서를 검색합니다.
  4. 관련 문서를 LLM에 전달하기 전에 에이전트가 해당 문서 또는 청크를 다시 분석하고 검색된 문서로는 질문에 답할 수 없다고 판단하면 질문을 더 정제합니다.
  5. 정제된 질문을 기반으로 프로세스를 반복하여 에이전트가 검색된 문서와 재구성된 질문에 만족할 때까지 진행합니다.
  6. 최종 컨텍스트가 LLM에 전달되어 답변이 생성됩니다.

RAG 파이프라인에 에이전트 루프를 구현하기 위해 Crew AI, Auto, LangChain의 LangGraph 등의 프레임워크를 사용할 수 있습니다. 이 경우에는 Transformers 패키지 내의 Transformers Agents라는 덜 알려진 기능을 사용하여 에이전트를 만들 것입니다.

먼저 필요한 패키지들, 즉 pandas, LangChain, LangChain Community 패키지, Sentence Transformer 패키지, Transformers 패키지를 설치해야 합니다. 그런 다음 필요한 모듈을 가져오고 데이터를 설정할 것입니다. 문서를 청크로 나누고 임베딩을 만들 것입니다.

다음으로 에이전트가 지식베이스에서 관련 문서를 검색할 수 있는 검색 도구를 만들 것입니다. 그리고 OpenAI 엔진을 사용하여 LLM을 설정할 것입니다.

마지막으로 검색 도구와 LLM에 접근할 수 있는 에이전트를 만들고, 에이전트의 행동을 안내하는 시스템 프롬프트를 설정할 것입니다. 그런 다음 에이전트 루프를 실행하여 샘플 질문에 대한 답변을 생성하고, 표준 RAG 파이프라인과 결과를 비교할 것입니다.

에이전트 기반 RAG 접근 방식을 통해 에이전트가 질문을 정제하고 가장 관련성 높은 정보를 검색할 수 있어 LLM의 응답 품질이 향상됩니다.

검색 도구 만들기

에이전트 기반 RAG 파이프라인을 위한 검색 도구를 만들기 위해 다음과 같은 구조의 RetrievalTool 클래스를 정의합니다:

class RetrievalTool:
    """Using semantic similarity, retrieves some documents from the knowledge base that have the closest embeddings to the input."""

    def __init__(self, vector_db):
        self.vector_db = vector_db

    def __call__(self, query: str) -> List[str]:
        """
        Retrieve up to 7 most similar chunks from the vector DB for the given query.
        
        Args:
            query (str): A query to perform retrieval on. This should be semantically close to the target documents.
        
        Returns:
            List[str]: A list of up to 7 most similar chunks from the vector DB.
        """
        results = self.vector_db.similarity_search(query, k=7)
        return [chunk.page_content for chunk in results]

RetrievalTool 클래스는 vector_db 객체를 입력으로 받습니다. 이 객체는 문서 임베딩을 저장하는 벡터 저장소(Faiss, Chroma, Pinecone 등)입니다.

__call__ 메서드는 query 문자열을 입력으로 받고 벡터 DB에서 가장 유사한 최대 7개의 청크를 반환합니다. vector_db 객체의 similarity_search 메서드를 사용하여 코사인 유사성 기반으로 가장 유사한 청크를 찾습니다.

이 검색 도구는 에이전트 기반 RAG 파이프라인의 일부로 사용될 수 있습니다. 에이전트는 초기 질문을 분석하고 정제하여 검색 도구에 전달할 수 있습니다.

언어 모델 통합하기

에이전트 기반 RAG 파이프라인에 언어 모델을 통합하려면 에이전트와 최종 응답 생성에 모두 사용될 LLM을 설정해야 합니다. 두 가지 옵션이 있습니다:

  1. Hugging Face 엔진 사용: Hugging Face 서버리스 아키텍처를 통해 다양한 LLM의 API 엔드포인트를 직접 호출할 수 있습니다. Llama 38B 또는 70B 모델 등을 사용할 수 있지만 일반적으로 Hugging Face Pro 구독이 필요합니다.

  2. OpenAI 사용: 이 예제에서는 OpenAI 엔진을 사용할 것입니다. 다른 LLM을 설정하는 과정도 유사하게 적용할 수 있습니다.

OpenAI 엔진을 설정하기 위해 Transformer Agents LLM 엔진의 message_rlegpt_generate_message_list 함수를 사용하는 OpenAIEngine 클래스를 만듭니다. 이 클래스는 입력 메시지를 정리하고 OpenAI 채팅 완성 엔드포인트를 사용하여 응답을 생성합니다.

다음으로 실제 에이전트를 만듭니다. 에이전트는 앞서 만든 검색 도구, 이 경우 OpenAIEngine을 사용하는 LLM, 그리고 에이전트 루프를 중지하기 전 최대 반복 횟수에 접근할 수 있습니다.

또한 에이전트에게 시스템 프롬프트를 제공하여 지식베이스의 정보를 사용하여 사용자 질문에 대한 포괄적인 답변을 제공하도록 안내합니다. 프롬프트는 에이전트가 필요한 정보를 찾지 못한 경우 다른 질문으로 검색 프로세스를 반복하도록 격려합니다.

에이전트와 LLM이 설정되면 에이전트 루프를 실행하여 사용자 질문에 답변할 수 있습니다. 에이전트는 질문을 반복적으로 정제하고, 지식베이스에서 관련 정보를 검색하며, LLM을 사용하여 최종 응답을 생성합니다. 이 접근 방식은 표준 RAG 파이프라인에 비해 더 자세하고 관련성 있는 답변을 제공합니다.

에이전트 기반 에이전트 구현하기

에이전트를 구현하기 위해 Transformers 패키지 내의 Transformers Agents 기능을 사용할 것입니다. 이를 통해 사용자 정의 에이전트를 만드는 모듈식이고 명확한 접근 방식을 제공합니다.

먼저 pandas, Langchain, Langchain Community 패키지, Sentence Transformers, Transformers Agents 등의 필요한 패키지를 설치해야 합니다.

그런 다음 필요한 모듈과 패키지를 가져옵니다. ReactJsonAgent를 사용하고, 에이전트를 위한 사용자 정의 도구를 구축하며, Hugging Face 엔진을 활용하여 언어 모델을 사용할 것입니다.

RAG 파이프라인을 구축하기 위해 Hugging Face 문서 데이터셋으로 시작합니다. 문서를 청크로

자주하는 질문