Kembali ke Blog

Cara Membangun Smart LLM Gateway dengan Node.js dan Load Balancing Otomatis

Dahono AI31 Juli 202615 views
Cara Membangun Smart LLM Gateway dengan Node.js dan Load Balancing Otomatis

Halo tech enthusiasts! Saat ini, mengandalkan satu model Large Language Model (LLM) saja sering kali tidak cukup untuk kebutuhan aplikasi enterprise modern. Kita sering kali harus memadukan OpenAI GPT-4, Anthropic Claude, hingga model open-source yang di-host secara lokal via vLLM atau Ollama.

Namun, tantangan terbesarnya adalah: Bagaimana cara mengelola trafik, menangani rate limit, serta melakukan failover secara otomatis ketika salah satu provider LLM mengalami down?

Di artikel praktis ini, kita akan membangun sebuah Smart LLM Gateway sederhana menggunakan Node.js dan Express. Gateway ini akan bertindak sebagai single entry point untuk aplikasi Anda dan secara cerdas mendistribusikan request ke beberapa model AI.


Prasyarat

Sebelum mulai ngoding, pastikan Anda telah menyiapkan:

  • Node.js (versi 18 ke atas)
  • Akun dan API Key dari minimal dua provider (misal: OpenAI dan Anthropic)
  • Pemahaman dasar tentang Express.js dan asynchronous JavaScript

Langkah 1: Inisialisasi Proyek

Buat direktori baru untuk proyek kita, lalu inisialisasi modul Node.js:

mkdir smart-llm-gateway
cd smart-llm-gateway
npm init -y

Install dependensi yang kita butuhkan, yaitu express, axios, dan dotenv untuk mengelola environment variables:

npm install express axios dotenv

Langkah 2: Konfigurasi Environment

Buat file .env di root direktori proyek Anda untuk menyimpan kredensial API dengan aman:

PORT=3000
OPENAI_API_KEY=sk-your-openai-key-here
ANTHROPIC_API_KEY=sk-ant-your-anthropic-key-here

Langkah 3: Membuat Logika Load Balancer & Failover

Buat file bernama server.js. Di sini kita akan menulis logika utama gateway yang bertugas menerima request, mengecek kesehatan provider, dan meneruskannya ke LLM yang tersedia.

require('dotenv').config();
const express = require('express');
const axios = require('axios');

const app = express();
app.use(express.json());

const PORT = process.env.PORT || 3000;

// Konfigurasi upstream providers
const providers = [
  {
    name: 'openai',
    url: 'https://api.openai.com/v1/chat/completions',
    headers: {
      'Authorization': `Bearer ${process.env.OPENAI_API_KEY}`,
      'Content-Type': 'application/json'
    },
    weight: 70 // 70% trafik dialokasikan ke sini
  },
  {
    name: 'anthropic',
    url: 'https://api.anthropic.com/v1/messages',
    headers: {
      'x-api-key': process.env.ANTHROPIC_API_KEY,
      'anthropic-version': '2023-06-01',
      'Content-Type': 'application/json'
    },
    weight: 30 // 30% trafik
  }
];

// Helper sederhana untuk memilih provider berdasarkan weight
function selectProvider() {
  // Implementasi sederhana: secara default kita coba OpenAI dulu, jika gagal fallback ke Anthropic
  return providers;
}

app.post('/v1/chat', async (req, res) => {
  const userPrompt = req.body.prompt;
  const activeProviders = selectProvider();

  let success = false;
  let lastError = null;

  for (const provider of activeProviders) {
    try {
      console.log(`Mencoba mengirim request ke provider: ${provider.name}`);
      
      let payload = {};
      if (provider.name === 'openai') {
        payload = {
          model: 'gpt-4o',
          messages: [{ role: 'user', content: userPrompt }],
        };
      } else {
        payload = {
          model: 'claude-3-5-sonnet-20241022',
          max_tokens: 1024,
          messages: [{ role: 'user', content: userPrompt }],
        };
      }

      const response = await axios.post(provider.url, payload, { headers: provider.headers, timeout: 10000 });
      
      // Kirim balik response sukses ke klien
      return res.status(200).json({
        gateway_provider: provider.name,
        data: response.data
      });

    } catch (error) {
      console.warn(`Gagal menggunakan ${provider.name}: ${error.message}. Melakukan failover...`);
      lastError = error.response ? error.response.data : error.message;
    }
  }

  // Jika semua provider gagal
  return res.status(502).json({
    error: 'Semua upstream LLM provider gagal merespons.',
    details: lastError
  });
});

app.listen(PORT, () => {
  console.log(`Smart LLM Gateway berjalan di port ${PORT}`);
});

Langkah 4: Menjalankan dan Menguji Gateway

Jalankan server Node.js Anda dengan perintah:

node server.js

Sekarang, Anda bisa melakukan POST request menggunakan curl atau Postman ke endpoint lokal Anda:

curl -X POST http://localhost:3000/v1/chat \
  -H "Content-Type: application/json" \
  -d '{"prompt": "Jelaskan apa itu arsitektur microservices dalam 2 kalimat."}'

Jika API OpenAI mengalami rate limit atau gangguan jaringan, kode failover kita secara otomatis akan mengalihkan request tersebut ke Anthropic Claude tanpa membuat aplikasi utama Anda crash!


Tantangan Mengelola LLM Gateway di Skala Produksi

Meskipun kode di atas bagus untuk prototipe, membangun LLM gateway tingkat production membawa tantangan tersendiri:

  1. Streaming Responses (SSE): Meneruskan chunk data secara real-time dari LLM ke klien.
  2. Semantic Caching: Menyimpan hasil prompt yang mirip untuk menghemat biaya token hingga 40%.
  3. Rate Limiting & Cost Tracking per Tenant: Memantau siapa saja yang menghabiskan kuota API terbanyak.

Jika Anda tidak ingin repot membangun dan memelihara sistem gateway yang kompleks dari nol untuk skala enterprise, Anda bisa memanfaatkan solusi siap pakai dari Dahono Router. Dahono Router dirancang khusus sebagai AI Gateway berperforma tinggi yang menangani load balancing multi-model, manajemen token, caching pintar, dan failover otomatis secara instan.

Selamat mencoba, dan semoga kode Anda selalu green di production!

Tags:

LLM GatewayNode.jsLoad Balancing AIOpenAI APIAnthropicDahono RouterExpress.js