주메뉴 바로가기 본문 바로가기

알림

콘솔 이동 시 로그인이 필요합니다.

로그인하시겠습니까?

아니요

닫기

주문 불가 알림

주문권한이 없습니다.

콘솔에 접근할 수 없는 계정입니다.

확인

닫기

알림

신용카드 등록이 필요합니다.

신용카드 등록 페이지로 이동하시겠습니까?

아니요

닫기
AX Tech
img

Azure 기반 Advanced RAG 구현

img 배정환
| 2025.05.28
  • RAG
  • GenerativeAI
  • Azure

RAG의 기본 개념과 일반적인 사용 사례, 그리고 Azure를 활용해 Advanced RAG를 구현

AI 기술의 발전은 정보 검색 및 생성 방식에 혁신을 가져왔습니다. 그중 RAG(Retriever-Augmented Generation) 패턴은 검색 기술과 대규모 언어 모델(LLM)을 결합하여 복잡한 질문에 답할 수 있는 강력한 도구로 자리 잡았습니다. 이번 글에서는 RAG의 기본 개념과 일반적인 사용 사례, 그리고 Azure를 활용해 Advanced RAG를 구현하며 기존 RAG 패턴의 한계를 어떻게 극복할 수 있는지 살펴보겠습니다.

[RAG(Retrieval-Augmented Generation)의 개념]

RAG는 대규모 언어 모델(LLM)의 성능을 향상시키는 기술로, 외부 지식 소스에서 관련 정보를 검색하여 LLM의 응답 생성에 활용합니다. 이 방식은 최신 정보 반영, 사실적 오류 감소, 그리고 도메인 특화된 지식 활용을 가능하게 합니다.RAG의 기본 워크플로우는 다음과 같습니다:


Better RAG 1: Advanced Basics(https://huggingface.co/blog/hrishioa/retrieval-augmented-generation-1-basics)
  1. 데이터 인덱싱: 문서를 청크로 나누고 임베딩하여 벡터 데이터베이스에 저장
  2. 쿼리 처리: 사용자 질문을 임베딩하여 관련 문서 검색
  3. 컨텍스트 생성: 검색된 문서를 바탕으로 LLM에 전달할 프롬프트 구성
  4. 응답 생성: LLM이 제공된 컨텍스트를 바탕으로 답변 생성

이러한 접근 방식은 LLM의 고유한 지식과 외부 데이터 소스의 최신 정보를 결합하여, 더욱 정확하고 맥락에 맞는 응답을 생성할 수 있게 합니다.

그렇다면 이러한 RAG 패턴이 어떻게 생겨났고, 어떻게 변화해왔는지에 대해서 알아보겠습니다.

[RAG의 진화와 패러다임 변화]

RAG의 발전 과정과 패러다임 변화를 학술적 관점에서 살펴보면 다음과 같습니다

  • 전통적인 정보 검색 시스템
    초기의 정보 검색 시스템은 주로 Boolean 모델과 벡터 공간 모델에 기반했습니다. 이 시스템들은 키워드 매칭에 의존하여 관련 문서를 찾았지만, 의미적 이해에는 한계가 있었습니다.
  • 신경망 기반 검색 모델
    2000년대 후반부터 신경망을 활용한 정보 검색 모델이 등장했습니다. DSSM(Deep Structured Semantic Models)과 같은 모델은 쿼리와 문서를 동일한 의미 공간에 매핑하여 더 정확한 검색을 가능하게 했습니다.

Learning Deep Structured Semantic Models for Web Search using Clickthrough Data(https://www.microsoft.com/en-us/research/wp-content/uploads/2016/02/cikm2013_DSSM_fullversion.pdf)
  • 트랜스포머와 BERT의 등장
    2018년 BERT의 등장으로 자연어 처리 분야에 큰 변화가 일어났습니다. BERT를 이용한 검색 모델은 문맥을 고려한 더 정교한 검색을 가능하게 했습니다.
  • RAG의 탄생
    2020년 Facebook AI에서 발표한 “Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks” 논문은 RAG의 기본 개념을 소개했습니다. 이 모델은 파라메트릭 메모리(LLM)와 비파라메트릭 메모리(검색 시스템)를 결합하여 지식 집약적 태스크의 성능을 크게 향상시켰습니다.

Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks(https://arxiv.org/pdf/2005.11401)
  • 하이브리드 검색 기술
    키워드 기반 검색과 의미론적 검색을 결합한 하이브리드 접근법이 등장했습니다. “ColBERT: Efficient and Effective Passage Search via Contextualized Late Interaction over BERT” 논문은 이러한 하이브리드 접근법의 효과성을 입증했습니다.
  • 멀티 쿼리 확장
    “Multi-Query Retrieval” 기법은 하나의 사용자 쿼리에서 여러 관련 쿼리를 생성하여 검색의 다양성과 정확성을 높였습니다. 이는 “Improving Passage Retrieval with Zero-Shot Question Generation” 논문에서 제안되었습니다.
  • 계층적 검색 및 재순위화
    계층적 검색과 재순위화 기술은 검색 결과의 품질을 더욱 향상시켰습니다. “COIL: Revisit Exact Lexical Match in Information Retrieval with Contextualized Inverted List” 논문은 이러한 접근법의 효과를 보여줍니다.
  • 멀티모달 RAG
    텍스트뿐만 아니라 다양한 형태의 데이터를 처리하는 멀티모달 RAG 시스템이 개발되었습니다. “Multimodal Few-Shot Learning with Frozen Language Models” 논문은 이미지와 텍스트를 결합한 RAG 시스템의 가능성을 제시했습니다.
  • 자기 반영 및 추론 기반 RAG
    최신 RAG 시스템은 자체 출력을 평가하고 필요한 경우 추가 정보를 검색하는 자기 반영 메커니즘을 포함합니다. “Self-RAG: Learning to Retrieve, Generate, and Critique through Self-Reflection” 논문은 이러한 접근법의 효과성을 보여줍니다.

이러한 RAG의 진화는 정보 검색과 자연어 처리 분야에 큰 변화를 가져왔습니다. 단순한 정보 검색에서 시작하여 이제는 복잡한 질문에 대해 정확하고 맥락에 맞는 답변을 생성할 수 있는 수준에 이르렀습니다. 이는 AI 시스템의 지식 기반을 크게 확장시키고, 더욱 지능적이고 유용한 AI 애플리케이션의 개발을 가능하게 했습니다.

[일반적인 RAG 패턴의 한계]

RAG는 강력한 패턴이지만, 몇 가지 중요한 문제점을 가지고 있습니다.

  1. 검색 품질 저하
    단순 키워드 검색은 질문의 맥락을 충분히 이해하지 못해 부정확한 정보를 반환할 수 있습니다. 이는 잘못된 답변 생성으로 이어질 수 있습니다.
  2. 토큰 제한
    언어 모델은 입력 길이에 제한이 있어 검색된 모든 정보를 사용할 수 없을 수 있습니다.
  3. 실시간성 부족
    데이터베이스가 최신 정보와 동기화되지 않으면 최신 데이터에 대한 답변이 불가능합니다.
  4. 복잡한 쿼리 처리 부족
    단순 키워드 기반 검색은 복잡한 논리나 상호 참조가 필요한 질문을 처리하는 데 한계가 있습니다.
  5. 보안 및 프라이버시 문제
    외부 데이터 소스와의 통합 과정에서 민감한 정보가 노출될 위험이 있습니다.
  6. 응답 속도 저하
    검색과 생성의 비효율적인 연결은 응답 속도를 떨어뜨리고 사용자 경험을 저하시킬 수 있습니다.

그렇다면 이러한 문제 및 제한 사항들을 해결하기 위해서 Advanced RAG를 구현하기 위해 Azure 환경에서는 어떻게 구성하는지 직접 살펴보겠습니다.

Azure에서 RAG를 구현하는 기본 단계는 다음과 같습니다:

  1. Azure OpenAI Service 설정
  2. Azure AI Search 구성
  3. 데이터 인덱싱 및 임베딩
  4. Azure Functions 또는 App Service를 사용한 API 개발
  5. 프론트엔드 애플리케이션 구축

[Advanced RAG 구현 (Hands-on Lab)]

이제 Azure를 사용하여 Advanced RAG를 구현하는 방법을 단계별로 살펴보겠습니다.
이론적인 내용은 하기의 링크를 참고할 수 있습니다.

[Build advanced retrieval-augmented generation systems]
Build Advanced Retrieval-Augmented Generation Systems
As a developer, learn about real-world considerations and patterns for retrieval-augmented generation (RAG)-based chat…learn.microsoft.com

1단계: 환경 설정

# Azure CLI 설치 (이미 설치되어 있다면 생략)
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
# Azure에 로그인
az login
# 리소스 그룹 생성
az group create --name myRAGResourceGroup --location eastus

2단계: Azure OpenAI Service 설정

# Azure OpenAI 리소스 생성
az cognitiveservices account create --name myOpenAI --resource-group myRAGResourceGroup --kind OpenAI --sku S0 --location eastus
# GPT-3.5 모델 배포
az cognitiveservices account deployment create --name myOpenAI --resource-group myRAGResourceGroup --deployment-name gpt35turbo --model-name gpt-35-turbo --model-version "0301" --model-format OpenAI

3단계: Azure AI Search 설정

# Azure AI Search 서비스 생성
az search service create --name mySearchService --resource-group myRAGResourceGroup --sku Basic
# 인덱스 생성 (JSON 파일을 사용하여 인덱스 스키마 정의)
az search index create --name myIndex --service-name mySearchService --resource-group myRAGResourceGroup --definition index-schema.json

4단계: 데이터 처리 및 인덱싱

Python 스크립트를 사용하여 데이터를 처리하고 Azure AI Search에 인덱싱합니다.

import os
import json
import nest_asyncio
import asyncio
from azure.core.credentials import AzureKeyCredential
from azure.search.documents import SearchClient
from azure.search.documents.indexes import SearchIndexClient
from azure.search.documents.indexes.models import SearchIndex, SimpleField, SearchFieldDataType, SearchableField
from azure.ai.textanalytics import TextAnalyticsClient
from openai import AzureOpenAI

# Azure 서비스 연결 설정
TEXT_ANALYTICS_ENDPOINT = os.getenv("TEXT_ANALYTICS_ENDPOINT")
TEXT_ANALYTICS_KEY = os.getenv("TEXT_ANALYTICS_KEY")
OPENAI_ENDPOINT = os.getenv("OPENAI_ENDPOINT")
OPENAI_KEY = os.getenv("OPENAI_KEY")
SEARCH_ENDPOINT = os.getenv("SEARCH_ENDPOINT")
SEARCH_KEY = os.getenv("SEARCH_KEY")
INDEX_NAME = os.getenv("INDEX_NAME")

# Azure 서비스 클라이언트 초기화
text_analytics_client = TextAnalyticsClient(endpoint=TEXT_ANALYTICS_ENDPOINT, credential=AzureKeyCredential(TEXT_ANALYTICS_KEY))
openai_client = AzureOpenAI(api_key=OPENAI_KEY, api_version="2023-05-15", azure_endpoint=OPENAI_ENDPOINT)
index_client = SearchIndexClient(endpoint=SEARCH_ENDPOINT, credential=AzureKeyCredential(SEARCH_KEY))
search_client = SearchClient(endpoint=SEARCH_ENDPOINT, index_name=INDEX_NAME, credential=AzureKeyCredential(SEARCH_KEY))

def create_search_index():
    """
    Azure Cognitive Search 인덱스를 생성하는 함수입니다.
    """
    fields = [
        SimpleField(name="id", type=SearchFieldDataType.String, key=True),
        SearchableField(name="content", type=SearchFieldDataType.String),
        SearchableField(name="keywords", type=SearchFieldDataType.Collection(SearchFieldDataType.String)),
        SearchableField(name="metadata", type=SearchFieldDataType.String)
    ]
    index = SearchIndex(name=INDEX_NAME, fields=fields)
    try:
        index_client.create_index(index)
    except Exception as e:
        print(f"Index creation failed: {e}")

def chunk_document(content, max_chunk_size=500):
    """
    긴 문서를 최대 크기 이하의 청크로 분할하는 함수입니다.
    """
    words = content.split()
    chunks = []
    chunk = []
    chunk_size = 0
    for word in words:
        if chunk_size + len(word) + 1 > max_chunk_size:
            chunks.append(" ".join(chunk))
            chunk = []
            chunk_size = 0
        chunk.append(word)
        chunk_size += len(word) + 1
    if chunk:
        chunks.append(" ".join(chunk))
    return chunks

def process_and_index_document(document):
    """
    문서를 처리하고 Azure Cognitive Search에 인덱싱하는 함수입니다.
    """
    key_phrase_result = text_analytics_client.extract_key_phrases([document["content"]])
    keywords = key_phrase_result[0].key_phrases if key_phrase_result else []
    keywords_str = json.dumps(keywords)
    chunks = chunk_document(document["content"])
    for i, chunk in enumerate(chunks):
        search_client.upload_documents([{
            "id": f"{document['id']}-{i}",
            "content": chunk,
            "keywords": keywords_str,
            "metadata": json.dumps(document["metadata"])
        }])

5단계: Advanced RAG 파이프라인 구현

async def run_query(query):
    """
    주어진 쿼리에 대해 Azure Cognitive Search를 실행하는 비동기 함수입니다.
    """
    results = search_client.search(search_text=query, top=2)
    return list(results)

async def run_parallel_queries(queries):
    """
    여러 쿼리를 병렬로 실행하는 비동기 함수입니다.
    """
    tasks = [run_query(query) for query in queries]
    return await asyncio.gather(*tasks)

def bm25_score(result, query):
    """
    BM25 알고리즘을 사용하여 검색 결과의 점수를 계산하는 함수입니다.
    """
    content = result.get("content", "")
    return sum(content.lower().count(term.lower()) for term in query.split())

def rerank_results(results, query):
    """
    검색 결과를 BM25 점수를 기준으로 재정렬하는 함수입니다.
    """
    return sorted(results, key=lambda result: bm25_score(result, query), reverse=True)

def generate_context(results):
    """
    상위 3개의 검색 결과를 기반으로 문맥을 생성하는 함수입니다.
    """
    return "\n".join([result["content"] for result in results[:3]])

def generate_response(query, context):
    """
    주어진 쿼리와 문맥을 기반으로 OpenAI 모델을 사용하여 응답을 생성하는 함수입니다.
    """
    prompt = f"Context: {context}\n\nQuestion: {query}\n\nAnswer:"
    response = openai_client.chat.completions.create(
        model="gpt-35-turbo",
        messages=[{"role": "user", "content": prompt}]
    )
    return response.choices[0].message.content

def main():
    """
    전체 프로세스를 실행하는 메인 함수입니다.
    """
    create_search_index()

    documents = [
        {"id": "1", "content": "Azure Cognitive Services는 자연어 처리, 컴퓨터 비전, 음성 인식과 같은 강력한 AI 기능을 제공합니다.", "metadata": {"category": "AI", "topic": "Cognitive Services"}},
        {"id": "2", "content": "Azure Search는 애플리케이션에 풍부한 검색 환경을 구축할 수 있도록 지원하는 완전 관리형 검색 서비스입니다.", "metadata": {"category": "Search", "topic": "Azure Search"}},
        {"id": "3", "content": "Azure OpenAI Service는 비즈니스 워크플로우에 GPT-3와 같은 대형 언어 모델을 통합하여 요약 및 감정 분석과 같은 작업을 수행할 수 있게 합니다.", "metadata": {"category": "AI", "topic": "OpenAI Service"}},
        {"id": "4", "content": "Advanced RAG(Retrieval-Augmented Generation)는 문서 검색과 생성형 AI를 결합하여 보다 정확하고 맥락적으로 관련성 있는 응답을 제공합니다.", "metadata": {"category": "AI", "topic": "Advanced RAG"}},
        {"id": "5", "content": "Azure Blob Storage는 이미지, 비디오 및 문서를 포함한 비정형 데이터를 위한 확장 가능하고 비용 효율적인 스토리지 솔루션을 제공합니다.", "metadata": {"category": "Storage", "topic": "Blob Storage"}},
        {"id": "6", "content": "Azure Kubernetes Service(AKS)는 클라우드에서 Kubernetes를 사용하여 컨테이너화된 애플리케이션을 배포 및 관리하는 작업을 간소화합니다.", "metadata": {"category": "DevOps", "topic": "Kubernetes"}},
        {"id": "7", "content": "Azure Functions는 이벤트 중심 애플리케이션을 인프라 관리 없이 구축할 수 있는 서버리스 컴퓨팅 플랫폼을 제공합니다.", "metadata": {"category": "Serverless", "topic": "Azure Functions"}},
        {"id": "8", "content": "Azure Synapse Analytics는 조직이 대규모 데이터 통합 및 빅데이터 분석을 수행할 수 있도록 지원합니다.", "metadata": {"category": "Analytics", "topic": "Synapse"}},
        {"id": "9", "content": "Microsoft Power BI는 데이터를 시각화하고 대화형 대시보드를 생성하여 인사이트를 도출할 수 있도록 합니다.", "metadata": {"category": "Analytics", "topic": "Power BI"}},
        {"id": "10", "content": "Azure DevOps는 개발팀에 버전 관리, CI/CD 및 프로젝트 관리 도구를 제공합니다.", "metadata": {"category": "DevOps", "topic": "DevOps Tools"}},
        {"id": "11", "content": "Azure Security Center는 하이브리드 클라우드 워크로드 전반에 걸쳐 통합된 보안 관리와 고급 위협 방지 기능을 제공합니다.", "metadata": {"category": "Security", "topic": "Security Center"}},
        {"id": "12", "content": "Azure Monitor는 애플리케이션과 인프라에 대한 완전한 관측성을 제공하며 사전적인 문제 해결을 가능하게 합니다.", "metadata": {"category": "Monitoring", "topic": "Azure Monitor"}},
        {"id": "13", "content": "Azure Logic Apps는 워크플로우를 자동화하고 애플리케이션 및 서비스를 원활하게 통합할 수 있도록 합니다.", "metadata": {"category": "Automation", "topic": "Logic Apps"}},
        {"id": "14", "content": "Azure Machine Learning은 데이터 과학자가 기계 학습 모델을 대규모로 구축, 학습, 배포할 수 있도록 합니다.", "metadata": {"category": "AI", "topic": "Machine Learning"}},
        {"id": "15", "content": "Azure Virtual Machines는 Linux와 Windows를 지원하며 주문형 확장 가능한 컴퓨팅 자원을 제공합니다.", "metadata": {"category": "Compute", "topic": "Virtual Machines"}},
        {"id": "16", "content": "Azure Networking 솔루션에는 애플리케이션 연결성과 보안을 향상시키는 Virtual Network, Load Balancer 및 Application Gateway가 포함됩니다.", "metadata": {"category": "Networking", "topic": "Networking Solutions"}},
        {"id": "17", "content": "Microsoft Teams는 Azure Communication Services와 통합되어 원활한 커뮤니케이션 및 협업 기능을 제공합니다.", "metadata": {"category": "Collaboration", "topic": "Teams Integration"}},
        {"id": "18", "content": "Azure Policy는 조직이 Azure 환경 전반에서 규정을 준수하고 리소스를 관리할 수 있도록 합니다.", "metadata": {"category": "Governance", "topic": "Azure Policy"}},
        {"id": "19", "content": "Azure Backup은 데이터를 클라우드에서 간단하고 신뢰할 수 있는 방식으로 백업하고 복구할 수 있도록 지원합니다.", "metadata": {"category": "Backup", "topic": "Backup Solutions"}},
        {"id": "20", "content": "Azure Databricks는 빅데이터 처리 도구와 통합되어 고급 분석 및 기계 학습 기능을 제공합니다.", "metadata": {"category": "Analytics", "topic": "Databricks"}}
    ]


    for doc in documents:
        process_and_index_document(doc)

    user_query = "Advanced RAG의 장점은 무엇인가요?"
    prompt = f"다음의 Input과 관련된 대체 질문 3개를 작성해주세요.:\n\nInput: {user_query}"

    response = openai_client.chat.completions.create(
        model="gpt-35-turbo",
        messages=[{"role": "user", "content": prompt}],
        temperature=0.7
    )

    expanded_queries = [q.strip() for q in response.choices[0].message.content.split("\n") if q.strip()]
    queries = [user_query] + expanded_queries[:3]

    nest_asyncio.apply()
    parallel_searchresults = asyncio.run(run_parallel_queries(queries))
    reranked_results = [rerank_results(results, user_query) for results in parallel_searchresults]
    context = generate_context(reranked_results[0])  # 첫 번째 쿼리 결과만 사용
    response = generate_response(user_query, context)

    print("User Query:", user_query)
    print("Response:", response)

if __name__ == "__main__":
    main()

실제로 테스트를 위해 위의 코드를 실행해보면 아래와 같은 결과를 출력합니다.

참고로, AI Search로 병렬 처리를 구현하는 부분의 경우 SearchClient로 구현 시 에러가 발생하여 asyncio를 사용했지만 AI Search의 파티션을 늘릴 경우 병렬 처리가 가능할 것으로 보입니다. (다만 비용은 많이 발생할 수 있습니다.)

결론적으로 Advanced RAG 구현은 쿼리 확장, 병렬 검색, 결과 재순위화 등의 고급 기술을 포함하고 있습니다. 이를 통해 더 정확하고 관련성 높은 응답을 생성할 수 있습니다.

Advanced RAG 기술은 LLM의 성능을 크게 향상시키며, Azure의 강력한 서비스들을 활용하여 효과적으로 구현할 수 있습니다. 이 가이드에서 소개한 방법들을 기반으로 자신의 use case에 맞게 RAG 시스템을 최적화하고 확장할 수 있을 것입니다. 지속적인 모니터링과 개선을 통해 더욱 정교한 AI 애플리케이션을 개발할 수 있습니다

[미래를 향한 도전과 기회]

RAG 기술은 계속해서 발전하고 있으며, 앞으로 더 많은 혁신이 예상됩니다. 실시간 학습 능력을 갖춘 적응형 RAG 시스템, 더욱 정교한 추론 능력을 가진 AI 등이 연구되고 있습니다. 이러한 발전은 AI가 더욱 지능적이고 유용한 도구로 진화할 수 있음을 시사합니다.Azure 플랫폼은 이러한 최신 기술을 빠르게 도입하고 있어, 기업들이 항상 최첨단 AI 솔루션을 활용할 수 있도록 지원합니다. RAG 기술의 발전과 Azure의 강력한 지원은 AI 기반 정보 검색 및 생성 분야에 무한한 가능성을 열어주고 있습니다.결론적으로, Advanced RAG는 단순한 기술 혁신을 넘어 우리가 정보와 상호작용하는 방식을 근본적으로 변화시키고 있습니다. Azure와 같은 강력한 클라우드 플랫폼의 지원을 받아, 이제 기업들은 이 혁신적인 기술을 실제 비즈니스 문제 해결에 적용할 수 있게 되었습니다. 앞으로 RAG 기술이 어떻게 발전하고, 우리의 일상과 업무를 어떻게 변화시킬지 지켜보는 것은 매우 흥미로울 것입니다.

img
배정환 | Cloud Consulting Team

Microsoft MVP로 활동중이며, SK C&C에서 Azure/GCP 클라우드 컨설팅을 담당하고 있습니다.