NouveauBranchez n’importe quel agent sur UberLLM : une clé, tous les modèles, au prix catalogue ou moins.
UberLLM

OpenAI SDK

UberLLM implémente l'API OpenAI Chat Completions. Tout code qui utilise le SDK officiel openai (ou un client compatible) fonctionne en configurant deux éléments :

  • base_url / baseURL → https://api.uberllm.dev/v1
  • api_key / apiKey → votre clé ull_

Tout le reste — messages, tools, response_format, stream, max_tokens, temperature — est inchangé.

Python

import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.uberllm.dev/v1",
    api_key=os.environ["UBERLLM_API_KEY"],
)

# Non-streaming
resp = client.chat.completions.create(
    model="deepseek/deepseek-v4-flash",
    messages=[{"role": "user", "content": "Explain rope embeddings briefly."}],
)
print(resp.choices[0].message.content)
print(resp.usage)  # prompt_tokens / completion_tokens are returned per request

# Streaming
stream = client.chat.completions.create(
    model="deepseek/deepseek-v4-flash",
    messages=[{"role": "user", "content": "Count to five."}],
    stream=True,
)
for chunk in stream:
    print(chunk.choices[0].delta.content or "", end="", flush=True)

TypeScript / JavaScript

import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.uberllm.dev/v1",
  apiKey: process.env.UBERLLM_API_KEY,
});

const resp = await client.chat.completions.create({
  model: "deepseek/deepseek-v4-flash",
  messages: [{ role: "user", content: "Explain rope embeddings briefly." }],
});
console.log(resp.choices[0].message.content);

Appel d'outil

L'appel d'outil/fonction est transmis tel quel. Utilisez les modèles qui annoncent la prise en charge des outils (voir Modèles et routage; le catalogue marque supports_tools).

resp = client.chat.completions.create(
    model="deepseek/deepseek-v4-flash",
    messages=[{"role": "user", "content": "What is the weather in Paris?"}],
    tools=[{
        "type": "function",
        "function": {
            "name": "get_weather",
            "description": "Get the current weather for a city",
            "parameters": {
                "type": "object",
                "properties": {"city": {"type": "string"}},
                "required": ["city"],
            },
        },
    }],
)
print(resp.choices[0].message.tool_calls)

Une réponse qui appelle un outil se termine toujours par finish_reason: "tool_calls" (stop_reason: "tool_use" sur /v1/messages), en streaming ou non, quel que soit le fournisseur qui l'a servie. Renvoyez chaque appel d'outil tel que vous l'avez reçu : certains comportent un champ extra_content (signature de pensée de Gemini) dont le modèle a besoin au tour suivant.

Forme de la réponse

Chaque réponse a les mêmes champs, quel que soit le fournisseur qui l’a servie : les champs de chat completion d’OpenAI (id, object, created, model, choices, usage) et notre usage.cost_usd. Les champs qu’un fournisseur ajoute de son côté (x_groq, service_tier, system_fingerprint, usage.queue_time et similaires) sont supprimés.

Les modèles de raisonnement envoient leur raisonnement à la fois dans reasoning et reasoning_content, avec le même texte, dans message (ou delta en streaming), donc un client qui lit l’un ou l’autre l’obtient. Quand un fournisseur envoie des reasoning_details de style OpenRouter, ils passent tels quels. Une réponse sans raisonnement n’a aucun des deux champs.

Les champs de requête qu’un fournisseur refuse mais qui ne font qu’ajuster la réponse (reasoning, thinking, verbosity, top_k et similaires) sont supprimés pour ce fournisseur, et reasoning: {"effort": "low"} est envoyé comme reasoning_effort quand c’est ce qu’il faut. Le contenu d’un message envoyé sous forme de liste de parties de texte est transmis comme une seule chaîne à un fournisseur qui n’accepte que des chaînes. Une image, un audio ou un fichier envoyés à un modèle qui ne lit que du texte sont refusés avec un 400 simple qui le dit : vérifiez d’abord input_modalities dans GET /v1/models.

Lister les modèles

curl https://api.uberllm.dev/v1/models \
  -H "Authorization: Bearer $UBERLLM_API_KEY"

Renvoie la structure de liste OpenAI ({"object":"list","data":[{"id": "...", ...}]}) avec les modèles de chat que vous pouvez utiliser dès maintenant ; ?type=all ajoute les modèles d'image, de vidéo, de musique et de parole. Chaque modèle de chat inclut context_length, max_output_tokens, input_modalities, supports_tools, supports_reasoning, supports_vision et supported_parameters (voir Modèles et routage). Le catalogue public (sans auth) est également disponible à GET /api/v1/public/models avec une tarification par endpoint.

Utilisation du streaming

Pour les requêtes de streaming, UberLLM demande automatiquement l'utilisation des tokens (stream_options.include_usage), ainsi le dernier chunk contient un objet usage avec cost_usd, ce pour quoi l'appel est facturé en dollars US. Une réponse qui n'est pas en streaming contient également usage.cost_usd, et l'en-tête X-UberLLM-Cost-USD (sauf pour une réponse lente qui a déjà commencé avec des espaces de keepalive : alors seulement le champ body). Votre facture correspond au coût que le marketplace rapporte pour cet appel. La réponse n'attend pas ce rapport : lorsqu'il n'est pas encore disponible, cost_usd est notre estimation, et votre solde et Tableau de bord → Activité affichent le montant exact un instant plus tard. Si l'utilisation est manquante, UberLLM se rabat sur une estimation du tokenizer — ces lignes sont signalées dans Tableau de bord → Activité.

API de Réponses

client.responses.create et client.responses.stream fonctionnent aussi, sur chaque modèle de chat : texte, appels d'outils (function_call → function_call_output), sortie structurée et streaming. UberLLM ne stocke rien, donc envoyez toute la conversation dans input à chaque appel au lieu de previous_response_id. Détails : API de Réponses.

r = client.responses.create(
    model="deepseek/deepseek-v4.1-flash",
    instructions="Answer in one short sentence.",
    input="What is the capital of France?",
)
print(r.output_text)

Notes

  • Le /v1 final est requis dans l'URL de base.
  • Chaque requête est envoyée à un fournisseur tiers disponible pour le modèle et est facturée au prix facturé par le fournisseur, sans frais UberLLM. Voir Tarification.
  • Pour les tentatives automatiques et les options de routage acceptées par UberLLM, voir Modèles et routage.