Executive Snapshot

Aspect Detail
What it is A vendor-neutral orchestration pattern that runs OpenAI, Anthropic, and Google models as independent advocates, reconciles one answer, and gates it behind validation
Best for High-stakes AI output where single-model bias, a vendor outage, or lock-in is an unacceptable risk
Core moving parts A normalization layer, a parallel fan-out, an adjudicator, and a validation gate
Providers OpenAI (GPT-5.5), Anthropic (Claude Opus 4.8), Google (Gemini 3.1 Pro) — representative flagships, mid-2026
The catch Cost and latency multiply, and your data leaves your boundary three times instead of once
Assumes API access to all three providers and a way to validate the output programmatically

TL;DR

  • One vendor is one point of failure — for correctness, for uptime, and for negotiating leverage. Running GPT, Claude, and Gemini against the same brief turns a single opinion into a cross-checked decision.
  • The hard part is the normalization layer, not the model calls. Three SDKs, three request/response shapes, and three tool-calling formats have to collapse into one internal contract.
  • Adjudicate; never average. A designated judge (model or human) picks or synthesizes one answer and surfaces genuine conflicts instead of blending incompatible ones.
  • Diversity is the point. Different model families fail differently, so agreement is real signal and disagreement flags a decision worth a human's time.
  • Governance is the price of admission. Fanning one prompt to three external clouds triples cost, latency, and data exposure — redact first, gate hard, and fan out only when the stakes justify it.

Introduction

If you have read the Claude Code advocate/adjudicator tutorial, you have seen the pattern applied inside one vendor's tooling, using Opus and Sonnet as competing advocates. This piece lifts the same logic up a level: across vendors. The advocates become OpenAI's GPT, Anthropic's Claude, and Google's Gemini, each reached through its own API.

Why bother crossing vendor lines? Because two models from the same family share training lineage, and therefore share blind spots. Three models from three vendors are far less likely to be confidently wrong in the same way. Add the operational reality — outages, rate limits, sudden deprecations, price changes, shifting content policies — and cross-vendor orchestration stops being an academic exercise and becomes a resilience and governance strategy. This tutorial shows the architecture, the code seams that matter, the flowcharts that make it legible, and the governance trade-offs an IT team has to own before shipping it.

Prerequisites

  • API access to all three providers: an OpenAI key, an Anthropic key, and a Google Gemini (Google AI or Vertex) key, each in your secret store.
  • A programmatic validator — a test suite, a schema check, a policy linter — anything that returns pass/fail without a human.
  • A redaction or DLP step you can put in front of the fan-out. Sending proprietary context to three vendors is a decision, not an accident.
  • Comfort with async orchestration in your language of choice; the examples below are TypeScript for brevity.

1. Why diversify across vendors

Single-vendor AI is convenient and, for most tasks, entirely appropriate. The calculus changes when the output is high-stakes — a customer-facing decision, a code change to a load-bearing system, a compliance determination. There, three independent risks stack up against you: the model can be confidently wrong, the vendor can be unavailable when you need it, and building everything around one provider's quirks quietly erodes your ability to switch.

Cross-vendor orchestration attacks all three at once. Correctness: disagreement between GPT, Claude, and Gemini is a cheap early-warning system that a task is ambiguous or a model is hallucinating. Availability: if one provider returns a 529, the round still completes on the other two. Leverage: an abstraction that treats providers as interchangeable advocates is the same abstraction that lets you renegotiate, re-tier, or drop a vendor without a rewrite. That last point is the one procurement and architecture teams care about most, and it is a direct by-product of the normalization layer you have to build anyway.

Three independent AI models from different vendors deliberating on the same question
Three advocates, three vendors: independent model families rarely share the same blind spot, so agreement is signal and disagreement is a flag worth a human’s time.

2. The architecture at a glance

The shape is the same as the single-vendor pattern — fan out, reconcile, gate — with a redaction step in front and an adapter layer in the middle that hides three very different APIs behind one contract.

flowchart TD
    A["Brief or change request"] --> R["Redaction / DLP filter"]
    R --> F{"Fan out?"}
    F -->|"Low stakes"| S["Single model"]
    F -->|"High stakes"| P["Parallel advocates"]
    P --> O["OpenAI GPT-5.5"]
    P --> C["Anthropic Claude Opus 4.8"]
    P --> G["Google Gemini 3.1 Pro"]
    O --> N["Adapter layer: normalize to one contract"]
    C --> N
    G --> N
    S --> N
    N --> J["Adjudicator"]
    J -->|"One answer"| V{"Validation gate"}
    J -->|"Conflict"| H["Escalate to human"]
    V -->|"Fail (max 2 retries)"| J
    V -->|"Pass"| D["Accepted"]

Two design choices in that diagram matter more than the rest. The complexity gate (Fan out?) keeps you from paying triple for a task one model handles fine. The redaction filter sits before any external call, because everything downstream of it leaves your security boundary.

3. The normalization layer

This is where cross-vendor orchestration is won or lost. Each provider has its own SDK, authentication, message schema, and quirks — OpenAI's Responses API, Anthropic's Messages API, and Google's Gen AI SDK do not agree on so much as the name of the field that holds your prompt. The fix is a single internal contract that every advocate must satisfy, plus one thin adapter per provider.

Differently shaped connectors from three providers normalized into one uniform output
The normalization layer is the real work: three SDKs and response shapes collapse into one internal contract — which is also what makes the providers interchangeable.
// The one shape every provider must return, regardless of its native API.
export interface AdvocateResult {
  vendor: 'openai' | 'anthropic' | 'google'
  model: string
  answer: string        // the candidate implementation or decision
  rationale: string
  risks: string[]
  confidence: number    // self-reported 0..1 — a hint, never ground truth
}

export interface Advocate {
  vendor: AdvocateResult['vendor']
  model: string
  plan(brief: string): Promise<AdvocateResult>
}

// A shared system instruction keeps the brief identical across vendors.
const SYSTEM = 'You are one of several independent advocates. Return ONLY JSON ' +
  'matching {answer, rationale, risks[], confidence}. Do not assume facts you ' +
  'were not given. Bias toward the smallest sufficient answer.'

Now three adapters. Each is deliberately thin — its only job is to translate the native response into AdvocateResult via a shared parse() that enforces the JSON contract.

import OpenAI from 'openai'
const openai = new OpenAI() // reads OPENAI_API_KEY

export const gptAdvocate: Advocate = {
  vendor: 'openai',
  model: 'gpt-5.5', // GA flagship; the gpt-5.6 "Sol/Terra/Luna" tiers are in preview
  async plan(brief) {
    const r = await openai.responses.create({
      model: this.model,
      input: `${SYSTEM}\n\n${brief}`,
    })
    return parse('openai', this.model, r.output_text)
  },
}
import Anthropic from '@anthropic-ai/sdk'
const anthropic = new Anthropic() // reads ANTHROPIC_API_KEY

export const claudeAdvocate: Advocate = {
  vendor: 'anthropic',
  model: 'claude-opus-4-8', // most capable; claude-sonnet-5 for the balanced tier
  async plan(brief) {
    const r = await anthropic.messages.create({
      model: this.model,
      max_tokens: 4096,
      system: SYSTEM,
      messages: [{ role: 'user', content: brief }],
    })
    return parse('anthropic', this.model, r.content[0].text)
  },
}
import { GoogleGenAI } from '@google/genai'
const genai = new GoogleGenAI({}) // reads GEMINI_API_KEY

export const geminiAdvocate: Advocate = {
  vendor: 'google',
  model: 'gemini-3.1-pro', // reasoning flagship; gemini-3.5-flash for the fast tier
  async plan(brief) {
    const r = await genai.models.generateContent({
      model: this.model,
      contents: `${SYSTEM}\n\n${brief}`,
    })
    return parse('google', this.model, r.text)
  },
}

Notice the model IDs are pinned as constants, in one place. That is not a style preference — it is the seam that lets you re-tier every advocate from one file when a new model ships. And they ship constantly: OpenAI moved GPT-5.6 into preview the same quarter GPT-5.5 went GA, while Google shipped Gemini 3.5 Flash weeks after 3.1 Pro. Treat the model ID as configuration, verify it against each vendor's current model list before you deploy, and never hardcode it three layers deep.

4. Fanning out and adjudicating

With a uniform contract, the fan-out is boring — which is exactly what you want. Run the advocates in parallel and tolerate partial failure so one vendor's outage never sinks the round.

const advocates = [gptAdvocate, claudeAdvocate, geminiAdvocate]

// Promise.allSettled, not Promise.all: a single 529 must not fail the round.
const settled = await Promise.allSettled(advocates.map(a => a.plan(brief)))
const results = settled
  .filter((s): s is PromiseFulfilledResult<AdvocateResult> => s.status === 'fulfilled')
  .map(s => s.value)

if (results.length === 0) throw new Error('all providers failed — escalate to human')

Then the adjudicator decides. The decision tree is the heart of the pattern: agreement is adopted, a lone dissent is logged as a risk, and a genuine split is escalated — never averaged.

flowchart TD
    A["Three normalized candidate answers"] --> B{"Agree on the load-bearing decision?"}
    B -->|"Consensus"| C["Adopt the consensus answer"]
    B -->|"Majority, one dissent"| D["Adopt majority; log the dissent as a risk"]
    B -->|"Genuine split"| E["Do NOT average"]
    E --> F["Surface all positions to a human"]
    C --> G["Validation gate"]
    D --> G

You can implement the adjudicator as a rules engine (string/semantic equality plus a majority vote) or as a designated judge model given all three candidates and an ordered rubric — correctness first, then smallest sufficient answer, then risk coverage. Whichever you choose, encode one hard rule: on a load-bearing conflict, stop and surface every position. Averaging three answers produces a fourth that none of the models vetted and no human chose.

5. The validation gate

An adjudicated answer is still just the best opinion in the room. For anything consequential, put a deterministic gate after it — the same maker-checker discipline from the single-vendor pattern, unchanged by the fact that the answer came from three clouds.

async function accept(candidate: AdvocateResult): Promise<AdvocateResult> {
  for (let attempt = 1; attempt <= 3; attempt++) {
    const check = await runValidators(candidate.answer) // tests, schema, policy lint
    if (check.ok) return candidate
    if (attempt === 3) throw new Error(`gate failed after retries: ${check.summary}`)
    candidate = await repair(candidate, check.failures) // one bounded correction pass
  }
  throw new Error('unreachable')
}

Whether runValidators runs a unit suite, validates a JSON schema, or lints against a policy, the principle holds: the gate is code that returns pass/fail, not a prompt that asks a model to grade itself. Bound the correction loop — two retries, then escalate with the failing output — so a stubborn task fails loudly instead of looping forever.

6. The governance reality: cost, latency, and data exposure

Here is where IT ownership matters more than cleverness. Every vendor now ships the same three-tier lineup, so the honest comparison is by role, not by brand:

Provider Representative models (mid-2026) Tiering (flagship / balanced / fast) Standout trait
OpenAI GPT-5.5 (GA); GPT-5.6 Sol/Terra/Luna (preview) Sol / Terra / Luna Broad tooling, Responses API
Anthropic Claude Opus 4.8, Sonnet 5, Haiku 4.5 Opus / Sonnet / Haiku Strong coding, long-horizon reasoning
Google Gemini 3.1 Pro, Gemini 3.5 Flash Pro / Flash / Flash-Lite 1M-token context, native grounding

Three consequences follow directly from fanning out:

  • Cost multiplies. Three flagship calls cost roughly three times one. OpenAI's own preview tiers illustrate the spread that lets you manage it — GPT-5.6 lists Sol at $5/$30, Terra at $2.50/$15, and Luna at $1/$6 per million input/output tokens. Match the tier to the task; you rarely need three flagships. (Verify current pricing on each vendor's page — these numbers move.)
  • Latency is the slowest of the three, not the average. A parallel fan-out finishes when the last advocate returns. Set an aggressive per-advocate timeout and proceed with whatever came back.
  • Data exposure triples. This is the one that should reach a security review. The same proprietary context now crosses into three separate external boundaries.

That last point deserves a picture. Trace exactly where data leaves your control in a single round:

sequenceDiagram
    participant Orq as Orchestrator
    participant DLP as Redaction / DLP
    participant O as OpenAI
    participant An as Anthropic
    participant Go as Google
    participant Adj as Adjudicator
    Orq->>DLP: brief + context
    DLP-->>Orq: redacted brief
    par Fan-out — data leaves your boundary 3x
        Orq->>O: redacted brief
        Orq->>An: redacted brief
        Orq->>Go: redacted brief
    end
    O-->>Adj: candidate
    An-->>Adj: candidate
    Go-->>Adj: candidate
    Adj-->>Orq: one answer or CONFLICT

Mitigate deliberately: redact or tokenize before the fan-out, prefer each vendor's zero-retention or enterprise endpoints under a signed data-processing agreement, keep a data-residency matrix so you know which providers are even eligible for a given workload, and gate the fan-out itself so sensitive tasks never reach all three. Cross-vendor orchestration is a capability; treating the data egress as an afterthought is how it becomes an incident.

Proprietary data passing through a redaction checkpoint before reaching three external clouds
Fanning one prompt to three vendors triples data egress. Redact before the fan-out, prefer zero-retention endpoints, and gate sensitive tasks out entirely.

7. When one model is enough

The complexity gate is not a nicety — it is what makes the pattern affordable. Fan out only when a wrong answer is expensive and reasonable models might disagree. For a summarization job, a well-understood transformation, or a low-blast-radius change, one appropriately-tiered model is the correct engineering choice, and paying three vendors to concur is waste dressed up as rigor. Reserve the council for the decisions that earn it.

Troubleshooting

  • Adapters return different JSON shapes. Your parse() is too trusting. Validate every advocate's output against the contract and reject non-conforming responses rather than letting a malformed one reach the adjudicator.
  • One vendor is always the outlier. Check for an unfair brief — a prompt that leans on one provider's conventions (tool-calling format, system-prompt style) skews the comparison. The brief must be genuinely provider-neutral.
  • Costs ballooned. The complexity gate is being skipped, or every advocate is pinned to a flagship tier. Route low-stakes tasks to a single model and reserve the fan-out for high-stakes ones.
  • Latency spikes intermittently. You are waiting on the slowest advocate with no timeout. Add a per-advocate deadline and adjudicate over whoever responded.
  • A model ID started erroring. It was deprecated or renamed. This is why IDs live in one config block — re-tier there against the vendor's current model list, don't grep three files.
  • The adjudicator quietly blended a conflict. Reinforce the hard rule: a load-bearing split stops the pipeline and surfaces every position. A synthesized compromise nobody vetted is worse than an honest escalation.

Key Takeaways

  • Cross-vendor orchestration buys correctness, availability, and leverage at once — three uncorrelated risks retired by one abstraction.
  • The normalization layer is the real work. One internal contract plus thin per-provider adapters is what makes providers interchangeable.
  • Diversity is the feature. Different model families fail differently, so agreement is signal and disagreement is a flag, not noise.
  • Adjudicate, never average, and stop on genuine conflicts so a human owns the load-bearing call.
  • Keep the validation gate deterministic — code that returns pass/fail, bounded to two correction retries.
  • Own the governance. Cost and latency multiply and data exposure triples; redact first, tier deliberately, and gate the fan-out.
  • Pin model IDs as config and verify them before every deploy — the lineups change monthly, as GPT-5.6 and Gemini 3.5 both showed this year.

Next Steps

  • Build the normalization layer first and test it against all three providers with a fixed brief before you add any adjudication logic.
  • Add a redaction step and run a tabletop review of what actually reaches each vendor — treat it as a data-egress change, because it is.
  • Instrument per-advocate cost, latency, and agreement rate. If two providers agree 99% of the time on your workload, you may only need two.
  • Wire the complexity gate to a real signal (blast radius, reversibility, dollar value) so the fan-out fires only when it earns its cost.

Related Articles

  • Multi-Model AI Code Review in Claude Code: The Advocate/Adjudicator Pattern — the single-vendor version of this pattern, implemented on Claude Code's subagents, skills, and hooks.
  • Copilot for Microsoft 365: Rollout, Licensing, Data Readiness, and Governance — the same governance-first lens applied to a managed AI rollout.
  • What's New in Microsoft 365 Copilot: The Mid-2026 Roundup for IT Pros — how multi-model choice is arriving inside mainstream productivity tooling.
Thorsteinn Halldorsson Senior Cloud Engineer

Senior Cloud Engineer with 25+ years of hands-on experience across the datacenter-to-cloud stack: fiber SAN and disk storage, IBM/Lenovo blade and Dell/HP/Lenovo servers, Hyper-V and VMware clusters, and SQL and Remote Desktop Services (RDS) clusters. Deep in the Microsoft platform — Active Directory, PKI/certificate services, SQL, Power BI, Dynamics 365 Business Central (NAV) and AX (Axapta), Microsoft 365, Entra, and Intune — with a focus on Azure operations, FinOps, and applying AI tools like GitHub Copilot and Claude in real workflows. Writes practical, no-nonsense guides for IT professionals who need to ship real solutions.

Leave a Reply

Your email address will not be published. Required fields are marked *