Vertex AI RAG 引擎:使用 Terraform 的高级 RAG——Chunking、Hybrid Search 与 Reranking 🧠
Source: Dev.to
概览
基本的分块可以让你得到一个演示。混合搜索、使用 Vertex AI 排序 API 的重新排序、元数据过滤以及调优的检索配置,可将 RAG Engine 语料库转变为生产系统。所有这些都通过 Terraform 和 Python SDK 进行连接。
在 RAG Post 1 中,我们部署了一个使用基本固定大小分块的 Vertex AI RAG Engine 语料库。它可以运行,但检索质量一般。用户提出细致的问题,却得到不完整或不相关的答案。
解决方案不是更好的生成模型,而是更好的检索。RAG Engine 支持:
- 分块调优
- 带可配置 α 权重的混合搜索
- 通过 Vertex AI 排序 API 进行重新排序
- 元数据过滤
- 向量距离阈值
基础设施层(Terraform)和运营层(Python SDK)各自处理不同的部分。本文介绍了能够产生差异的生产模式。 🎯
分块
RAG Engine 使用在 文件导入时 配置的固定大小 token 分块。与提供语义和层次策略作为原生选项的 AWS Bedrock 不同,GCP 的分块保持简洁,但提供对大小和重叠的细粒度控制。
Key insight: Chunking 配置在 per import operation 时设置,而不是在语料库层面。您可以重新导入相同文件并使用不同的分块设置,以测试哪种效果最佳。
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、问答对 | 256 | 30 | 小块 = 精确匹配 |
| 常规文档、指南 | 512 | 100 | 精度与上下文的平衡 |
| 长篇法律/技术文档 | 1024 | 200 | 保留交叉引用上下文 |
| 预处理内容(已分割) | 0 (使用原样) | 0 | 已在自然边界处分割 |
调优方法
- 从
chunk_size=512/overlap=100开始。 - 如果答案缺乏上下文 → 增加到
1024/200。 - 如果检索返回不相关的块 → 降低到
256/50。
重新导入并比较——语料库支持对同一文件进行多次导入,使用不同的配置。
嵌入速率
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) 将向量相似度与关键词(稀疏/基于 token)匹配相结合。α 参数控制两者的平衡。
| α 值 | 行为 |
|---|---|
| 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 # 略微倾向语义,但仍包含关键词匹配
),
)
# 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 引擎集成了两种重新排序方法。
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, # Retrieve wide
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‑来源文件,元数据来自文件的属性,或可以在导入操作期间通过编程方式设置。
向量距离阈值
vector_distance_threshold 参数在向模型传递之前过滤掉低相关性的块。只有向量距离 低于 阈值的块会被返回。
# 严格过滤 – 仅返回高度相关的块
filter = rag.Filter(vector_distance_threshold=0.3)
# 放宽过滤 – 捕获更广范围的块
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 |
|---|---|---|---|
| Chunking | Fixed‑size + Document Layout skill | Fixed, hierarchical, semantic, Lambda | Fixed‑size only |
| Hybrid search | BM25 + vector via RRF (built‑in) | Supported on OpenSearch | Alpha‑weighted dense/sparse |
| Semantic reranking | Built‑in transformer ranker (L2) | Cohere Rerank | Rank Service + LLM Ranker |
| Query decomposition | Agentic retrieval (native) | Native API parameter | Not built‑in |
| Metadata filtering | Filterable index fields + OData | JSON metadata files in S3 | Filter string at query time |
| Strictness control | 1‑5 scale on data source | Not built‑in | Vector distance threshold |
| Reranker score range | 0‑4 (calibrated, cross‑query consistent) | Model‑dependent | Model‑dependent |
Takeaway: GCP 的优势在于运营简便——托管向量数据库和按导入进行的分块使实验更快。AWS 提供了更多内置的分块策略和原生查询分解。
您的情境矩阵
| 用例 | 块大小 / 重叠 | 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! 💬