Gateway
Modèles locaux
Les modèles locaux fonctionnent, mais ils imposent des exigences plus élevées en matière de matériel, de taille de contexte et de défense contre l’injection de prompts : les modèles de petite taille ou fortement quantifiés tronquent le contexte et ignorent les filtres de sécurité côté fournisseur. Cette page couvre les piles locales haut de gamme et les serveurs personnalisés compatibles avec OpenAI. Pour la solution la plus simple, commencez par LM Studio ou Ollama et openclaw onboard.
Pour les serveurs locaux qui ne doivent démarrer que lorsqu’un modèle sélectionné en a besoin, consultez Services de modèles locaux.
Configuration matérielle minimale
Visez au moins 2 Mac Studio en configuration maximale ou une machine GPU équivalente (~30 000 $ ou plus) pour une boucle d’agent confortable. Un seul GPU de 24 Go ne prend en charge que des prompts plus légers, avec une latence plus élevée. Exécutez toujours la variante la plus grande ou complète que vous pouvez héberger : les points de contrôle de petite taille ou fortement quantifiés augmentent le risque d’injection de prompts (voir Sécurité).
Choisir un moteur
| Moteur | À utiliser lorsque |
|---|---|
| ds4 | DeepSeek V4 Flash local sur macOS Metal avec des appels d’outils compatibles avec OpenAI |
| LM Studio | Première configuration locale, chargeur avec interface graphique, API Responses native |
| LiteLLM / OAI-proxy / proxy personnalisé compatible avec OpenAI | Vous placez un proxy devant une autre API de modèle et souhaitez qu’OpenClaw la traite comme OpenAI |
| MLX / vLLM / SGLang | Service auto-hébergé à haut débit avec un point de terminaison HTTP compatible avec OpenAI |
| Ollama | Flux de travail CLI, bibliothèque de modèles, service systemd autonome |
Utilisez api: "openai-responses" lorsque le moteur le prend en charge, comme LM Studio. Sinon, utilisez api: "openai-completions". Si api est omis pour un fournisseur personnalisé doté d’une baseUrl, OpenClaw utilise par défaut openai-completions.
LM Studio + grand modèle local (API Responses)
Il s’agit actuellement de la meilleure pile locale. Chargez un grand modèle dans LM Studio, par exemple une version complète de Qwen, DeepSeek ou Llama, activez le serveur local (http://127.0.0.1:1234 par défaut) et utilisez l’API Responses afin de séparer le raisonnement du texte final.
{ agents: { defaults: { model: { primary: "lmstudio/my-local-model" }, models: { "anthropic/claude-opus-4-6": { alias: "Opus" }, "lmstudio/my-local-model": { alias: "Local" }, }, }, }, models: { mode: "merge", providers: { lmstudio: { baseUrl: "http://127.0.0.1:1234/v1", apiKey: "lmstudio", api: "openai-responses", models: [ { id: "my-local-model", name: "Local Model", reasoning: false, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 196608, maxTokens: 8192, }, ], }, }, },}Liste de contrôle de la configuration :
- Installez LM Studio : https://lmstudio.ai
- Téléchargez la plus grande version disponible du modèle (évitez les variantes « petites » ou fortement quantifiées), démarrez le serveur et vérifiez que
http://127.0.0.1:1234/v1/modelsla répertorie. - Remplacez
my-local-modelpar l’identifiant réel du modèle affiché dans LM Studio. - Gardez le modèle chargé ; un chargement à froid ajoute de la latence au démarrage.
- Ajustez
contextWindow/maxTokenssi votre version de LM Studio utilise des valeurs différentes. - Pour WhatsApp, utilisez l’API Responses afin que seul le texte final soit envoyé.
- Conservez
models.mode: "merge"afin que les modèles hébergés restent disponibles comme solutions de repli.
Configuration hybride : modèle principal hébergé, solution de repli locale
{ agents: { defaults: { model: { primary: "anthropic/claude-sonnet-4-6", fallbacks: ["lmstudio/my-local-model", "anthropic/claude-opus-4-6"], }, models: { "anthropic/claude-sonnet-4-6": { alias: "Sonnet" }, "lmstudio/my-local-model": { alias: "Local" }, "anthropic/claude-opus-4-6": { alias: "Opus" }, }, }, }, models: { mode: "merge", providers: { lmstudio: { baseUrl: "http://127.0.0.1:1234/v1", apiKey: "lmstudio", api: "openai-responses", models: [ { id: "my-local-model", name: "Local Model", reasoning: false, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 196608, maxTokens: 8192, }, ], }, }, },}Pour privilégier le modèle local tout en conservant un filet de sécurité hébergé, inversez l’ordre de primary et fallbacks, puis conservez le même bloc providers et models.mode: "merge".
Hébergement régional / routage des données
Des variantes hébergées de MiniMax/Kimi/GLM sont également disponibles sur OpenRouter avec des points de terminaison limités à une région, par exemple hébergés aux États-Unis. Choisissez la variante régionale afin de maintenir le trafic dans la juridiction de votre choix, tout en conservant models.mode: "merge" pour les solutions de repli Anthropic/OpenAI. Une configuration entièrement locale reste la meilleure option en matière de confidentialité ; le routage régional hébergé constitue une solution intermédiaire lorsque vous avez besoin des fonctionnalités d’un fournisseur tout en souhaitant maîtriser le flux des données.
Autres proxys locaux compatibles avec OpenAI
MLX (mlx_lm.server), vLLM, SGLang, LiteLLM, OAI-proxy ou tout Gateway personnalisé fonctionne s’il expose un point de terminaison /v1/chat/completions conforme au format OpenAI. Utilisez openai-completions, sauf si la documentation du moteur indique explicitement la prise en charge de /v1/responses.
{ agents: { defaults: { model: { primary: "local/my-local-model" }, }, }, models: { mode: "merge", providers: { local: { baseUrl: "http://127.0.0.1:8000/v1", apiKey: "sk-local", api: "openai-completions", timeoutSeconds: 300, models: [ { id: "my-local-model", name: "Local Model", reasoning: false, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 120000, maxTokens: 8192, }, ], }, }, },}Les entrées de fournisseur personnalisées/locales approuvent l’origine exacte de leur baseUrl configurée pour les requêtes de modèle protégées, y compris les hôtes local loopback, du réseau local, du tailnet et du DNS privé. Les origines de métadonnées ou link-local sont toujours bloquées. Les requêtes vers d’autres origines privées nécessitent toujours models.providers.<id>.request.allowPrivateNetwork: true ; définissez l’indicateur de confiance sur false pour désactiver l’approbation de l’origine exacte.
models.providers.<id>.models[].id est propre au fournisseur : n’incluez pas le préfixe du fournisseur. Pour un serveur MLX démarré avec mlx_lm.server --model mlx-community/Qwen3-30B-A3B-6bit :
models.providers.mlx.models[].id: "mlx-community/Qwen3-30B-A3B-6bit"agents.defaults.model.primary: "mlx/mlx-community/Qwen3-30B-A3B-6bit"
Définissez input: ["text", "image"] pour les modèles de vision locaux ou accessibles par proxy afin que les pièces jointes d’image soient injectées dans les tours de l’agent. L’intégration interactive d’un fournisseur personnalisé déduit les identifiants courants des modèles de vision et ne pose la question que pour les noms inconnus ; l’intégration non interactive utilise la même déduction, avec --custom-image-input / --custom-text-input pour la remplacer.
Utilisez models.providers.<id>.timeoutSeconds pour les serveurs de modèles locaux ou distants lents avant d’augmenter agents.defaults.timeoutSeconds. Le délai d’expiration du fournisseur couvre la connexion, les en-têtes, la diffusion du corps et l’abandon total de la récupération protégée pour les seules requêtes HTTP du modèle. Si le délai d’expiration de l’agent ou de l’exécution est inférieur, augmentez-le également, car le délai d’expiration du fournisseur ne peut pas prolonger l’ensemble de l’exécution.
Remarques sur le comportement des moteurs /v1 locaux ou accessibles par proxy :
- OpenClaw les traite comme des routes compatibles avec OpenAI de type proxy, et non comme des points de terminaison OpenAI natifs.
- La mise en forme des requêtes réservée à OpenAI natif ne s’applique pas : pas de
service_tier, pas destorepour Responses, pas de mise en forme de charge utile pour la compatibilité du raisonnement OpenAI, ni d’indications de cache de prompts. - Les en-têtes d’attribution OpenClaw masqués (
originator,version,User-Agent) ne sont pas injectés dans les URL de proxy personnalisées.
Remplacements de compatibilité pour les moteurs compatibles avec OpenAI plus stricts :
-
Contenu sous forme de chaîne uniquement : certains serveurs n’acceptent que des valeurs de type chaîne pour
messages[].content, et non des tableaux structurés de parties de contenu. Définissezmodels.providers.<provider>.models[].compat.requiresStringContent: true. -
Clés de message strictes : si le serveur rejette les entrées de message comportant d’autres clés que
role/content, définissezcompat.strictMessageKeys: true. -
Texte d’outil entre crochets : certains modèles locaux émettent sous forme de texte des requêtes d’outil autonomes entre crochets, comme
[tool_name], suivies de JSON et de[END_TOOL_REQUEST]. OpenClaw les convertit en véritables appels d’outils uniquement lorsque le nom correspond exactement à un outil enregistré pour le tour ; sinon, le contenu reste un texte masqué non pris en charge. -
Texte non structuré ressemblant à un appel d’outil : si un modèle émet du texte au format JSON/XML/ReAct qui ressemble à un appel d’outil sans constituer une invocation structurée, OpenClaw le conserve sous forme de texte et consigne un avertissement comprenant l’identifiant d’exécution, le fournisseur/modèle, le motif détecté et, lorsqu’il est disponible, le nom de l’outil. Il s’agit d’une incompatibilité du fournisseur ou du modèle, et non d’une exécution d’outil terminée.
-
Imposer l’utilisation d’un outil : si les outils apparaissent sous forme de texte de l’assistant, qu’il s’agisse de JSON/XML/ReAct brut ou d’un tableau
tool_callsvide, vérifiez d’abord que le modèle de discussion ou l’analyseur du serveur prend en charge les appels d’outils. Si l’analyseur ne fonctionne que lorsque l’utilisation d’un outil est imposée, remplacez pour chaque modèle la valeur de proxy par défauttool_choice: "auto":json5 { agents: { defaults: { models: { "local/my-local-model": { params: { extra_body: { tool_choice: "required", }, }, }, }, }, },}Utilisez cette option uniquement lorsque chaque tour normal doit appeler un outil. Remplacez
local/my-local-modelpar la référence exacte issue deopenclaw models list, ou définissez-la via la CLI :bash openclaw config set agents.defaults.models '{"local/my-local-model":{"params":{"extra_body":{"tool_choice":"required"}}}}' --strict-json --merge -
Niveaux d’effort de raisonnement supplémentaires : si un modèle personnalisé compatible avec OpenAI accepte des niveaux d’effort de raisonnement OpenAI au-delà du profil intégré, déclarez-les dans le bloc de compatibilité du modèle. L’ajout de
"xhigh"le rend disponible pour cette référence de modèle dans/think xhigh, les sélecteurs de session, la validation du Gateway et la validation dellm-task:json5 { models: { providers: { local: { baseUrl: "http://127.0.0.1:8000/v1", apiKey: "sk-local", api: "openai-responses", models: [ { id: "gpt-5.4", name: "GPT 5.4 via local proxy", reasoning: true, input: ["text"], cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, contextWindow: 196608, maxTokens: 8192, compat: { supportedReasoningEfforts: ["low", "medium", "high", "xhigh"], reasoningEffortMap: { xhigh: "xhigh" }, }, }, ], }, }, },}
Moteurs plus petits ou plus stricts
Si le modèle se charge correctement, mais que les tours complets de l’agent se comportent mal, procédez du haut vers le bas : vérifiez d’abord le transport, puis réduisez le périmètre.
-
Vérifiez que le modèle local répond : sans outils ni contexte d’agent :
bash openclaw infer model run --local --model <provider/model> --prompt "Reply with exactly: pong" --json -
Confirmez le routage du Gateway - envoie uniquement le prompt, sans la transcription, l’amorçage d’AGENTS, l’assemblage du moteur de contexte, les outils ni les serveurs MCP intégrés, mais teste tout de même le routage du Gateway, l’authentification et la sélection du fournisseur :
bash openclaw infer model run --gateway --model <provider/model> --prompt "Reply with exactly: pong" --json -
Essayez le mode allégé si les deux sondes réussissent, mais que les véritables tours de l’agent échouent en raison d’appels d’outils mal formés ou de prompts trop volumineux : définissez
agents.defaults.experimental.localModelLean: true. Ce mode supprime les outils lourds liés au navigateur, à Cron, aux messages, à la génération de médias, à la voix et aux PDF, sauf s’ils sont explicitement requis, et place par défaut les catalogues d’outils plus volumineux derrière des contrôles structurés de recherche d’outils, tout en laissantexecdirectement visible. Consultez Fonctionnalités expérimentales -> Mode allégé pour les modèles locaux pour plus de détails et pour savoir comment vérifier qu’il est activé. -
Désactivez entièrement les outils en dernier recours en définissant
models.providers.<provider>.models[].compat.supportsTools: falsepour ce modèle ; l’agent s’exécute alors sans appels d’outils. -
Au-delà, le goulot d’étranglement se situe en amont. Si le backend échoue encore uniquement lors des exécutions OpenClaw plus volumineuses après l’activation du mode allégé et de
supportsTools: false, le problème restant vient généralement du modèle ou du serveur lui-même — fenêtre de contexte, mémoire GPU, éviction du cache KV ou bug du backend — et non de la couche de transport d’OpenClaw.
Dépannage
- Le Gateway ne parvient pas à joindre le proxy ?
curl http://127.0.0.1:1234/v1/models. - Le modèle LM Studio est déchargé ? Rechargez-le ; un démarrage à froid est une cause fréquente de « blocage ».
- Le serveur local indique
terminated,ECONNRESETou ferme le flux au milieu d’un tour ? OpenClaw enregistre dans les diagnostics unmodel.call.error.failureKindà faible cardinalité ainsi qu’un instantané de la RSS et du tas du processus OpenClaw. En cas de pression mémoire dans LM Studio/Ollama, comparez cet horodatage au journal du serveur ou à un journal de plantage/jetsam de macOS pour confirmer si le serveur de modèles a été arrêté. - Erreurs de contexte ? OpenClaw déduit les seuils de vérification préalable de la fenêtre de contexte à partir de la fenêtre détectée du modèle (ou de la fenêtre plafonnée lorsque
agents.defaults.contextTokensla réduit), avec un avertissement sous 20 % et un plancher de 8k, et un blocage strict sous 10 % avec un plancher de 4k (plafonné à la fenêtre de contexte effective afin que des métadonnées de modèle surdimensionnées ne puissent pas rejeter une limite utilisateur valide). RéduisezcontextWindowou augmentez la limite de contexte du serveur ou du modèle. messages[].content ... expected a string? Ajoutezcompat.requiresStringContent: trueà l’entrée de ce modèle.validation.keys, ou « message entries only allowroleandcontent» ? Ajoutezcompat.strictMessageKeys: trueà l’entrée de ce modèle.- Les appels directs à
/v1/chat/completionsfonctionnent, maisopenclaw infer model run --localéchoue avec Gemma ou un autre modèle local ? Vérifiez d’abord l’URL du fournisseur, la référence du modèle, le marqueur d’authentification et les journaux du serveur —model runignore entièrement les outils de l’agent. Simodel runréussit, mais que les tours d’agent plus volumineux échouent, réduisez la surface des outils aveclocalModelLeanoucompat.supportsTools: false. - Les appels d’outils apparaissent sous forme de texte JSON/XML/ReAct brut, ou le fournisseur renvoie un tableau
tool_callsvide ? N’ajoutez pas de proxy qui convertit aveuglément le texte de l’assistant en exécution d’outils — corrigez d’abord le modèle de conversation ou l’analyseur du serveur. Si le modèle fonctionne uniquement lorsque l’utilisation d’outils est forcée, ajoutez la substitutionparams.extra_body.tool_choice: "required"ci-dessus et utilisez cette entrée de modèle uniquement pour les sessions où un appel d’outil est attendu à chaque tour. - Sécurité : les modèles locaux contournent les filtres côté fournisseur. Limitez étroitement les agents et maintenez la Compaction activée afin de réduire la portée des injections de prompt.