Vertex AI RAG 엔진 Terraform으로 구현하는 고급 RAG: Chunking, Hybrid Search, 그리고 Reranking 🧠
I’m happy to translate the article for you, but I’ll need the full text of the post (excluding the source line you’ve already provided). Could you please paste the content you’d like translated? Once I have it, I’ll keep the source link at the top unchanged and translate the rest into Korean while preserving all formatting, markdown, and technical terms.
Overview
Basic chunking gets you a demo. Hybrid search, reranking with the Vertex AI Ranking API, metadata filtering, and tuned retrieval configs turn a RAG Engine corpus into a production system. All wired through Terraform and the Python SDK.
In RAG Post 1 we deployed a Vertex AI RAG Engine corpus with basic fixed‑size chunking. It works, but retrieval quality is mediocre. Your users ask nuanced questions and get incomplete or irrelevant answers back.
The fix isn’t a better generation model – it’s better retrieval. RAG Engine supports:
- Chunking tuning
- Hybrid search with configurable α weighting
- Reranking via the Vertex AI Ranking API
- Metadata filtering
- Vector‑distance thresholds
The infrastructure layer (Terraform) and the operational layer (Python SDK) each handle different parts. This post covers the production patterns that make the difference. 🎯
청크 나누기
RAG Engine은 파일 가져오기 시점에 설정되는 고정 크기 토큰 청크를 사용합니다. AWS Bedrock(시맨틱 및 계층적 전략을 기본 옵션으로 제공)과 달리 GCP는 청크 나누기를 단순하게 유지하면서도 크기와 오버랩에 대한 세밀한 제어를 제공합니다.
핵심 인사이트: 청크 설정은 코퍼스가 아니라 가져오기 작업당 지정됩니다. 동일한 파일을 다른 청크 설정으로 다시 가져와 어떤 설정이 가장 좋은지 테스트할 수 있습니다.
from vertexai import rag
# Production chunking config
rag.import_files(
corpus_name=corpus.name,
paths=["gs://company-docs-prod/policies/"],
transformation_config=rag.TransformationConfig(
chunking_config=rag.ChunkingConfig(
chunk_size=512,
chunk_overlap=100,
)
),
max_embedding_requests_per_min=900,
)
권장 청크 크기
| 문서 유형 | 청크 크기 | 오버랩 | 이유 |
|---|---|---|---|
| 짧은 FAQ, Q&A 쌍 | 256 | 30 | 작은 청크 = 정밀 매칭 |
| 일반 문서, 가이드 | 512 | 100 | 정밀도와 컨텍스트의 균형 |
| 긴 법률/기술 문서 | 1024 | 200 | 교차 참조 컨텍스트 유지 |
| 전처리된 콘텐츠 (이미 분할됨) | 0 (그대로 사용) | 0 | 자연 경계에서 이미 분할됨 |
튜닝 접근법
chunk_size=512/overlap=100로 시작합니다.- 답변에 컨텍스트가 부족하면
1024/200으로 늘립니다. - 검색 결과가 관련 없는 청크를 반환하면
256/50으로 줄입니다.
재수입하고 비교하세요 – 코퍼스는 동일 파일에 대해 서로 다른 설정으로 여러 번 가져오기를 지원합니다.
Embedding Rate
max_embedding_requests_per_min 매개변수는 프로덕션 환경에서 매우 중요합니다. 이 매개변수가 없으면 대규모 가져오기가 임베딩 모델 할당량을 소진시켜 중간에 실패할 수 있습니다. 임베딩 모델의 QPM 제한보다 아래로 설정하십시오.
# Terraform outputs feed into SDK config
# environments/prod.tfvars sets the quota boundary
embedding_qpm_rate = 900 # Leave headroom below 1000 QPM limit
하이브리드 검색
기본적으로, RAG Engine은 순수 벡터(밀집) 검색을 사용합니다. 하이브리드 검색은 벡터 유사도와 키워드(희소/토큰‑기반) 매칭을 Reciprocal Rank Fusion (RRF)으로 결합합니다. α 파라미터가 균형을 제어합니다.
| α 값 | 동작 |
|---|---|
| 1.0 | 순수 벡터 / 의미 검색 |
| 0.5 | 동일 가중치 (기본값) |
| 0.0 | 순수 키워드 검색 |
from vertexai import rag
from vertexai.generative_models import GenerativeModel, Tool
rag_retrieval_config = rag.RagRetrievalConfig(
top_k=10,
filter=rag.Filter(
vector_distance_threshold=0.3,
),
hybrid_search=rag.HybridSearch(
alpha=0.6 # Slightly favor semantic, but include keyword matching
),
)
# Retrieve‑only (no generation)
response = rag.retrieval_query(
rag_resources=[rag.RagResource(rag_corpus=corpus.name)],
text="What is policy ABC-123 regarding overtime?",
rag_retrieval_config=rag_retrieval_config,
)
α를 조정할 때
- 특정 코드, ID, 정확한 용어 (예: 정책 번호, 제품 SKU, 오류 코드) → 0.3–0.4 정도로 α를 낮춥니다.
- 개념에 대한 자연어 질문 → 0.6–0.8 범위의 α를 유지합니다.
재정렬
유사도와 관련성은 동일하지 않습니다. 상위 K개의 청크를 더 깊은 질의‑문서 이해를 통해 재정렬(재채점)하면 결과가 크게 개선될 수 있습니다. RAG Engine은 두 가지 재정렬 방식을 통합합니다.
1️⃣ Google‑호스팅 순위 서비스
Google의 사전 학습된 순위 모델을 Discovery Engine API를 통해 사용합니다. 서비스를 활성화해야 합니다:
# rag/apis.tf
resource "google_project_service" "discovery_engine" {
project = var.project_id
service = "discoveryengine.googleapis.com"
disable_dependent_services = false
disable_on_destroy = false
}
검색 시점에 구성합니다:
rag_retrieval_config = rag.RagRetrievalConfig(
top_k=15, # 넓게 검색
ranking=rag.Ranking(
rank_service=rag.RankService(
model_name="semantic-ranker-default@latest"
)
),
hybrid_search=rag.HybridSearch(alpha=0.6),
)
response = rag.retrieval_query(
rag_resources=[rag.RagResource(rag_corpus=corpus.name)],
text="What are the penalties for late contract delivery?",
rag_retrieval_config=rag_retrieval_config,
)
패턴: 하이브리드 검색으로 15개의 청크를 검색하고, 순위 서비스를 통해 재채점하여 가장 관련성이 높은 결과를 반환합니다. 이 “넓게 검색하고, 좁게 재정렬” 접근법은 직접 5개 청크만 검색하는 경우보다 일관되게 더 좋은 성능을 보입니다.
2️⃣ LLM‑기반 순위기
LLM을 사용해 결과를 재정렬합니다. 지연 시간이 더 길지만 미묘한 관련성 판단을 처리할 수 있습니다.
rag_retrieval_config = rag.RagRetrievalConfig(
top_k=10,
ranking=rag.Ranking(
llm_ranker=rag.LlmRanker(
model_name="gemini-2.0-flash"
)
),
)
response = rag.retrieval_query(
rag_resources=[rag.RagResource(rag_corpus=corpus.name)],
text="What are the penalties for late contract delivery?",
rag_retrieval_config=rag_retrieval_config,
)
트레이드‑오프
- 순위 서비스 – 빠르고 비용이 저렴합니다.
- LLM 순위기 – 복잡하고 모호한 질의에 더 적합합니다.
먼저 순위 서비스를 사용하고, 관련성이 낮은 특정 질의 패턴에 대해서만 LLM 순위기로 전환하십시오.
메타데이터 필터링
메타데이터 필터를 사용하여 특정 문서 카테고리로 검색 범위를 제한합니다. 메타데이터는 쿼리 시 필터 문자열로 적용됩니다.
rag_retrieval_config = rag.RagRetrievalConfig(
top_k=10,
filter=rag.Filter(
vector_distance_threshold=0.3,
metadata_filter="department = 'legal' AND year >= 2024"
),
hybrid_search=rag.HybridSearch(alpha=0.6),
)
response = rag.retrieval_query(
rag_resources=[rag.RagResource(rag_corpus=corpus.name)],
text="What changed in the",
)
(예시 쿼리가 원본 자료에서 잘려 있습니다; 필요에 따라 전체 질문으로 교체하세요.)
메타데이터 & 임포트
메타데이터는 파일 임포트 시 첨부됩니다. GCS‑sourced files의 경우, 메타데이터는 파일의 속성에서 가져오거나 임포트 작업 중 프로그래밍 방식으로 설정할 수 있습니다.
벡터‑거리 임계값
vector_distance_threshold 매개변수는 모델에 도달하기 전에 낮은 관련성 청크를 필터링합니다. 임계값 아래인 벡터 거리를 가진 청크만 반환됩니다.
# Strict filtering – only highly relevant chunks
filter = rag.Filter(vector_distance_threshold=0.3)
# Relaxed filtering – cast a wider net
filter = rag.Filter(vector_distance_threshold=0.7)
튜닝 가이드
| 시작점 | 조일 때 | 완화할 때 |
|---|---|---|
| 0.5 | 관련 없는 청크가 나타남 → 0.3으로 낮춤 | 결과가 너무 적음 → 0.7으로 올림 |
팁: 재정렬을 사용할 때는 완화된 임계값(예: 0.7)을 설정하여 더 많은 후보를 통과시키고, 그 후 재정렬기가 관련성에 따라 정렬하도록 하세요.
인프라 계층 (Terraform)
Terraform 구성은 필요한 API, GCS 버킷, IAM 및 Vertex AI RAG 엔진을 프로비저닝합니다.
# rag/main.tf
resource "google_project_service" "required_apis" {
for_each = toset([
"aiplatform.googleapis.com",
"discoveryengine.googleapis.com",
"storage.googleapis.com",
])
project = var.project_id
service = each.value
disable_dependent_services = false
disable_on_destroy = false
}
resource "google_vertex_ai_rag_engine_config" "this" {
region = var.region
rag_managed_db {
type = var.rag_db_tier
}
depends_on = [google_project_service.required_apis]
}
resource "google_storage_bucket" "rag_docs" {
name = "${var.project_id}-${var.environment}-rag-docs"
location = var.region
uniform_bucket_level_access = true
lifecycle_rule {
condition { age = var.doc_retention_days }
action { type = "Delete" }
}
}
환경별 변수
dev.tfvars
rag_db_tier = "BASIC"
doc_retention_days = 90
embedding_qpm_rate = 500
# Retrieval config (passed to SDK)
chunk_size = 300
chunk_overlap = 50
retrieval_top_k = 5
alpha = 0.5
distance_threshold = 0.5
reranker = "none"
prod.tfvars
rag_db_tier = "SCALED"
doc_retention_days = 2555
embedding_qpm_rate = 900
# Retrieval config (passed to SDK)
chunk_size = 512
chunk_overlap = 100
retrieval_top_k = 15
alpha = 0.6
distance_threshold = 0.3
reranker = "semantic-ranker-default@latest"
기능 비교
| Feature | Azure AI Search | AWS Bedrock KB | GCP RAG Engine |
|---|---|---|---|
| 청크 처리 | Fixed‑size + Document Layout skill | Fixed, hierarchical, semantic, Lambda | Fixed‑size only |
| 하이브리드 검색 | BM25 + vector via RRF (내장) | OpenSearch에서 지원 | Alpha‑weighted dense/sparse |
| 시맨틱 재정렬 | Built‑in transformer ranker (L2) | Cohere Rerank | Rank Service + LLM Ranker |
| 쿼리 분해 | Agentic retrieval (네이티브) | 네이티브 API 파라미터 | 내장되지 않음 |
| 메타데이터 필터링 | Filterable index fields + OData | S3의 JSON 메타데이터 파일 | 쿼리 시점에 필터 문자열 |
| 엄격성 제어 | 1‑5 스케일 on data source | 내장되지 않음 | Vector distance threshold |
| 재정렬 점수 범위 | 0‑4 (보정됨, 쿼리 간 일관성) | Model‑dependent | Model‑dependent |
요약: GCP의 장점은 운영상의 단순성입니다 – 관리형 벡터 DB와 임포트당 청크 처리가 실험을 더 빠르게 합니다. AWS는 더 많은 내장 청크 전략과 네이티브 쿼리 분해 기능을 제공합니다.
Your Situation Matrix
| 사용 사례 | 청크 크기 / 겹침 | Alpha | 재정렬기 | 거리 임계값 |
|---|---|---|---|---|
| 시작하기, 혼합 문서 | 512 / 100 | 0.5 | None | 0.5 |
| 사용자가 코드/ID로 검색 | 256 / 50 | 0.3 | Rank Service | 0.5 |
| 긴 기술 문서 | 1024 / 200 | 0.7 | Rank Service | 0.3 |
| 고정밀 프로덕션 | 512 / 100 | 0.6 | Rank Service | 0.3 |
| 복잡하고 모호한 쿼리 | 512 / 100 | 0.6 | LLM Ranker | 0.5 |
추천: 기본 구성으로 “고정밀 프로덕션” 행을 시작하십시오. Discovery Engine API를 활성화하고 Rank Service 재정렬을 사용한 뒤, 거기서 미세 조정하십시오.
Series Context
- Post 1: Vertex AI RAG Engine – Basic Setup 🔍
- Post 2 (you’re here): Advanced RAG – Chunking, Hybrid Search, Reranking 🧠
Your RAG pipeline just leveled up: hybrid search for precision, Rank Service reranking for relevance, metadata filtering for scope, and vector‑distance thresholds for noise control – all driven by Terraform variables per environment.
Found this helpful? Follow for the full RAG Pipeline with Terraform series! 💬
시리즈 개요
- Post 1: Vertex AI RAG Engine – Basic Setup 🔍
- Post 2 (여기서): Advanced RAG – Chunking, Hybrid Search, Reranking 🧠
RAG 파이프라인이 한 단계 업그레이드되었습니다: 정밀도를 위한 하이브리드 검색, 관련성을 위한 Rank Service 재정렬, 범위를 위한 메타데이터 필터링, 그리고 노이즈 제어를 위한 벡터 거리 임계값 — 모두 환경별 Terraform 변수에 의해 제어됩니다.
이 내용이 도움이 되었나요? 전체 Terraform와 함께하는 RAG 파이프라인 시리즈를 팔로우하세요! 💬