ArquitecturaExperto40 min
Orquestación Multi-Modelo
Claude + GPT-4 + Gemini · Routing inteligente · Fallbacks · Consensus
Multi-modeloRoutingFallbacks
✓ Guía gratuita · Acceso completo
Mapa rápido · salta al paso que te interese
01
Por qué multi-modelo: cuando un solo LLM no alcanza
Cada modelo tiene fortalezas y debilidades. Claude es mejor en razonamiento largo. GPT-4 es mejor en código. Gemini es mejor en multimodal. Usarlos juntos te da lo mejor de cada uno.
| Modelo | Fortaleza | Debilidad | Precio relativo |
|---|---|---|---|
| Claude Opus 4 | Razonamiento, análisis largo | Latencia | Alto |
| Claude Sonnet 4 | Balance general | Creatividad | Medio |
| GPT-4.1 | Código, structured output | Instrucciones complejas | Medio |
| GPT-4.1-mini | Velocidad, costo | Tareas complejas | Bajo |
| Gemini 2.0 Flash | Multimodal, velocidad | Consistencia | Bajo |
| Gemini 2.0 Pro | Contexto largo (2M) | Disponibilidad | Medio |
4 razones para multi-modelo
- Redundancia: Si Claude cae, GPT responde
- Optimización de costos: Modelo barato para tareas simples
- Calidad: Cada modelo para lo que hace mejor
- Validación: Múltiples opiniones reducen errores
02
4 patrones de orquestación
Cada patrón resuelve un problema diferente. Elegilos según tu caso de uso.
Un clasificador decide qué modelo usar basado en la tarea.
Router inteligente
type TaskType = 'code' | 'analysis' | 'creative' | 'simple' | 'multimodal'
const MODEL_MAP: Record<TaskType, string> = {
code: 'gpt-4.1', // GPT es mejor en código
analysis: 'claude-opus-4', // Claude es mejor en análisis
creative: 'claude-sonnet-4',
simple: 'gpt-4.1-mini', // Barato para tareas simples
multimodal: 'gemini-2.0-flash',
}
async function classifyTask(prompt: string): Promise<TaskType> {
// Clasificador barato con GPT-4.1-mini
const response = await openai.chat.completions.create({
model: 'gpt-4.1-mini',
messages: [{
role: 'user',
content: `Clasificá esta tarea en una categoría.
Categorías: code, analysis, creative, simple, multimodal
Solo responde con la categoría, nada más.
Tarea: ${prompt.slice(0, 500)}`
}],
max_tokens: 10,
})
return response.choices[0].message.content as TaskType
}
async function routedQuery(prompt: string): Promise<string> {
const taskType = await classifyTask(prompt)
const model = MODEL_MAP[taskType]
// Llamar al modelo correcto
if (model.startsWith('claude')) {
return callClaude(model, prompt)
} else if (model.startsWith('gpt')) {
return callOpenAI(model, prompt)
} else {
return callGemini(model, prompt)
}
}03
Implementación completa
Clase orquestador que combina todos los patrones.
lib/orchestrator.ts
import Anthropic from '@anthropic-ai/sdk'
import OpenAI from 'openai'
import { GoogleGenerativeAI } from '@google/generative-ai'
interface OrchestratorConfig {
defaultModel: string
fallbackEnabled: boolean
routingEnabled: boolean
}
export class ModelOrchestrator {
private anthropic: Anthropic
private openai: OpenAI
private gemini: GoogleGenerativeAI
private config: OrchestratorConfig
constructor(config: Partial<OrchestratorConfig> = {}) {
this.anthropic = new Anthropic()
this.openai = new OpenAI()
this.gemini = new GoogleGenerativeAI(process.env.GOOGLE_AI_KEY!)
this.config = {
defaultModel: 'claude-sonnet-4-20250514',
fallbackEnabled: true,
routingEnabled: true,
...config,
}
}
async query(prompt: string, options: { forceModel?: string } = {}): Promise<string> {
// Si se fuerza un modelo, usarlo directamente
if (options.forceModel) {
return this.callModel(options.forceModel, prompt)
}
// Routing si está habilitado
let model = this.config.defaultModel
if (this.config.routingEnabled) {
const taskType = await this.classifyTask(prompt)
model = this.getModelForTask(taskType)
}
// Fallback si está habilitado
if (this.config.fallbackEnabled) {
return this.callWithFallback(model, prompt)
}
return this.callModel(model, prompt)
}
private async callWithFallback(primaryModel: string, prompt: string): Promise<string> {
const fallbacks = this.getFallbacksFor(primaryModel)
for (const model of [primaryModel, ...fallbacks]) {
try {
return await this.callModel(model, prompt)
} catch (error) {
console.warn(`Model ${model} failed, trying next...`)
}
}
throw new Error('All models failed')
}
private async callModel(model: string, prompt: string): Promise<string> {
if (model.includes('claude')) {
const res = await this.anthropic.messages.create({
model, max_tokens: 4096,
messages: [{ role: 'user', content: prompt }]
})
return res.content[0].text
}
if (model.includes('gpt')) {
const res = await this.openai.chat.completions.create({
model, max_tokens: 4096,
messages: [{ role: 'user', content: prompt }]
})
return res.choices[0].message.content!
}
if (model.includes('gemini')) {
const geminiModel = this.gemini.getGenerativeModel({ model })
const res = await geminiModel.generateContent(prompt)
return res.response.text()
}
throw new Error(`Unknown model: ${model}`)
}
// ... classifyTask, getModelForTask, getFallbacksFor
}"No es Claude vs GPT vs Gemini. Es Claude + GPT + Gemini. El que usa uno solo está dejando capacidad en la mesa."
— El Arsenal, Renderz Studio
¿Quieres el sistema completo?
500+ páginas, 25 capítulos, código de producción, acceso a todas las guías del Arsenal.
Curso Completo · €29PayPal · Acceso inmediato