Virtual Models: Manage AI Models Without Code Changes

Peter Bubenik · Vercel · · Source
Image for Introducing Virtual Models on AI Gateway

Step-by-Step Teaching

Step 1: The Problem Being Solved

Before understanding Virtual Models, understand why they exist.

The old way:

  • Your app code contains a model string like anthropic/claude-opus-5.5
  • That string lives inside your code
  • Switching models = editing code + redeploying your app
  • New models release ~10 per week, making this painful

The core pain points:

ProblemImpact
Model string is hardcodedEvery change needs a redeploy
No central controlDifferent apps may use inconsistent settings
Security settings can be overriddenCallers can bypass Zero Data Retention
Hard to track spend per taskReporting is messy

Step 2: What a Virtual Model Actually Is

Think of a Virtual Model as a named pointer that sits between your app and the real model.

Your App
    ↓
calls "vmc/coding-agent"   ← Virtual Model ID (never changes)
    ↓
AI Gateway reads config
    ↓
Routes to actual model (e.g., Claude, GPT-6) ← This CAN change

Key insight: Your app always calls the same ID. What that ID points to can change anytime, centrally, without touching your app.


Step 3: Core Concepts You Must Know

3.1 The Virtual Model ID

  • Always prefixed with vmc/
  • Example: vmc/coding-agent, vmc/storefront-assistant
  • This is what your code uses as the model string
  • It never needs to change in your code

3.2 What a Virtual Model Holds

A virtual model bundles together:

  • ✅ The actual model to use (e.g., anthropic/claude-opus-5.5)
  • ✅ Fallback models if the primary fails
  • ✅ Zero Data Retention enforcement
  • ✅ Provider priority/order
  • ✅ Tags for spend tracking
  • ✅ Speed/performance settings

3.3 Configuration Hierarchy (Important!)

Virtual model settings ALWAYS win over request-level settings

This means:

  • A caller cannot override fallbacks you configured centrally
  • A caller cannot disable Zero Data Retention if you set it
  • Tags from the virtual model replace tags sent in the request

Step 4: Creating a Virtual Model

Via CLI:

vercel ai-gateway virtual-models create coding-agent \
  --model anthropic/claude-opus-5.5 \
  --config '{"speed":"fast","zeroDataRetention":true}'

Breaking this down:

PartMeaning
coding-agentThe name (becomes vmc/coding-agent)
--modelThe real model it points to right now
--configSettings that travel with this virtual model

Via Dashboard:

  • Go to your team dashboard → Virtual Models page → Create

Step 5: Using a Virtual Model in Your App

import { streamText } from 'ai';

const result = streamText({
  model: 'vmc/coding-agent',        // ← Virtual model ID, not a real model
  prompt: 'Remove the deprecated API calls from this module.',
});

Notice: The model string is vmc/coding-agent, not anthropic/claude-opus-5.5. Your code never needs to know which real model is behind it.


Step 6: Updating a Virtual Model (The Key Benefit)

When a better model releases, you update the virtual model — not your app:

vercel ai-gateway virtual-models edit coding-agent \
  --model openai/gpt-6.1-sol

What happens next:

  • Every app calling vmc/coding-agent picks up the new model within minutes
  • Zero code changes
  • Zero redeployments
  • All your other settings (ZDR, fallbacks, tags) stay intact

⚠️ Exception: Provider-specific options (like Anthropic-only settings) stop applying when you switch to an OpenAI model. Always review provider options after switching providers.


Step 7: Designing Virtual Models Per Task

A best practice is one virtual model per task type, because different tasks have different needs:

vmc/support-triage      → cheap, fast model (runs 100s of times/hour)
vmc/legal-review        → expensive, high-reasoning model (runs rarely)
vmc/coding-agent        → balanced model for code tasks
vmc/storefront-assistant → reliable model with strong fallbacks

Why this matters:

  • You can optimize cost and quality independently per task
  • You can evolve each task's model separately
  • Spend reporting is clean and task-specific

Step 8: Safe Model Switching in Production

Never switch a production virtual model blindly. Use this pattern:

Step 1: Create a candidate virtual model
        vmc/coding-agent-candidate → new model

Step 2: Run your evaluations against the candidate

Step 3: If quality is good → update vmc/coding-agent to new model

Step 4: If quality drops → point vmc/coding-agent back to old model

This gives you a safe rollback path with no code changes needed at any step.


Step 9: Governance and Team Control

Virtual Models solve a security and governance problem too:

WhoCan Do
Platform/Security teamCreate and edit virtual models, enforce settings
Developers/AppsCall virtual model IDs, cannot override enforced settings

Practical examples of enforcement:

  • You set zeroDataRetention: true → callers cannot set it to false
  • You set provider fallback order → callers cannot change it
  • You set tags → caller tags are replaced, spend always lands correctly

Step 10: Summary Mental Model

WITHOUT Virtual Models:
[App Code: "anthropic/claude-opus-5.5"] → change model = redeploy

WITH Virtual Models:
[App Code: "vmc/coding-agent"] → never changes
        ↓
[AI Gateway Config] → change model here, anytime, centrally
        ↓
[Real Model: whatever you configured]

The three core benefits to remember:

  1. Flexibility — Switch models without touching code
  2. Control — Centrally enforce settings that callers can't override
  3. Visibility — Track spend and performance per task cleanly

Quick Reference Checklist

  • I understand why hardcoded model strings are a problem
  • I know a virtual model ID always starts with vmc/
  • I can create a virtual model using the CLI
  • I know virtual model settings override request-level settings
  • I understand the candidate pattern for safe production switching
  • I know provider-specific settings must be reviewed when switching providers
  • I can explain why one virtual model per task is a best practice

More to study