LM Warden

Claude Code sur vos propres GPU.

Gardez vos identifiants Claude et exécutez ici les modèles désignés par vos règles, ou passez entièrement en local.

Un seul ANTHROPIC_BASE_URL, deux sources de réponse possibles.

Chaque requête que Claude Code envoie à Anthropic est décomptée des limites d’utilisation de votre abonnement, ou facturée au jeton sur une clé API, et fait sortir son prompt, votre code compris, de votre machine. Beaucoup de ces requêtes sont petites. Traitez-les sur des cartes que vous possédez déjà : elles ne coûtent que de l’électricité, ne sont pas décomptées de vos limites, et leurs prompts restent sur votre machine.

Claude lui-même ne tourne jamais ici. Une règle désigne les modèles Claude que cette machine remplace, claude-haiku* par exemple, et un modèle que vous avez chargé répond à leur place, sous le nom demandé par Claude Code. Tout le reste, Opus compris, est transmis à Anthropic octet pour octet avec vos propres identifiants, streaming compris. Votre clé warden est transmise dans un en-tête distinct : vos identifiants ne sont donc jamais modifiés, et rien n’est relayé pour une clé qui n’a pas l’option « May relay to Anthropic ».

Un petit modèle suffit-il ? Nous n’avons pas mesuré la qualité des réponses : c’est donc une appréciation, pas un benchmark. Claude Code utilise son modèle de la classe Haiku pour les tâches de fond plus légères ; un petit modèle local peut raisonnablement le remplacer pour celles-ci et pour des modifications simples et bien définies. Pour les changements touchant de nombreux fichiers, le débogage et les plans de longue haleine, gardez Sonnet et Opus chez Anthropic : c’est ce que fait la règle par défaut, sauf si vous ajoutez une règle. Un modèle plus gros sur des cartes plus puissantes déplace cette limite ; nos mesures avec Claude Code et les réplicas, ci-dessous, ont été faites avec un modèle 4B.

Dimensionnez le contexte pour Claude Code, pas pour le chat : son premier tour dans notre session faisait 38 167 jetons, donc le modèle local a besoin de bien plus de 40 k jetons de contexte.

Where a request from Claude Code goes Claude Code sends a request to LM Warden with two headers: Authorization, its own login, and X-LMWarden-Key, the warden key. LM Warden tries its rules in order and the first match wins. A request for claude-haiku or claude-sonnet matches a rule, is answered by your local model under the Claude name it asked for, and goes through translate, the scheduler and the replica router to one of four vLLM replicas, the conversation staying on its home replica. A request that matches no rule, such as Opus, or any other /v1 path, is passed to api.anthropic.com with the login forwarded and the warden key removed. If the local leg fails before the first byte, a dashed path sends the request to Anthropic, or the rule can refuse with a 529 that Claude Code retries. Claude Code ANTHROPIC_BASE_URL points at the warden Authorization your own login X-LMWarden-Key vw_…, the warden key POST /v1/messages LM Warden rules, first match wins claude-haiku* your local model claude-sonnet* your local model anything else pass through reads the warden key, never forwards it match Local leg translate to the engine scheduler, key priority replica router breaker: 3 failures, open 60 s session id picks the replica vLLM replica 0 vLLM replica 1 vLLM replica 2 vLLM replica 3 a conversation stays on its replica no match: Opus, or any other /v1 path passed on byte for byte, streaming included only for a key with “May relay to Anthropic” local leg failed before the first byte: the rule falls back to Anthropic, or refuses with a 529 that Claude Code retries api.anthropic.com your login forwarded, the warden key removed Off by default. The content of a passed-through request is never logged, stored or shown.
Where a request from Claude Code goes The same flow as the wide drawing, top to bottom. Claude Code sends a request to LM Warden with its own login in Authorization and the warden key in X-LMWarden-Key. LM Warden tries its rules in order; a request for claude-haiku or claude-sonnet is answered by your local model and goes down through the local leg (translate, scheduler, replica router) to one of four vLLM replicas, where the conversation stays. A request that matches no rule goes down the right-hand line to api.anthropic.com, with the login forwarded and the warden key removed. A dashed line from the local leg to Anthropic is the fallback when the local leg fails before the first byte; the rule can instead refuse with a 529 that Claude Code retries. Claude Code Authorization your own login X-LMWarden-Key the warden key ANTHROPIC_BASE_URL = the warden POST /v1/messages LM Warden rules, first match wins claude-haiku* your local model claude-sonnet* your local model anything else pass through reads the warden key, never forwards it match Local leg translate to the engine scheduler, key priority replica router breaker: 3 failures, open 60 s session id picks the replica vLLM replica 0 vLLM replica 1 vLLM replica 2 vLLM replica 3 a conversation stays on its replica no match: Opus, any other /v1 path dashed: the local leg failed before its first byte, so the rule falls back, or refuses with a 529 that Claude Code retries api.anthropic.com your login forwarded, the warden key removed Off by default. Only a key with “May relay to Anthropic” is passed through.
Fig. 2Où va une requête. Les règles sont essayées dans l’ordre et la première correspondance l’emporte. Une réponse locale passe par le même ordonnanceur et le même routeur de réplicas que toute autre requête ; un réplica est une copie complète du modèle, ici une par GPU. En cas d’échec local avant le premier octet, la requête part chez Anthropic ou revient sous forme d’une erreur 529 que Claude Code réessaie ; après 3 échecs d’affilée, le disjoncteur du modèle s’ouvre : pendant 60 s, plus rien ne lui est envoyé.

En clair : Claude Code envoie la requête au warden avec ses propres identifiants Anthropic dans Authorization et la clé warden dans X-LMWarden-Key. Le warden essaie ses règles dans l’ordre. Une requête pour un modèle désigné par une règle est traduite, mise en file par l’ordonnanceur et envoyée par le routeur de réplicas à un réplica vLLM. Toute autre requête, par exemple pour Opus, est transmise à api.anthropic.com avec les identifiants transférés et la clé warden retirée. Si la partie locale échoue avant son premier octet, la requête part chez Anthropic, ou la règle la refuse avec une erreur 529 que Claude Code réessaie.

export ANTHROPIC_BASE_URL=https://warden.example
export ANTHROPIC_CUSTOM_HEADERS="X-LMWarden-Key: vw_…"
claude

Claude Code 2.1.227 ou version ultérieure. Restez connecté à claude comme d’habitude ; la clé va dans un en-tête distinct, pas dans ANTHROPIC_API_KEY.

La page Router de la console. Un bandeau vert indique « Routing normally » et « 96% answered locally since 13:38 ». Sous « Where each Claude model goes. First match wins », la règle 1 envoie claude-haiku* au modèle chargé qwen3-4b-dp4, avec « If it fails: Anthropic » et « Thinking off ». La dernière ligne est la règle par défaut : tous les autres modèles Claude et chemins /v1 partent chez Anthropic avec les identifiants de l’utilisateur et exigent une clé dotée de l’option « May relay to Anthropic ». Le panneau Traffic compte 107 requêtes en local, 2 transmises à Anthropic, 0 repli sur Anthropic et 2 refusées ou en erreur, et liste deux motifs, no_upstream_credential et relay_not_allowed, un de chaque. La première correspondance l’emporte ; tous les autres modèles vont chez Anthropic Anthropic est contacté avec les identifiants de l’utilisateur
Fig. 3La page Router, le warden tournant depuis 13 h 38 : « Routing normally », 96 % des requêtes traitées en local depuis le redémarrage. Une règle envoie claude-haiku* à un modèle local et la règle par défaut transmet tout le reste à Anthropic ; les règles sont numérotées dans l’ordre où elles sont essayées. Le panneau Traffic compte 107 requêtes en local, 2 transmises, 0 repli et 2 refusées. Faites défiler l’image horizontalement pour voir toute la page.

Attendez-vous à ce que le premier tour soit le plus lent. Dans une session précédente, le premier tour de Claude Code faisait 38 167 jetons et le modèle local était chargé avec un contexte de 32 768 jetons : le moteur l’a donc refusé (status_400) et la requête est partie chez Anthropic. Avec le contexte porté à 65 536 jetons et un cache KV fp8 (le cache d’attention stocké sur 8 bits, soit moitié moins de mémoire), le modèle 4B sur des cartes de 16 Gio a traité ce même tour en local en 28 s, avec tout le prompt de 38 k jetons lu à froid, sans rien encore dans le cache. Les tours suivants d’une conversation trouvent l’essentiel de leur prompt déjà dans le cache du moteur : le délai médian avant le premier octet pour la règle claude-haiku* de la fig. 4 est de 290 ms.

La page d’activité Router. Quatre compteurs : local 107, transmises à Anthropic 2, repli 0, et refusées · erreurs 2 · 0. Un tableau « By rule » donne la règle claude-haiku* vers qwen3-4b-dp4 avec ses nombres de réponses locales, de replis et de refus, la latence et le délai avant le premier octet en p50 et p95, et l’état de son disjoncteur, fermé ; la ligne de transmission donne les mêmes délais pour les requêtes transmises à Anthropic. Un tableau des modèles locaux montre qwen3-4b-dp4 avec son disjoncteur fermé, et un panneau « Fallback reasons » liste no_upstream_credential et relay_not_allowed, un de chaque. Le disjoncteur de ce modèle : fermé Pourquoi une règle a renvoyé vers Anthropic ou refusé, par motif
Fig. 4L’activité du Router sur la même période : 107 requêtes traitées en local, 2 transmises à Anthropic, 0 repli, et 2 refusées avec 0 erreur. En dessous, la latence et le délai avant le premier octet par règle en p50 et p95, le disjoncteur de chaque modèle local, et les motifs pour lesquels une règle a renvoyé vers Anthropic ou refusé. Les compteurs sont propres à chaque processus ; un redémarrage les remet à zéro. Relevé le 4 octobre 2026. Faites défiler l’image horizontalement pour voir toute la page.
Protocole
Anthropic Messages
Prise en charge
Complète

Les modèles Claude désignés par vos règles tournent ici ; tous les autres modèles et chemins /v1 partent chez Anthropic avec vos propres identifiants. En mode Router, ne mettez jamais la clé warden dans ANTHROPIC_API_KEY ni dans ANTHROPIC_AUTH_TOKEN : elle remplacerait vos identifiants. Le mode Local uniquement fait tout tourner sur un seul modèle servi, y compris les petites tâches d’arrière-plan, et rien ne part chez Anthropic.

Prérequis

  • Claude Code 2.1.227 ou version ultérieure (ANTHROPIC_CUSTOM_HEADERS).
  • Le routage doit être activé, avec au moins une règle active.
  • La clé doit être autorisée à relayer vers Anthropic (May relay).
  • Nécessite au moins 49 152 jetons de contexte : le premier tour fait à lui seul environ 38 000 jetons avant la lecture du moindre fichier.
  • 131 072 jetons ou plus pour de vraies sessions ; moins suffit pour des sessions courtes.
  • Claude Code peut signaler que le nom du modèle ne figure pas dans son catalogue. C’est purement informatif : il suppose une fenêtre de 200 k jetons et compacte automatiquement en conséquence. Définissez CLAUDE_CODE_MAX_CONTEXT_TOKENS sur la fenêtre de contexte réelle du modèle.

Configuration

Dans la console, Connect génère ces fichiers avec l’adresse de votre warden, votre clé et le modèle choisi. Ils sont présentés ici avec des valeurs fictives.

Router : gardez vos identifiants Claude

Vos identifiants Claude continuent d’être envoyés à Anthropic ; la clé warden est transmise dans un en-tête distinct, et les modèles désignés par vos règles sont servis ici.

Shell
export ANTHROPIC_BASE_URL=https://your-warden
export ANTHROPIC_CUSTOM_HEADERS="X-LMWarden-Key: vw_YOUR_KEY"
claude
settings.json (~/.claude/settings.json)
{
  "env": {
    "ANTHROPIC_BASE_URL": "https://your-warden",
    "ANTHROPIC_CUSTOM_HEADERS": "X-LMWarden-Key: vw_YOUR_KEY"
  }
}

Local uniquement (sans compte Anthropic)

Tous les choix de modèle de Claude Code pointent vers le modèle servi sélectionné, et la clé warden sert de jeton d’authentification. Rien ne part chez Anthropic.

Shell
export ANTHROPIC_BASE_URL=https://your-warden
export ANTHROPIC_AUTH_TOKEN=vw_YOUR_KEY
export ANTHROPIC_MODEL=your-served-model-name
export ANTHROPIC_DEFAULT_OPUS_MODEL=your-served-model-name
export ANTHROPIC_DEFAULT_SONNET_MODEL=your-served-model-name
export ANTHROPIC_DEFAULT_HAIKU_MODEL=your-served-model-name
export CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS=1
export CLAUDE_CODE_MAX_CONTEXT_TOKENS=32768
# The model's context window is unknown: 32768 is a guess. Set it to the model's real window.
settings.json (~/.claude/settings.json)
{
  "env": {
    "ANTHROPIC_BASE_URL": "https://your-warden",
    "ANTHROPIC_AUTH_TOKEN": "vw_YOUR_KEY",
    "ANTHROPIC_MODEL": "your-served-model-name",
    "ANTHROPIC_DEFAULT_OPUS_MODEL": "your-served-model-name",
    "ANTHROPIC_DEFAULT_SONNET_MODEL": "your-served-model-name",
    "ANTHROPIC_DEFAULT_HAIKU_MODEL": "your-served-model-name",
    "CLAUDE_CODE_DISABLE_EXPERIMENTAL_BETAS": "1",
    "CLAUDE_CODE_MAX_CONTEXT_TOKENS": "32768"
  }
}

Documentation officielle : https://code.claude.com/docs/en/llm-gateway (consultée le 2026-10-04).