Skip to content

Vertex RAG Engine

Gunpal Jain edited this page Nov 15, 2026 · 3 revisions

Vertex RAG Engine

The Vertex AI RAG Engine lets you build knowledge bases (corpora), import your documents into them, and ground Gemini responses on that data (Retrieval-Augmented Generation). In the SDK, VertexRagManager manages the RAG Engine configuration, corpora and files, and the retrieval tool connects a corpus to a GenerativeModel.

Platform Support
Vertex AI Yes, in regional locations only (for example us-central1).
Gemini API No. Use File Search instead. UseVertexRetrievalTool throws NotSupportedException outside Vertex AI.

Prerequisites

  • NuGet packages: Google_GenerativeAI, plus Google_GenerativeAI.Auth for GoogleServiceAccountAuthenticator
  • A Google Cloud project with the Vertex AI API enabled.
  • Serverless mode (the mode for new projects, see below) also needs the Vector Search API (vectorsearch.googleapis.com) enabled.
  • Credentials with enough IAM permissions, for example Vertex AI User and Vertex AI RAG Data Service Agent (plus Secret Manager Secret Accessor if you use Pinecone/Weaviate API keys stored in Secret Manager).
  • A regional location. The RAG Engine is not available in the global location. Use a region such as us-central1, with a model that is served in that region.
using GenerativeAI;
using GenerativeAI.Authenticators;
using GenerativeAI.Types.RagEngine;   // VertexRagManager and the RAG types

var vertexAi = new VertexAI(projectId, "us-central1",
    authenticator: new GoogleServiceAccountAuthenticator("path/to/service-account.json"));
// or another authenticator, e.g. ADC. See the Authentication page.

VertexRagManager ragManager = vertexAi.CreateRagManager();

RAG Engine configuration: Serverless vs Spanner

The RAG Engine stores its data in a RAG-managed database, configured per project and location:

  • Serverless mode (RagManagedDbConfig.CreateServerless()): no provisioned database, billed per use. New projects must use Serverless mode. It requires the Vector Search API (vectorsearch.googleapis.com).
  • Spanner mode: a provisioned Spanner database, with the Scaled tier (RagManagedDbConfig.CreateSpannerScaled()) or the Basic tier (RagManagedDbConfig.CreateSpannerBasic()).

Read, change or switch the configuration on VertexRagManager:

// Current mode
RagEngineConfig? current = await ragManager.GetEngineConfigAsync();
bool isServerless = current?.RagManagedDbConfig?.Serverless != null;
Console.WriteLine(isServerless ? "Serverless" : "Spanner");

// Switch to Serverless (waits for the change to complete)
await ragManager.SwitchToServerlessModeAsync();

// Or set any configuration explicitly
await ragManager.UpdateEngineConfigAsync(new RagEngineConfig
{
    RagManagedDbConfig = RagManagedDbConfig.CreateSpannerBasic()
});

Warning: setting RagManagedDbSpanner.Unprovisioned disables the RAG Engine and permanently deletes all of its data.

Corpora

A corpus is a knowledge base. CreateCorpusAsync waits for the create operation and returns the RagCorpus.

// RAG-managed vector store (the default)
RagCorpus? corpus = await ragManager.CreateCorpusAsync("product-docs", "Manuals and FAQs");
Console.WriteLine(corpus?.Name);   // projects/.../locations/us-central1/ragCorpora/...

Other overloads use an external vector database: Pinecone (RagVectorDbConfigPinecone), Weaviate (RagVectorDbConfigWeaviate), Vertex AI Feature Store or Vertex AI Vector Search. Pinecone and Weaviate take the Secret Manager resource name of the database API key (projects/{PROJECT_NUMBER}/secrets/{SECRET_ID}/versions/{VERSION_ID}). Every overload takes an optional embeddingModelName.

var list = await ragManager.ListCorporaAsync(pageSize: 10);
foreach (var c in list?.RagCorpora ?? new List<RagCorpus>())
    Console.WriteLine($"{c.Name} {c.DisplayName} {c.RagFilesCount}");

var one = await ragManager.GetCorpusAsync(corpus!.Name!);
var updated = await ragManager.UpdateCorpusAsync(one!);
await ragManager.DeleteRagCorpusAsync(corpus.Name!);

Newly created corpora can take a while to appear in list results, especially in Serverless mode. If you list right after creating, retry for a short time, or keep the name returned by CreateCorpusAsync.

Upload and import files

Upload a local file:

RagFile? file = await ragManager.UploadLocalFileAsync(
    corpus.Name!, "docs/manual.pdf",
    displayName: "Manual",
    description: "Router X user manual",
    progressCallback: p => Console.WriteLine($"{p:F0}%"));

A brand-new corpus can briefly reject uploads; retry after a few seconds if that happens.

Import files from Cloud Storage, Google Drive, Slack, Jira or SharePoint. Imports are long-running operations; wait for them with AwaitForLongRunningOperation:

var operation = await ragManager.ImportFilesAsync(corpus.Name!, new GcsSource
{
    Uris = new List<string> { "gs://my-bucket/docs/" }
});

if (operation?.Name != null)
    await ragManager.AwaitForLongRunningOperation(operation.Name);   // default timeout: LongRunningOperationTimeout (5 min)

Each ImportFilesAsync overload takes optional RagFileParsingConfig and RagFileTransformationConfig arguments. For full control, pass an ImportRagFilesRequest.

Manage files:

var files = await ragManager.ListFilesAsync(corpus.Name!);
foreach (var f in files?.RagFiles ?? new List<RagFile>())
    Console.WriteLine($"{f.Name} {f.DisplayName}");

var ragFile = await ragManager.GetFileAsync(fileName);
await ragManager.DeleteFileAsync(fileName);

Ground generation on a corpus

Pass the corpus name as corpusIdForRag when you create the model. It adds a Vertex retrieval tool for that corpus:

var model = vertexAi.CreateGenerativeModel(
    "gemini-2.5-flash",     // a model served in your region (the newest models are global-only)
    corpusIdForRag: corpus.Name);

var result = await model.GenerateContentAsync("What does the manual say about factory resets?");
Console.WriteLine(result.Text());

Tune retrieval with ragRetrievalConfig:

var model = vertexAi.CreateGenerativeModel(
    "gemini-2.5-flash",
    corpusIdForRag: corpus.Name,
    ragRetrievalConfig: new RagRetrievalConfig
    {
        Filter = new RagRetrievalConfigFilter { VectorDistanceThreshold = 0.5 },
        HybridSearch = new RagRetrievalConfigHybridSearch { Alpha = 0.5f }
    });

You can also add the tool to an existing model with model.UseVertexRetrievalTool(corpusName, retrievalConfig).

Error handling

  • API errors are thrown as GenerativeAI.Exceptions.ApiException (ErrorCode, ErrorStatus, ErrorMessage).
    • A region/location error or FAILED_PRECONDITION usually means you are using global, or the RAG Engine is not available in that region. Use a regional location such as us-central1.
    • In Serverless mode, a permission or "API not enabled" error can mean the Vector Search API is not enabled.
  • A failed long-running operation (create corpus, engine config change, AwaitForLongRunningOperation) throws GenerativeAI.Exceptions.VertexAIException with the operation's error.
  • NotSupportedException from UseVertexRetrievalTool when the model is not on Vertex AI.
try
{
    var corpus = await ragManager.CreateCorpusAsync("docs", null);
}
catch (ApiException ex)
{
    Console.WriteLine($"{ex.ErrorCode} {ex.ErrorStatus}: {ex.ErrorMessage}");
}
catch (VertexAIException ex)
{
    Console.WriteLine($"Operation failed: {ex.Message}");
}

Important considerations

  • Cost: imports, embeddings and queries are billed; Spanner mode also bills for provisioned capacity.
  • Latency: larger corpora and external vector databases can add latency.
  • Keep data fresh: re-import changed documents to keep answers accurate.

Official documentation: https://cloud.google.com/vertex-ai/generative-ai/docs/rag-overview and https://cloud.google.com/vertex-ai/generative-ai/docs/rag-engine/switching-modes

Related pages

Clone this wiki locally