SERVICE LLM · LOCAL D'ABORD
llmCLI
Une seule CLI pour servir des modèles de langage en local sur ton propre GPU. Les moteurs llama.cpp et GGUF se tiennent derrière un endpoint HTTP compatible OpenAI, hot-swappables depuis un catalogue TOML, avec un proxy LiteLLM partagé que tout outil du LAN peut appeler. Le frère de voiceCLI et imageCLI — même forme, la couche d'inférence.
Ce que c'est
Servir un modèle local revient d'habitude à veiller sur un processus serveur — choisir des ports, jongler avec la VRAM, redémarrer pour changer de poids. llmCLI réduit ça à une commande : récupère un GGUF, sers-le sur un endpoint compatible OpenAI, hot-swap vers un autre sans toucher aux appelants. Tout tourne sur un matériel que tu possèdes — aucune clé cloud, aucune facturation au token, aucun modèle qui disparaît quand un fournisseur le déprécie.
C'est le troisième frère de la famille des CLI local-first. voiceCLI fait la voix, imageCLI fait les pixels, llmCLI fait les tokens — la même forme opérationnelle appliquée à la couche d'inférence sur laquelle les autres s'appuient.
Le contrat durable, c'est l'endpoint OpenAI, pas le moteur. Les appelants parlent une seule API ; le modèle derrière change librement.
Un catalogue de modèles
Les modèles sont de la config, pas du code. Les réglages d'hôte vivent dans un TOML ; chaque modèle est un fichier plat unique dans un dossier models/ — nomme le fichier, nomme le modèle. Dépose-en un nouveau et llmcli list le détecte aussitôt, sans redémarrage.
# ~/.roxabi/llmcli/models/qwen3-14b-q5.toml
engine = "llamacpp"
repo = "Qwen/Qwen3-14B-GGUF"
file = "qwen3-14b-q5_k_m.gguf"
port = 8092
vram_gib = 11
flags = ["-ngl", "99", "-c", "8192", "-fa", "on", "--jinja"]Le catalogue laisse chaque hôte porter ce que sa carte peut tenir — un poste de 16 Go fixe les gros modèles, une machine toujours allumée de 10 Go garde les petits résidents. llmcli swap hot-swap le moteur en cours ; llmcli status rapporte moteurs, ports, VRAM et uptime d'un coup d'œil.
Un endpoint, tous les appelants
Le serveur expose l'API chat-completions d'OpenAI, donc tout ce qui parle ce protocole fonctionne sans changement — tes propres scripts, un SDK, un agent. L'enjeu est l'uniformité : un Qwen local et un modèle hébergé ont la même forme d'appel pour ce qui se tient devant.
| Commande | Fait |
|---|---|
llmcli pull <name> | Télécharge un modèle dans le cache HF hub partagé. |
llmcli serve [name] | Démarre le daemon et sert un modèle. |
llmcli swap <name> | Hot-swap le modèle en cours sur place. |
llmcli status · list | Moteurs, ports, VRAM, uptime · catalogue + état en cours. |
llmcli chat <name> "…" | Appel one-shot, en contournant le proxy. |
Proxy & worker
Deux surfaces de déploiement sont livrées comme unités Quadlet Podman. Le proxy LiteLLM tourne sur chaque hôte et donne à tout le LAN une seule adresse — Claude Code, agents et outils routent à travers lui, mêlant moteurs locaux et modèles cloud derrière une config unique. Le worker NATS ne tourne que là où vit un GPU, exposant l'inférence locale sur le bus de messages.
llama-server :PORT ◄── llmcli serve (hot-swap piloté par catalogue)
▲
│ API OpenAI
├── agents (bibliothèque LiteLLM, config par agent)
└── proxy litellm ◄── claude-code, outils du LANC'est ainsi que llmCLI se branche sur roxabi-factory : le worker s'enregistre sur le bus, et n'importe quel agent atteint un modèle local sans savoir quelle machine porte le GPU.
Lance-le
Prérequis : Python 3.12, un GPU CUDA pour le service local, et le gestionnaire de paquets uv. Le proxy seul tourne partout ; le moteur veut le GPU.
uv sync
cp models/*.toml ~/.roxabi/llmcli/models/ # amorce le catalogue
llmcli pull qwen3_6-35b-a3b-tq3 # récupère un modèle
systemctl --user start llmcli # proxy sur :18091
llmcli statusMoteurs, catalogue, proxy et worker NATS sont tous en accès ouvert.
- Le repo · github.com/Roxabi/llmCLI →