Skillia

Utiliser LiteLLM en TypeScript

OpenCode c'est pour le terminal. Mais la vraie puissance du proxy, c'est dans ton code. Puisque LiteLLM expose une API 100% OpenAI-compatible, tu utilises le SDK OpenAI standard. Zéro dépendance spécifique.

Setup du projet

mkdir litellm-demo && cd litellm-demo
npm init -y
npm install openai
npm install -D tsx typescript

Crée un .env :

LITELLM_URL=https://ton-litellm-xxx.vm.elestio.app/v1
LITELLM_KEY=sk-ta-master-key-ici

Remplace par l'URL et la master key de ton instance LiteLLM (tu les trouves dans le dashboard Elestio).

Appel basique

Dans notre cas, on a configuré un alias skillia.dev qui pointe vers openrouter/google/gemini-3-flash-preview (Gemini Flash via OpenRouter). C'est ce nom qu'on utilise dans model :

// src/index.ts
import OpenAI from "openai";

const litellm = new OpenAI({
  baseURL: process.env.LITELLM_URL,
  apiKey: process.env.LITELLM_KEY,
});

const response = await litellm.chat.completions.create({
  model: "skillia.dev",  // alias → openrouter/google/gemini-3-flash-preview
  messages: [
    { role: "system", content: "Tu es un assistant concis. Réponds en 2-3 phrases max." },
    { role: "user", content: "C'est quoi un proxy LLM et pourquoi j'en aurais besoin ?" },
  ],
  max_tokens: 200,
});

console.log(response.choices[0].message.content);
console.log(`\nModèle: ${response.model}`);
console.log(`Tokens: ${response.usage?.prompt_tokens} in / ${response.usage?.completion_tokens} out`);
npx tsx --env-file=.env src/index.ts

Résultat :

Un proxy LLM est une couche intermédiaire entre vos applications et les
fournisseurs d'IA (OpenAI, Anthropic, etc.). Il permet de centraliser la
gestion des clés d'API, de contrôler les coûts et d'ajouter des fonctions
de sécurité ou de redirection automatique en cas de panne.

Modèle: skillia.dev
Tokens: 34 in / 60 out

Le point clé : npm install openai et c'est tout. Pas de SDK LiteLLM, pas de SDK OpenRouter. Un seul client pour tous les modèles. L'alias skillia.dev cache le fait que c'est Gemini Flash derrière. Tu pourrais changer le modèle sous-jacent dans LiteLLM sans toucher une ligne de code.

Streaming

// src/stream.ts
import OpenAI from "openai";

const litellm = new OpenAI({
  baseURL: process.env.LITELLM_URL,
  apiKey: process.env.LITELLM_KEY,
});

const stream = await litellm.chat.completions.create({
  model: "skillia.dev",
  messages: [
    { role: "user", content: "Écris un haiku sur le code TypeScript" },
  ],
  max_tokens: 200,
  stream: true,
});

for await (const chunk of stream) {
  const content = chunk.choices[0]?.delta?.content;
  if (content) process.stdout.write(content);
}

Les tokens arrivent un par un, comme avec l'API OpenAI directe. Ton proxy est transparent.

Changer de modèle = changer une string

C'est là que le proxy prend tout son sens. Si tu configures plusieurs modèles dans LiteLLM (comme on l'a vu dans la leçon 3), tu peux les appeler avec le même client. Même code, même format, modèle différent :

// src/multi-model.ts
import OpenAI from "openai";

const litellm = new OpenAI({
  baseURL: process.env.LITELLM_URL,
  apiKey: process.env.LITELLM_KEY,
});

const prompt = "En une phrase : c'est quoi TypeScript ?";
// Ces noms correspondent aux model_name configurés dans LiteLLM
const models = ["skillia.dev", "claude-sonnet", "gpt-4o"];

for (const model of models) {
  const start = Date.now();
  const response = await litellm.chat.completions.create({
    model,
    messages: [{ role: "user", content: prompt }],
    max_tokens: 200,
  });

  const ms = Date.now() - start;
  console.log(`--- ${model} (${ms}ms) ---`);
  console.log(response.choices[0].message.content);
}

Tu passes de Gemini Flash à Claude à GPT sans changer un import, un SDK, ou un format. Juste une string. Chaque nom (skillia.dev, claude-sonnet, gpt-4o) correspond à un model_name dans ta config LiteLLM, qui pointe vers le vrai modèle chez le provider.

Virtual keys par projet

// Projet A -- budget 50$
const clientProjetA = new OpenAI({
  baseURL: process.env.LITELLM_URL,
  apiKey: "sk-virtual-key-projet-a",
});

// Projet B -- budget 20$
const clientProjetB = new OpenAI({
  baseURL: process.env.LITELLM_URL,
  apiKey: "sk-virtual-key-projet-b",
});

Chaque projet a son budget. Si un script s'emballe, il ne peut pas dépasser son enveloppe.

C'est la dernière leçon du cours. Tu as maintenant un gateway LLM complet : déployé sur Elestio, connecté à OpenRouter, utilisable depuis OpenCode et depuis ton code TypeScript.