将 Vector Search 2.0 与 RAG 搭配使用

本页面介绍了 Gemini Enterprise Agent Platform 上的 RAG 引擎如何使用 Gemini Enterprise Agent Platform Vector Search 2.0,这是一款 Cloud de Confiance by S3NS 产品,可作为全面的存储和检索系统,用于存储和管理文档的向量表示法。然后,Gemini Enterprise Agent Platform Vector Search 2.0 会根据文档与给定查询的语义相似度检索相关文档。

RAG 将为您管理 Vector Search 2.0 集合,您将拥有对项目中 Vector Search 2.0 集合的完整访问权限。

选择 RAG 后端

在 Gemini Enterprise Agent Platform 上使用 RAG 引擎时,您可以为 RAG 语料库选择不同的后端存储选项。下表总结了主要区别:

后端选项 底层技术 由 RAG 引擎管理 项目中的数据可见性 CMEK 支持
RagManagedVertexVectorSearch Gemini Enterprise Agent Platform Vector Search 2.0 完全由 Google 管理。 在您的 Cloud de Confiance by S3NS 项目中可见 否
VertexVectorSearch Gemini Enterprise Agent Platform Vector Search 1.0 用户需要自行设置、管理和清理 Vector Search 1.0 实例。 在您的 Cloud de Confiance by S3NS 项目中可见 否
RagManagedDb Spanner 完全由 Google 管理。 在项目中不直接可见 是

选择 RagManagedVertexVectorSearch,即可获享最新功能、自动化管理以及 Vector Search 2.0 数据的透明度。如果 CMEK 支持是严格要求,请考虑使用 RagManagedDb,但请注意,您无法直接查看后端数据库。

启用 Vector Search API

如需使用 RAG 托管的 Gemini Enterprise Agent Platform Vector Search,您需要先启用 Vector Search API。

使用 RagManagedVertexVectorSearch 创建 RAG 语料库

此代码示例演示了如何使用 RagManagedVertexVectorSearch 创建 RAG 语料库。

Python

from vertexai.preview import rag
import vertexai

PROJECT_ID = YOUR_PROJECT_ID
LOCATION = YOUR_RAG_ENGINE_LOCATION
DISPLAY_NAME = YOUR_RAG_CORPUS_DISPLAY_NAME

# Initialize Agent Platform API once per session
vertexai.init(project=PROJECT_ID, location=LOCATION)

vector_db = rag.RagManagedVertexVectorSearch()
rag_corpus = rag.create_corpus(
    display_name=DISPLAY_NAME, backend_config=rag.RagVectorDbConfig(vector_db=vector_db))

REST

执行以下变量替换操作:

  • PROJECT_ID:您的项目 ID。
  • LOCATION:处理请求的区域。
  • CORPUS_DISPLAY_NAME:RAG 语料库的显示名称。
PROJECT_ID=PROJECT_ID
LOCATION=LOCATION
CORPUS_DISPLAY_NAME=CORPUS_DISPLAY_NAME

curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
https://${LOCATION}-aiplatform.googleapis.com/v1beta1/projects/${PROJECT_ID}/locations/${LOCATION}/ragCorpora \
-d '{
      "display_name" : '\""${CORPUS_DISPLAY_NAME}"\"',
      "vector_db_config": {
        "rag_managed_vertex_vector_search": {}
      }
    }'

将数据导入到 RagManagedVertexVectorSearch 中

您可以使用 ImportRagFiles API 或 UploadRagFile API 将数据导入 RagManagedVertexVectorSearch。

如需将本地文件上传到 RAG 语料库,请参阅上传 RAG 文件。如需将数据导入 RAG 语料库,请参阅以下代码示例,其中演示了如何从 Cloud Storage 导入数据。如需了解支持的数据源,请参阅支持 RAG 的数据源。

Python

from vertexai.preview import rag
import vertexai

PROJECT_ID = YOUR_PROJECT_ID
LOCATION = YOUR_RAG_ENGINE_LOCATION
CORPUS_ID = YOUR_CORPUS_ID
PATHS = ["gs://my_bucket/my_files_dir"]

# Initialize Agent Platform API once per session
vertexai.init(project=PROJECT_ID, location=LOCATION)

corpus_name = f"projects/{PROJECT_ID}/locations/{LOCATION}/ragCorpora/{CORPUS_ID}"
# This is a non blocking call.
response = await rag.import_files_async(
    corpus_name=corpus_name,
    paths=PATHS,
)

# Wait for the import to complete.
await response.result()

REST

GCS_URI=GCS_URI

curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
https://${LOCATION}-aiplatform.googleapis.com/v1beta1/projects/${PROJECT_ID}/locations/${LOCATION}/ragCorpora/${CORPUS_ID}/ragFiles:import \
-d '{
  "import_rag_files_config": {
    "gcs_source": {
      "uris": '\""${GCS_URI}"\"',
      },
  }
}'

为语料库创建索引

RAG 引擎会为每个语料库创建一个 Vector Search 2.0 集合,但不会在该集合上创建索引。在您创建索引之前,每次检索都是暴力 KNN 扫描。

暴力扫描比索引搜索慢,并且 KNN 仅在包含最多 100,000 个数据对象的集合上运行。RAG 引擎会为每个数据对象存储一个分块,因此,一旦语料库超出该限制,检索就会失败,直到索引存在。

不要为每个语料库都编制索引。索引在自己的服务基础架构上运行,只要索引存在,无论是否被查询,都会产生费用。如需确定哪些语料库需要索引,请参阅确定要将哪些语料库编入索引。

索引创建完成后,检索功能会自动使用该索引。语料库不会发生变化,您也无需再次导入数据。

如果您要为多个语料库编制索引,请编写循环脚本:没有批量创建路径。并发索引操作受配额限制,因此请串行或小批量创建索引。如需了解详情,请参阅配额。

准备工作

创建索引需要对集合拥有 vectorsearch.indexes.create 权限,而统计其数据对象需要 vectorsearch.dataObjects.query 权限。Vector Search Admin (roles/vectorsearch.admin) 角色包含这两项权限;Vector Search Index Writer (roles/vectorsearch.indexWriter) 角色仅授予第一项权限。还必须在项目中启用 Vector Search API。

查找语料库 ID

在您的项目中,每个语料库都只有一个名为 vertex-rag-RAG_CORPUS_ID 的集合。列出您的语料库以获取其 ID。

将 PROJECT_ID 替换为您的项目 ID:

PROJECT_ID=PROJECT_ID
LOCATION=us-central1

curl -X GET \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
"https://${LOCATION}-aiplatform.googleapis.com/v1beta1/projects/${PROJECT_ID}/locations/${LOCATION}/ragCorpora?pageSize=100"

每个语料库 name 末尾的数字部分是 RAG_CORPUS_ID。每个语料库还会在 vectorDbConfig.ragManagedVertexVectorSearch.collectionName 中报告完整的集合资源名称。

响应最多会列出 100 个语料库,如果您省略 pageSize,则最多会列出 25 个。 如果响应包含 nextPageToken,请将该值作为 pageToken 传递,以提取下一页。

如果您已经知道要编入索引的 RAG_CORPUS_ID,请改为提取该语料库。响应会携带相同的 collectionName:

curl -X GET \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
"https://${LOCATION}-aiplatform.googleapis.com/v1beta1/projects/${PROJECT_ID}/locations/${LOCATION}/ragCorpora/RAG_CORPUS_ID"

决定要将哪些语料库编入索引

对于每个语料库,统计其集合中的数据对象数量。传递一个空的 filter 以统计整个集合:

COLLECTION_ID=vertex-rag-RAG_CORPUS_ID

curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
"https://vectorsearch.googleapis.com/v1/projects/${PROJECT_ID}/locations/${LOCATION}/collections/${COLLECTION_ID}/dataObjects:aggregate" \
-d '{"aggregate": "COUNT", "filter": {}}'

计数在 aggregateResults 中返回:

{
  "aggregateResults": [
    {
      "count": 95217
    }
  ]
}

如果满足以下任一条件,请为该语料库创建索引:

  • 计数接近或超过 100,000。此限制统计的是数据对象数量,而不是文件数量,因此包含少量大文件的语料库仍可能远超此限制。
  • 以您的查询速率,检索速度太慢。索引搜索比暴力扫描更快,并且随着集合的增长,差距会越来越大。

否则,请勿将语料库编入索引,以免产生投放费用。如果索引后续有所增长,您可以稍后再添加。

查看 Collection 架构

RAG 引擎会使用以下架构创建每个集合。在指定索引字段和过滤条件字段时,请使用这些名称。

字段 种类 说明
text_embedding 密集向量 块嵌入。这是您要编入索引的字段。维度数量与语料库嵌入模型一致。
corpus_id 字符串 RAG 语料库的 ID。
file_id 字符串 块来源 RAG 文件的 ID。
chunk_id 字符串 数据块的 ID。
chunk_data 字符串 文本块。
chunk_data_type 字符串 分块数据的类型。
file_original_uri 字符串 源文件的原始 URI。
rag_metadata 字符串 用户为数据块提供的元数据。

选择索引设置

UpdateIndex 仅更改显示名称、说明、标签和副本数,因此如需更改本部分中的任何设置,您必须删除索引并创建一个新索引。

索引字段:将其设置为 text_embedding,这是集合架构中唯一的向量字段。

距离指标:将其设置为余弦。RAG 引擎始终在其检索请求中发送 COSINE_DISTANCE,而 Vector Search 2.0 会拒绝指标与索引不匹配的检索请求。如果您省略该指标,则默认值为 DOT_PRODUCT,因此在未指定该指标的情况下创建的索引会破坏该语料库的检索。RAG Engine 会将失败报告为 FAILED_PRECONDITION,并显示消息 Failed to process Rag Managed Vertex Vector Search response.,该消息不会将指标标识为原因。拼写因界面而异:REST 正文采用 COSINE_DISTANCE,gcloud CLI 标志采用 cosine-distance。

基础设施:将索引保留在默认的性能优化型基础设施上,因为存储优化型基础设施不支持余弦距离。索引在专用服务基础架构上运行,只要存在,就会计费。在 v1 上,min_replica_count 和 max_replica_count 均默认为 2,因此默认情况下,索引由两个副本提供,并且不会自动扩缩。如需了解详情,请参阅集合索引。

过滤字段:仅将 filter_fields 设置为 file_id。这是 RAG Engine 在检索时过滤的唯一字段,并且仅在检索请求将搜索限制为特定文件时才会这样做。具体而言,对于给定集合中的每个数据对象,corpus_id 都具有相同的值,因此对其进行过滤没有任何好处。

元数据过滤也不需要额外的过滤字段。当检索请求设置 ragRetrievalConfig.filter.metadataFilter 时,RAG 引擎会先根据文件元数据解析过滤条件,将结果转换为一组匹配的 RAG 文件 ID,然后将该组 ID 作为相同的 file_id 过滤条件发送到 Vector Search。将 rag_metadata 添加到 filter_fields 会增加索引大小,但不会改变检索结果。

存储字段:将 store_fields 留空。RAG 引擎会在每次检索时请求所有数据字段,这不符合内嵌服务条件,因此无论如何都会从后备数据库中读取分块数据。store_fields 中列出的字段会被推送到索引中,并计入其大小,因此设置这些字段会增加费用,而不会改变检索。

创建索引

Python

执行以下变量替换操作:

  • PROJECT_ID:您的项目 ID。
  • RAG_CORPUS_ID:要编入索引的 RAG 语料库的 ID。
from google.cloud import vectorsearch_v1

client = vectorsearch_v1.VectorSearchServiceClient()

index = vectorsearch_v1.Index(
    index_field="text_embedding",
    distance_metric=vectorsearch_v1.DistanceMetric.COSINE_DISTANCE,
    filter_fields=["file_id"],
)
request = vectorsearch_v1.CreateIndexRequest(
    parent="projects/PROJECT_ID/locations/us-central1/collections/vertex-rag-RAG_CORPUS_ID",
    index_id="vertex-rag-RAG_CORPUS_ID-index",
    index=index,
)

operation = client.create_index(request=request)

# Wait for the result (note this may take up to several minutes).
operation.result()

REST

执行以下变量替换操作:

  • PROJECT_ID:您的项目 ID。
  • RAG_CORPUS_ID:要编入索引的 RAG 语料库的 ID。
PROJECT_ID=PROJECT_ID
RAG_CORPUS_ID=RAG_CORPUS_ID
LOCATION=us-central1
COLLECTION_ID=vertex-rag-${RAG_CORPUS_ID}
INDEX_ID=${COLLECTION_ID}-index

curl -X POST \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
"https://vectorsearch.googleapis.com/v1/projects/${PROJECT_ID}/locations/${LOCATION}/collections/${COLLECTION_ID}/indexes?indexId=${INDEX_ID}" \
-d '{
      "index_field": "text_embedding",
      "distance_metric": "COSINE_DISTANCE",
      "filter_fields": ["file_id"]
    }'

gcloud

执行以下变量替换操作:

  • PROJECT_ID:您的项目 ID。
  • RAG_CORPUS_ID:要编入索引的 RAG 语料库的 ID。
gcloud vector-search collections indexes create vertex-rag-RAG_CORPUS_ID-index \
  --collection=vertex-rag-RAG_CORPUS_ID \
  --index-field=text_embedding \
  --distance-metric=cosine-distance \
  --filter-fields=file_id \
  --location=us-central1 \
  --project=PROJECT_ID

除非您传递 --async,否则该命令会一直阻塞,直到操作完成。

轮询完成情况

创建索引会返回一个长时间运行的操作:

{
  "name": "projects/PROJECT_ID/locations/us-central1/operations/operation-1770302393524-64a14a54fa197-0dea326c-5a90efda",
  "metadata": {
    "@type": "type.googleapis.com/google.cloud.vectorsearch.v1.OperationMetadata",
    "createTime": "2026-02-05T14:39:53.558308609Z",
    "target": "projects/PROJECT_ID/locations/us-central1/collections/vertex-rag-RAG_CORPUS_ID/indexes/vertex-rag-RAG_CORPUS_ID-index",
    "verb": "create",
    "apiVersion": "v1"
  },
  "done": false
}

使用该响应中的名称轮询操作:

OPERATION_NAME=OPERATION_NAME

curl -X GET \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
"https://vectorsearch.googleapis.com/v1/${OPERATION_NAME}"

当 done 为 true 时,response 字段表示索引已成功构建,error 字段会给出失败原因。构建索引需要几分钟时间,对于大型语料库,则需要更长时间。

如需列出项目和位置中的操作,请运行以下命令:

curl -X GET \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
"https://vectorsearch.googleapis.com/v1/projects/PROJECT_ID/locations/us-central1/operations"

如需检查现有索引,请运行以下命令:

gcloud vector-search collections indexes describe vertex-rag-RAG_CORPUS_ID-index \
  --collection=vertex-rag-RAG_CORPUS_ID \
  --location=us-central1 \
  --project=PROJECT_ID

如需删除索引(您必须执行此操作才能更改其任何永久设置),请运行以下命令。在构建替换索引之前,检索会回退到暴力 KNN 扫描,如果语料库超过 100,000 个分块,则会完全失败。

gcloud vector-search collections indexes delete vertex-rag-RAG_CORPUS_ID-index \
  --collection=vertex-rag-RAG_CORPUS_ID \
  --location=us-central1 \
  --project=PROJECT_ID

后续步骤