Azure 기반의 실제 RAG 파이프라인: Terraform을 이용한 내부 문서 Q&A (모델 불가지론적 방식)
요약
Azure AI Search와 Azure OpenAI를 활용하여 Terraform으로 자동화된 RAG 파이프라인을 구축하는 방법을 소개합니다. 모델 변경이 용이한 모델 불가지론적 설계를 통해 인프라 관리의 효율성을 극대화합니다.
핵심 포인트
- Terraform을 이용한 Azure 기반 RAG 인프라 프로비저닝 자동화
- 모델 변경 시 tfvars 수정만으로 대응 가능한 모델 불가지론적 설계
- Azure AI Search의 통합 벡터화를 통한 임베딩 코드 작성 최소화
- Blob Storage, AI Search, OpenAI를 결합한 엔드투엔드 아키텍처
모든 기업이 겪는 동일한 내부 문서 Q&A 문제를 Azure AI Search 및 Azure OpenAI를 통해 해결합니다. Terraform이 모든 것을 프로비저닝하며, 모델 배포는 tfvars에서 한 줄만 바꾸면 되고, 소규모 평가를 통해 운영 환경에 반영되기 전 회귀(regression)를 잡아냅니다.
모든 기업이 겪는 동일한 문제: 제품 문서, FAQ, 정책 PDF가 공유 드라이브에 쌓이고, 지원 요원들은 적절한 답변을 충분히 빠르게 찾지 못하며, 매주 동일한 질문이 동일한 Slack 채널에 올라옵니다. 이 포스트는 Azure AI Search와 Azure OpenAI를 결합하여 그 해결책인 내부 지식 Q&A를 구축합니다.
Azure의 패턴은 한 번의 호출로 세 가지 요소를 연결합니다: Blob Storage는 문서를 보관하고, Azure AI Search는 벡터 및 키워드 검색을 통해 문서를 인덱싱하며, 데이터 소스 매개변수가 포함된 Azure OpenAI의 chat completions API가 검색(retrieval), 재순위화(reranking), 생성(generation)을 함께 처리합니다. Terraform이 인프라를 프로비저닝합니다. 모델 배포는 변수(variable)로 처리되므로, 임베딩 모델(embedding model)이나 생성 모델(generation model)을 업그레이드하는 것은 코드 재작성이 아닌 tfvars 변경만으로 가능합니다. 🎯
🏗️ 아키텍처 (The Architecture)
Docs (PDF/HTML/TXT) → Blob Storage
↓
Azure AI Search (integrated vectorization + indexer)
...
Azure AI Search의 통합 벡터화(integrated vectorization)는 인덱서(indexer)가 데이터 수집(ingestion) 중에 임베딩 모델을 호출하고, 검색 시점에도 검색 텍스트를 위해 다시 호출함을 의미합니다. 임베딩 코드를 직접 작성할 필요가 없습니다.
🔧 Terraform: 전체 파이프라인 (The Full Pipeline)
모델 배포 - 설계 단계부터 모델 불가지론적 (Model-Agnostic by Design)
# variables.tf
variable "embedding_model" {
...
Azure OpenAI 배포 (Azure OpenAI Deployments)
# openai.tf
resource "azurerm_cognitive_account" "openai" {
...
소스 문서용 스토리지 (Storage for Source Documents)
# storage.tf
resource "azurerm_storage_account" "docs" {
...
Azure AI Search 서비스 (Azure AI Search Service)
# search.tf
resource "azurerm_search_service" "this" {
...
설정 브리지 - Terraform에서 SDK로 (Config Bridge - Terraform to SDK)
# config.tf
resource "local_file" "rag_config" {
...
AWS 및 GCP와 동일한 트릭입니다. 인덱스 이름은 임베딩 모델 (Embedding Model)과 그 차원 (Dimensions)으로부터 유도됩니다. 모델을 변경하면, 단 하나의 다운스트림 리소스도 건드리지 않고 자동으로 새로운 인덱스 이름을 얻을 수 있습니다.
🐍 인덱스, 스킬셋 및 인덱서 (SDK)
azurerm 프로바이더는 인덱스 스키마 (Index Schema), 스킬셋 (Skillset), 또는 인덱서 (Indexer)를 직접 관리하지 않습니다. 이들은 SDK 또는 REST API를 통해 생성되는 데이터 평면 (Data-plane) 객체입니다:
# app/setup_index.py
import json
from azure.search.documents.indexes import SearchIndexClient
...
인덱서 설정 (Blob Storage에서 데이터를 가져오고, 청킹 (Chunking) 및 벡터화 (Vectorization)를 자동으로 수행)은 벡터라이저 (Vectorizer)를 참조하는 스킬셋과 함께 SearchIndexerClient를 사용하는 동일한 패턴을 따릅니다. 인덱스 이름에 임베딩 모델 버전이 포함되어 있으므로, 모델을 업그레이드할 때마다 이 스크립트를 안전하게 다시 실행할 수 있습니다.
🐍 파이프라인 쿼리 (모델 불가지론적 생성)
# app/query.py
from openai import AzureOpenAI
import json
...
tfvars에서 generation_model.name을 gpt-4.1에서 gpt-4.1-mini 또는 미래의 모델로 교체하고, terraform apply를 실행하면 끝입니다. 코드 변경은 필요 없습니다. data_sources 파라미터가 의도 추출 (Intent Extraction), 하이브리드 검색 (Hybrid Retrieval), 시맨틱 재순위화 (Semantic Reranking), 그리고 생성을 한 번의 호출로 처리합니다.
📐 환경 설정
# environments/dev.tfvars
environment = "dev"
search_sku = "basic"
...
⚠️ 임베딩 차원 정직성 검사 (Embedding Dimension Honesty Check)
다른 두 클라우드와 동일한 현실입니다. 벡터 필드 (Vector Field)의 차원 수는 필드가 생성될 때 고정됩니다. 기존 필드의 vector_search_dimensions를 변경할 수 없으며, 설령 차원 수가 우연히 일치하더라도 벡터 공간 (Vector Spaces)이 서로 비교 불가능하기 때문에 일반적으로 하나의 필드에 서로 다른 모델의 임베딩을 섞어서는 안 됩니다.
설정의 index_name에는 이미 임베딩 모델과 차원 수가 포함되어 있으므로, 업그레이드 패턴은 GCP에서 사용되는 것과 동일합니다:
tfvars파일에서embedding_model을 변경합니다.terraform apply실행 - 새로운index_name을 계산하며, 현재 실행 중인 인덱스에는 영향을 주지 않습니다.setup_index.py재실행 - 새로운 인덱스와 인덱서 (indexer)를 생성하고, 동일한 Blob 컨테이너로부터 다시 벡터화 (re-vectorize)를 수행합니다.- 아래의 평가 (evaluation) 과정을 두 인덱스 모두에 대해 실행합니다.
- 새 인덱스가 승리하면
query.py가 새 인덱스를 가리키도록 설정한 후, 기존 인덱스를 삭제합니다.
🧪 소규모 평가: 업그레이드가 실제로 도움이 되었는가?
# evaluate.py
from app.query import ask
...
먼저 설정을 기존 인덱스와 모델로 지정하여 점수를 캡처한 다음, 새 인덱스로 다시 지정하여 비교하십시오. 실제 지원 티켓에서 추출한 10~20개의 실제 질문이면 프로덕션에 반영되기 전에 성능 저하 (regression)를 포착하기에 충분합니다.
⚠️ 주의 사항 및 팁
데이터 평면 (Data-plane) 객체는 Terraform 상태 (state) 외부에 존재합니다. 인덱스 스키마 (index schemas), 스킬셋 (skillsets), 인덱서 (indexers)는 azurerm이 아닌 SDK에 의해 관리됩니다. Terraform은 영구적인 인프라를 소유하고, SDK는 콘텐츠와 스키마를 소유합니다.
시맨틱 랭킹 (Semantic ranking)에는 Standard 계층이 필요합니다. basic SKU는 개발용으로는 작동하지만, 시맨틱 재순위화 (semantic reranking)를 위해서는 standard 계층과 명시적인 시맨틱 구성 (semantic configuration)이 필요합니다. 프로덕션용 tfvars에 이 비용을 반영하십시오.
공유 프라이빗 링크 (Shared private links)는 Azure 대 Azure 연결에서만 작동합니다. 임베딩 모델이 Azure OpenAI 외부에서 실행되는 경우, 인덱서 연결은 공용 인터넷을 통해 이루어져야 합니다.
모델 변경뿐만 아니라 콘텐츠 변경 후에도 인덱서를 재실행하십시오. Blob Storage의 새 문서는 인덱서가 스케줄에 따라 또는 수동으로 트리거되어 다시 실행될 때까지 인덱스에 나타나지 않습니다.
실제 내부 질문을 위한 모델 불가지론적 (model-agnostic) RAG 파이프라인으로, 임베딩을 업그레이드하는 정직한 프로세스와 업그레이드가 실제로 도움이 되었는지 확인하는 내장된 방법을 제공합니다. 인프라에는 Terraform을, 인덱스에는 SDK를 사용하며, 모든 전환 (cutover) 전에 평가를 수행합니다. 🔍
이 내용이 도움이 되었나요? 더 많은 RAG 심층 분석을 위해 팔로우하세요! 💬
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기