Ketergantungan pada satu penyedia LLM (Large Language Model) seperti OpenAI atau Anthropic membawa risiko operasional fatal bagi internal developer tooling. Masalah umum mencakup lonjakan HTTP 429 (rate limit exceeded), penurunan kuota mendadak, hingga suspensi akun secara sepihak (vendor ban). Tanpa layer perantara, seluruh tim teknis yang mengandalkan AI CLI akan terhenti total.

Solusinya adalah menempatkan API Gateway terpusat antara client CLI dan upstream provider. Arsitektur ini mengisolasi kredensial, menormalisasi perbedaan skema request/response, dan menjalankan dynamic fallback secara otomatis saat provider utama mengalami gangguan.

Topologi Gateway dan Dynamic Fallback

Pola dynamic fallback bekerja layaknya circuit breaker. Gateway mengirim request ke provider prioritas (misal Anthropic Claude 3.5 Sonnet). Jika menerima response status 429, 5xx, atau timeout, request langsung dialihkan ke provider cadangan (misal OpenAI GPT-4o atau Google Gemini via Vertex AI) tanpa mengembalikan error ke terminal pengguna.

+----------------+      +-------------------------------------------+
|     AI CLI     | ---> |                API Gateway                |
| (Internal Dev) | <--- |  - Auth & Team Isolation                  |
+----------------+      |  - Payload Normalization (Unified Schema) |
                        |  - Dynamic Fallback Routing               |
                        +-------------------------------------------+
                                  |                     |
                       Primary    v         Fallback    v
                            +-----------+         +-----------+
                            | Anthropic |         |  OpenAI   |
                            | (Claude)  |         |  (GPT-4o) |
                            +-----------+         +-----------+

Normalisasi Payload dan Eksekusi Fallback

Tantangan utama multi-provider adalah inkonsistensi format API. Anthropic memisahkan field system dari array messages, sementara OpenAI menggabungkannya sebagai objek dengan role system. Gateway bertugas menerima skema standar dari CLI, lalu mentransformasikannya sesuai upstream target.

Berikut implementasi router fallback berbasis Node.js/TypeScript menggunakan fetch standar:

interface UnifiedMessage {
  role: 'system' | 'user' | 'assistant';
  content: string;
}

interface GenerateRequest {
  messages: UnifiedMessage[];
  maxTokens: number;
}

// Adapter payload Anthropic
function toAnthropicPayload(req: GenerateRequest) {
  const systemMsg = req.messages.find(m => m.role === 'system');
  const userMsgs = req.messages.filter(m => m.role !== 'system');
  return {
    model: 'claude-3-5-sonnet-20241022',
    max_tokens: req.maxTokens,
    system: systemMsg?.content,
    messages: userMsgs
  };
}

// Adapter payload OpenAI
function toOpenAIPayload(req: GenerateRequest) {
  return {
    model: 'gpt-4o',
    max_tokens: req.maxTokens,
    messages: req.messages
  };
}

// Router dengan dynamic fallback
async function executeWithFallback(req: GenerateRequest): Promise<string> {
  // Provider 1: Anthropic
  try {
    const res = await fetch('https://api.anthropic.com/v1/messages', {
      method: 'POST',
      headers: {
        'x-api-key': process.env.ANTHROPIC_API_KEY!,
        'anthropic-version': '2023-06-01',
        'content-type': 'application/json'
      },
      body: JSON.stringify(toAnthropicPayload(req)),
      signal: AbortSignal.timeout(8000) // Cut-off latency 8 detik
    });

    if (res.ok) {
      const data = await res.json();
      return data.content[0].text;
    }
    
    // Validasi status code untuk fallback: rate limit atau server error
    if (![429, 500, 502, 503, 529].includes(res.status)) {
      throw new Error(`Upstream client error: ${res.status}`);
    }
  } catch (err) {
    // Log kegagalan ke telemetry
  }

  // Provider 2: Fallback ke OpenAI
  const fallbackRes = await fetch('https://api.openai.com/v1/chat/completions', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.OPENAI_API_KEY}`,
      'Content-type': 'application/json'
    },
    body: JSON.stringify(toOpenAIPayload(req)),
    signal: AbortSignal.timeout(10000)
  });

  if (!fallbackRes.ok) {
    throw new Error(`Fallback failed: ${fallbackRes.statusText}`);
  }

  const fallbackData = await fallbackRes.json();
  return fallbackData.choices[0].message.content;
}

Manajemen Rate Limit Terdistribusi

Mengandalkan response 429 upstream sebelum berpindah provider memicu latency penalty. Pendekatan yang lebih aman adalah memantau kuota secara lokal di layer gateway menggunakan Token Bucket berbasis Redis.

  • Token Bucket Terdistribusi: Setiap tim atau instance gateway mengurangi counter token di Redis sebelum request diteruskan. Jika token lokal habis, request langsung diarahkan ke secondary provider tanpa menunggu rejected call dari primary API.
  • Proactive Backoff: Baca header response seperti anthropic-ratelimit-requests-remaining atau x-ratelimit-remaining-tokens. Jika sisa kuota kurang dari threshold kritis (misal < 5%), gateway otomatis mengalihkan persentase traffic tertentu ke secondary provider.

Isolasi API Credential per Tim

Developer CLI tidak boleh menyimpan API key vendor langsung di mesin lokal. Gateway bertindak sebagai auth-proxy:

  1. Virtual API Key: CLI melakukan autentikasi menggunakan internal token tim (misal team-backend-secret).
  2. Vault Storage: Gateway mengambil key upstream vendor dari Secret Manager (HashiCorp Vault, AWS Secrets Manager) yang dirotasi berkala.
  3. Cost Attribution: Gateway mencatat konsumsi token per tim ke database analytics. Jika satu tim melakukan looping script dan memicu rate limit, circuit breaker gateway hanya membatasi tim tersebut tanpa melumpuhkan tim lain.

Trade-off: Latency vs Operational Cost

Penerapan multi-provider memunculkan trade-off mendasar:

  • Latency: Mekanisme serial fallback (mencoba Provider A, gagal, lalu beralih ke Provider B) menambah waktu tunggu respon di terminal CLI hingga 2-5 detik. Strategi hedged requests (memanggil dua provider sekaligus dan mengambil yang tercepat) memangkas latency, namun melipatgandakan tagihan token upstream.
  • Output Quality & Context Drift: Model dari vendor berbeda memiliki pemahaman system prompt yang tidak identik. CLI coding yang mengandalkan format JSON strict dari Claude mungkin menerima output dengan formatting markdown dari GPT-4o, requiring defensive parsing di layer gateway.
  • Cost Management: Failover ke model dengan harga per million tokens lebih tinggi tanpa routing logic yang ketat berisiko membengkakkan biaya saat primary provider mengalami downtime panjang.