Vertex AI (Generative AI)
Concept
Vertex AI is Google Cloud's unified ML and generative-AI platform. For GenAI it provides managed foundation models (the Gemini family and others via Model Garden), embeddings, grounding, safety controls, evaluation, and โ through the Google Gen AI SDK โ a consistent API for text, multimodal input, streaming, structured output, and function/tool calling.
Problem it solves. It lets you build GenAI applications without hosting models yourself, with enterprise controls: IAM, VPC-SC, data residency, private connectivity, safety filters, and observability. It unifies model access, embeddings, vector search, and evaluation behind one platform.
โ When to use
- You want managed, enterprise-governed access to frontier models on GCP
- You need embeddings + vector search + grounding in one platform
- You require VPC-SC, data residency, or private connectivity
โ When not to
- You need a specific model only available elsewhere and can't route to it
- Ultra-low-latency, fully offline inference on-device
- A trivial rules-based task where an LLM is overkill and adds cost/latency
Use cases
- Text generation, summarization, extraction, classification
- Multimodal understanding (text + image/PDF/video)
- Embeddings for semantic search and RAG
- Function/tool calling for agents
- Batch inference over large datasets
Production use cases
- A grounded RAG assistant with citations
- An LLM gateway that routes across models with fallback and caching
- Multimodal document processing feeding a data pipeline
Limitations
- Per-model context-window, region availability, and quota limits
- Token cost and latency scale with prompt/response size
- Model versions change โ pin versions and keep a config-driven registry
- Safety filters can block outputs; you must handle blocked responses
Amazon Bedrock / SageMaker
Azure OpenAI / Azure ML
Interactive architecture
Accessible text description
flowchart LR APP[FastAPI on Cloud Run] --> ADC[ADC / Workload Identity] ADC --> VX[Vertex AI endpoint] VX --> GEM[Gemini model] VX --> SAFE[Safety filters] APP --> EMB[Embeddings API] EMB --> VS[(Vector Search / AlloyDB AI)] APP --> TRC[Cloud Trace + token metrics] VX -.tool call.-> TOOL[Your functions / RAG retriever] classDef gcp fill:#e8f0fe,stroke:#4285f4,color:#174ea6; class APP,VX,GEM,EMB,VS,TRC,TOOL,ADC,SAFE gcp;
How it works
Your app authenticates with ADC and calls a Vertex AI endpoint. Requests are authorized by IAM, run through safety filters, and billed by input/output tokens (or per-character/per-image depending on the model). Streaming, tool calling, and structured output are request options, not separate services.
- 1 ยท App builds a requestYour service (Gen AI SDK)
You construct a prompt with system instructions, optional tools, and generation config (temperature, max tokens, response schema).
๐ฐ Larger prompts = more input tokens - 2 ยท AuthenticationADC / Workload Identity
The SDK uses Application Default Credentials; on Cloud Run/GKE this is a workload identity โ no keys.
โ 403 if the SA lacks roles/aiplatform.user ๐ Audit logs - 3 ยท Vertex AI authorizes & routesVertex AI
IAM authorizes the call; the request routes to the requested model + version in the requested region.
โ 404/400 on unknown model/version; 429 on quota ๐ Quota metrics - 4 ยท Safety & generationModel + safety filters
The model generates (optionally streaming). Safety filters may block or annotate output; tool calls pause generation for your app to execute the tool and return results.
โ Blocked responses (safety), truncation at max tokens ๐ Finish reason, safety ratings - 5 ยท Response handlingYour service
Parse text or structured JSON, record input/output token counts, attach citations if grounding was used, and stream to the client.
๐ Token counts, latency, cost per response
Hands-on example
Cloud Console
- Cloud Console โ Vertex AI โ enable the Vertex AI API
- Open Vertex AI Studio to prototype prompts and copy generated code
- Model Garden โ browse available managed and open models
- Grant the runtime service account roles/aiplatform.user
Code
PROJECT=my-project
gcloud config set project "$PROJECT"
gcloud services enable aiplatform.googleapis.com
# Grant the Cloud Run runtime SA permission to call Vertex AI
gcloud projects add-iam-policy-binding "$PROJECT" \
--member "serviceAccount:rag-api-sa@$PROJECT.iam.gserviceaccount.com" \
--role roles/aiplatform.user
# Quick REST smoke test with an access token (model id is configuration-driven)
LOC=us-central1
MODEL=${GENAI_MODEL:-gemini-2.0-flash} # keep model ids in config, not hard-coded
curl -s -X POST \
"https://$LOC-aiplatform.googleapis.com/v1/projects/$PROJECT/locations/$LOC/publishers/google/models/$MODEL:generateContent" \
-H "Authorization: Bearer $(gcloud auth print-access-token)" \
-H "Content-Type: application/json" \
-d '{"contents":[{"role":"user","parts":[{"text":"Explain Cloud Run in one sentence."}]}]}' # pip install google-genai pydantic
# Model ids are configuration-driven โ never hard-code them permanently.
import os
from pydantic import BaseModel
from google import genai
from google.genai import types
MODEL = os.getenv("GENAI_MODEL", "gemini-2.0-flash")
# Vertex AI mode uses ADC (no API keys) โ set these env vars in Cloud Run:
# GOOGLE_GENAI_USE_VERTEXAI=true, GOOGLE_CLOUD_PROJECT, GOOGLE_CLOUD_LOCATION
client = genai.Client()
# 1) Simple + streaming generation
def stream_answer(question: str):
for chunk in client.models.generate_content_stream(
model=MODEL,
contents=question,
config=types.GenerateContentConfig(temperature=0.2, max_output_tokens=1024),
):
yield chunk.text
# 2) Structured JSON output enforced by a schema
class Answer(BaseModel):
summary: str
confidence: float
def structured(question: str) -> Answer:
resp = client.models.generate_content(
model=MODEL, contents=question,
config=types.GenerateContentConfig(
response_mime_type="application/json",
response_schema=Answer,
),
)
# Token accounting for cost tracking
print("tokens:", resp.usage_metadata.total_token_count)
return Answer.model_validate_json(resp.text)
# 3) Function / tool calling
def get_weather(city: str) -> str:
return f"Sunny in {city}"
def with_tools(question: str) -> str:
resp = client.models.generate_content(
model=MODEL, contents=question,
config=types.GenerateContentConfig(tools=[get_weather]), # SDK auto-invokes
)
return resp.text
# 4) Embeddings for RAG
def embed(texts: list[str]) -> list[list[float]]:
r = client.models.embed_content(
model=os.getenv("EMBED_MODEL", "text-embedding-005"), contents=texts)
return [e.values for e in r.embeddings] # See the gcloud tab for a full curl example; the endpoint pattern is:
# POST https://{LOCATION}-aiplatform.googleapis.com/v1/projects/{PROJECT}/locations/{LOCATION}/publishers/google/models/{MODEL}:generateContent resource "google_project_service" "vertex" {
service = "aiplatform.googleapis.com"
disable_on_destroy = false
}
resource "google_project_iam_member" "vertex_user" {
project = var.project_id
role = "roles/aiplatform.user"
member = "serviceAccount:${google_service_account.rag_api.email}"
} Verify
- Run the REST smoke test โ expect a JSON candidate with generated text
- Confirm usage_metadata token counts appear in your logs
- Trigger a tool call and confirm your function executed
- Send a prompt that should be blocked and confirm you handle the safety finish reason
Cleanup
- Delete any Vector Search indexes/endpoints (these bill continuously)
- Remove batch prediction jobs and their output
- Revoke temporary IAM bindings created for testing
Troubleshooting
- 403 โ runtime SA missing roles/aiplatform.user
- 429 โ hitting per-model quota; request an increase or add backoff/routing
- Empty/blocked output โ check finish_reason and safety ratings; adjust prompt or thresholds
- 404 model โ wrong model id/version/region; verify against Model Garden and your registry
- High latency โ stream responses, trim context, and cache repeated prompts
Production considerations
Scalability
Vertex AI scales as a managed API; your bottleneck is per-model quota. Route across models/regions and add backoff to absorb spikes.
Availability
Multi-region model availability varies; design fallback to an alternate model/region and degrade gracefully.
Performance
Stream for perceived latency; keep prompts lean; cache embeddings and repeated prompts. Measure time-to-first-token and total latency.
Reliability
Wrap calls with timeouts, retries (respect 429/503 with backoff+jitter), and a fallback model. Handle blocked/truncated responses explicitly.
Networking
Use Private Service Connect for private access and VPC-SC to prevent exfiltration; keep prompts/data in-region for residency.
Security
ADC/Workload Identity, least-privilege IAM, safety settings, PII handling in logs, and grounding to reduce hallucination.
Monitoring
Record input/output tokens, cost per response, latency percentiles, finish reasons, and safety ratings; trace tool calls end to end.
Cost
Token-based; optimize with smaller models where adequate, prompt trimming, caching, batch inference, and routing. Track cost per query / per user.
Quotas
Per-model, per-region token and request quotas โ plan and request increases before launch.
Data protection
Understand data-usage/residency terms; keep sensitive data in approved regions and apply DLP where needed.
Disaster recovery
Multi-region fallback for model access; your data tier (vector store) needs its own backup/replication.
Multi-region
Deploy the app per region and route to the nearest available model region; watch cross-region egress and latency.
What interviewers expect you to know
Definitions
- Foundation model, context window, tokens, embeddings, grounding
- Function/tool calling vs structured output; streaming vs batch inference
Design questions
- Design a resilient GenAI API: retries, fallback model, streaming, token/cost tracking
- How would you ground responses and add citations to reduce hallucination?
- How do you keep model selection configurable as models are deprecated?
Trade-offs
- Larger model (quality) vs smaller/flash (latency & cost)
- Managed Gemini vs open model on GKE (control/portability vs ops)
- Long context vs retrieval (RAG) for grounding
Failure scenarios
- 429 quota storms during a launch โ how do you absorb them?
- Safety filter blocks a needed response โ how do you handle it?
- A model version is deprecated โ how does your system keep running?
Common follow-ups
- How do you track and control token cost per tenant?
- How do you secure prompts/outputs that may contain PII?
- How do you evaluate output quality over time?
Misconceptions
- 'Bigger context always beats RAG' โ cost/latency and lost-in-the-middle say otherwise
- 'Model ids are stable' โ pin versions and keep a config-driven registry
- 'Safety is optional' โ you must handle blocked responses in code
๐ฌ A strong answer
I'd put a thin gateway in front of Vertex AI so model choice is config-driven, with timeouts, backoff on 429/503, and a fallback model. I'd stream responses for perceived latency, enforce structured output with a schema where the app needs JSON, and record input/output tokens per request for cost-per-response tracking. To reduce hallucination I'd ground with RAG and return citations, handle safety finish-reasons explicitly, and keep credentials on Workload Identity with roles/aiplatform.user only. Private Service Connect + VPC-SC protect the data path.
Common mistakes
- Hard-coding model ids so the app breaks when a version is deprecated
- Using API keys instead of ADC/Workload Identity
- Ignoring usage_metadata, so token cost is invisible until the bill arrives
- Not handling blocked/truncated responses (finish_reason)
- Sending huge contexts when retrieval would be cheaper and more accurate
- No fallback model or backoff, so a 429 spike takes the feature down
- Logging full prompts/outputs with PII and no redaction
- Leaving Vector Search index endpoints deployed (continuous billing)
Comparisons
Managed Gemini vs open model on GKE
| Dimension | Gemini (Vertex AI) | Open model on GKE |
|---|---|---|
| Ops | None โ managed API | You run GPUs, serving, scaling |
| Cost model | Per token | Per GPU-hour (fixed while running) |
| Control/portability | Managed, limited | Full control, portable weights |
| Best for | Most apps, fast start | Custom/fine-tuned models, data-locality, steady load |
Verdict. Start managed; self-host on GKE only when control, a specific model, or steady GPU economics demand it.
Knowledge check
How should a Cloud Run service authenticate to Vertex AI in production?
Which change most directly reduces token cost for a high-volume summarization endpoint without changing the model?
You set response_mime_type='application/json' with a Pydantic response_schema. What do you get back?