Configurer dsh : clés API, modèles et endpoints
Découvrez où dsh stocke sa configuration Linux, comment utiliser une clé API DeepSeek ou un endpoint Ollama local, et ce qui quitte votre machine.
Emplacement de la configuration de dsh
dsh (DeepSeek Harness) conserve sa configuration dans un seul répertoire : $DSH_HOME, qui correspond par défaut à ~/.dsh. Tout ce que vous définissez dans l’interface Web y est enregistré sous forme de fichiers texte. Copiez ce répertoire sur un autre serveur pour que le nouveau système se comporte comme l’ancien.
Quatre chemins contiennent tout ce que vous aurez à modifier.
~/.dsh/settings.yamlcontient les paramètres saisis manuellement ou enregistrés depuis l’interface, notamment vos routes de provider et de modèle.~/.dsh/.credentials.yamlcontient les secrets. Les paramètres ne conservent qu’une référence vers un credential ; la valeur de la clé se trouve donc dans un seul fichier.~/.dsh/profiles/contient les profils nommés et~/.dsh/storages/contient les sessions enregistrées.~/.dsh/cordis.patch.ymlconstitue votre couche de correctifs. Elle est appliquée par-dessus la configuration intégrée pour chaque profil.
DeepSeek a présenté le harness comme une developer preview sous licence MIT le 17 août 2026. Le README précise que des changements incompatibles sont prévus. Les noms de champs et les chemins de ce guide correspondent à la documentation du dépôt en août 2026. Vérifiez-les dans la documentation correspondant à la version que vous avez installée avant de copier une configuration depuis un guide, y compris celui-ci, car une preview peut renommer des éléments d’une release à l’autre.
Le minimum honnête pour obtenir la première sortie
dsh nécessite Node.js 22.19 ou une version ultérieure de la branche 22, ou la version 24 et les suivantes. Node 23 ne fait pas partie de ces versions. Vérifiez d’abord la version, car une incompatibilité de version provoque un échec au démarrage et le message d’erreur donne l’impression que le package est défectueux.
node -v
npx @deepseek-ai/dsh webnpx télécharge le package depuis le registre npm et démarre l’interface Web sur http://127.0.0.1:3080. Il se lie à l’adresse loopback. Le port n’est donc pas accessible depuis une autre machine, même si votre firewall l’autorise. Sur un VPS, transférez-le avec SSH au lieu d’ouvrir le port 3080 sur Internet. Si l’URL affichée prête à confusion, pourquoi dsh démarre sur cette adresse explique ce que protège la liaison loopback et ce qu’elle ne protège pas.
ssh -N -L 3080:127.0.0.1:3080 you@your-serverOuvrez http://127.0.0.1:3080 sur votre ordinateur portable, puis accédez à Settings et Models. La carte DeepSeek comporte un seul champ pour la clé API. Collez la clé obtenue sur platform.deepseek.com, puis enregistrez-la. La route du modèle devient immédiatement utilisable, sans redémarrage, car le serveur en cours d’exécution stocke l’identifiant et résout la référence à la volée. Accéder à l’interface Web de dsh sur un serveur distant couvre les cas du tunnel et du reverse proxy, tandis que installer DeepSeek Harness sur un VPS couvre la préparation du serveur supposée par ce guide.
Après l’enregistrement, vérifiez ce que l’application a créé.
ls -la ~/.dsh
stat -c '%a %n' ~/.dsh/.credentials.yamlVous devez voir settings.yaml, .credentials.yaml et profiles/. Si stat affiche un mode différent de 600, exécutez chmod 600 ~/.dsh/.credentials.yaml. Un fichier d’identifiants lisible par le groupe ou par tous les utilisateurs transmet votre clé à tous les autres comptes du serveur.
Pour un premier test sans navigateur, une seule commande suffit.
npx @deepseek-ai/dsh --profile headless "summarise the files in this directory"Le profil headless exécute une seule session et affiche la réponse finale.
Variables d’environnement ou fichier de configuration
Il existe 2 façons de fournir une clé à dsh, et elles ne sont pas interchangeables.
Un fournisseur du catalogue (DeepSeek, Anthropic, OpenAI et les autres fournisseurs intégrés) reçoit sa clé depuis la page Models. La valeur est enregistrée dans ~/.dsh/.credentials.yaml, et vos paramètres ne contiennent qu’une référence vers celle-ci. L’interface Web n’affiche plus la clé après son enregistrement.
Un fournisseur personnalisé peut utiliser une variable d’environnement à la place, avec apiKeyEnv. C’est la structure indiquée par la documentation pour ~/.dsh/settings.yaml.
llm-pi-ai:
providers:
my-gateway:
apiKeyEnv: GATEWAY_API_KEY
api: openai-completions
baseURL: https://gateway.example/v1
models:
- id: legacy-chat
- id: vision-preview
input: [text, image]Ajoutez d’abord un fournisseur depuis l’interface Web, puis ouvrez ~/.dsh/settings.yaml et copiez la structure qui y a été écrite. Pendant une preview destinée aux développeurs, c’est l’imbrication qui risque le plus de changer. Le fichier que l’application vient d’écrire est toujours à jour.
apiKeyEnv est lu dans l’environnement du processus dsh, et non dans votre login shell. Une clé exportée dans une session interactive est invisible pour une unité systemd. La même configuration qui fonctionne lorsque vous saisissez dsh web manuellement renvoie donc MISSING_CREDENTIAL avec un service. Fournissez à l’unité son propre fichier.
[Service]
EnvironmentFile=/etc/dsh/dsh.envConservez ce fichier avec le mode 600 et attribuez-le à l’utilisateur sous lequel le service s’exécute.
Choisir les modèles et l’ID que vous ne pouvez pas renommer
Tous les providers configurés apparaissent dans le sélecteur de modèles. La sélection d’un modèle en fait également le modèle par défaut des nouvelles sessions. Les sessions déjà créées conservent le modèle qui y est enregistré. Le changement ne réécrit donc pas une ancienne conversation.
Le Provider ID est permanent. Les requêtes, les sessions enregistrées, les modèles par défaut et les références aux identifiants d’accès pointent tous vers cet ID. Il n’existe donc aucun bouton de renommage. Le modifier revient à créer un nouveau provider, puis à supprimer l’ancien. Choisissez un nom que vous pourrez conserver : local-ollama plutôt que test2.
Les modèles sont limités au texte, sauf indication contraire. Ajoutez input: [text, image] à l’entrée d’un modèle pour déclarer la prise en charge des images, ou définissez defaultInput au niveau de la route comme valeur de repli pour les modèles que le catalogue ne décrit pas. La route chat-completions de DeepSeek est exclusivement textuelle et ne peut pas être configurée autrement. Une image jointe à cette route est donc refusée avant tout envoi.
Pointez dsh vers un endpoint local pour que votre code reste sur la machine
Ollama expose une API compatible avec OpenAI sur http://127.0.0.1:11434/v1. dsh peut utiliser n’importe quelle base URL compatible avec OpenAI via un provider personnalisé. Les deux services peuvent donc communiquer directement. Configurez d’abord le model server : auto-héberger un LLM avec Ollama sur un VPS explique l’installation et le téléchargement du modèle.
Vérifiez que l’endpoint répond avant de configurer dsh.
ollama list
curl -s http://127.0.0.1:11434/v1/modelsollama list affiche le tag exact de chaque modèle téléchargé. Copiez cette chaîne. curl renvoie les mêmes modèles au format JSON. Une liste vide signifie qu’Ollama fonctionne sans modèle téléchargé. Connection refused signifie qu’Ollama n’est pas démarré ou n’écoute pas sur 11434.
Ajoutez maintenant le provider. Ollama exige un champ de clé API, mais ignore sa valeur. Toute chaîne non vide convient donc.
llm-pi-ai:
providers:
local-ollama:
apiKeyEnv: OLLAMA_API_KEY
api: openai-completions
baseURL: http://127.0.0.1:11434/v1
models:
- id: <the exact tag printed by ollama list>Exportez la variable dans l’environnement où le processus dsh pourra la lire.
sudo install -d -m 700 /etc/dsh
printf 'OLLAMA_API_KEY=ollama\n' | sudo tee /etc/dsh/dsh.env
sudo chmod 600 /etc/dsh/dsh.envTrois erreurs couvrent presque tous les échecs possibles. MISSING_CREDENTIAL signifie que dsh n’a pas pu lire la variable nommée par apiKeyEnv. Vérifiez donc l’environnement du processus, et non celui de votre terminal. UNKNOWN_MODEL signifie que le id ne correspond pas à un modèle configuré. Comparez-le caractère par caractère avec ollama list, y compris le tag après les deux-points. Une erreur 401 lors de la récupération des modèles disponibles vient de la découverte des modèles. Celle-ci appelle GET /models sur votre base URL. Les endpoints qui ne fournissent pas ce chemin nécessitent de saisir les modèles manuellement.
La base URL constitue un autre piège. N’y ajoutez pas /v1. Sinon, les requêtes utilisent des chemins qu’Ollama ne fournit pas. L’appel renvoie alors une erreur 404 et le modèle ne s’exécute jamais. Ce suffixe fait partie de l’interface compatible avec OpenAI. Ce n’est pas un élément décoratif.
Si Ollama s’exécute sur une autre machine, l’adresse de cette machine devient la base URL. Vos prompts traversent alors le réseau en clair via HTTP simple. Conservez Ollama sur le même hôte, ou placez-le derrière TLS (transport layer security) et une authentification : sécuriser un endpoint Ollama exposé.
Ce qui quitte la machine dans chaque mode
Avec une clé DeepSeek, chaque requête est envoyée à l’API de DeepSeek. Elle contient votre prompt, le contenu des fichiers que l’agent a lus pour y répondre, la sortie des commandes qu’il a exécutées et les résultats des outils qu’il a choisi d’inclure. Votre code source se trouve dans cette charge utile dès que l’agent a ouvert un fichier. C’est ainsi que fonctionne un modèle hébergé. C’est pourquoi vous devez réfléchir au répertoire depuis lequel vous démarrez l’agent.
Avec un autre fournisseur de catalogue ou une passerelle d’entreprise, la même charge utile est envoyée à ce fournisseur. L’URL de base vous indique précisément sa destination.
Avec un endpoint local, la requête destinée au modèle est envoyée à 127.0.0.1:11434 et reste sur la machine. Aucun élément de votre code n’atteint un fournisseur de modèles. Trois éléments traversent tout de même le réseau. npx télécharge le package depuis le registre npm. Les outils exécutés par l’agent peuvent accéder eux-mêmes à Internet, notamment les serveurs MCP (model context protocol) que vous avez connectés. La page exécuter des serveurs MCP sur un VPS présente ce sujet en détail. Un plugin appartient à la même catégorie. Son installation exécute le code d’un autre auteur avec les permissions de votre agent. Il est donc utile de vérifier ce à quoi un plugin peut accéder avant de l’installer. Il en va de même pour la télémétrie, si vous l’activez.
La télémétrie est désactivée tant que vous ne l’avez pas acceptée. DSH_TELEMETRY_MODE est le paramètre de consentement. Les valeurs absentes, vides ou non reconnues sont interprétées comme DISABLED. Dans cet état, dsh ne construit aucun provider, processor ou exporter OpenTelemetry (OTel). Un profil vierge n’effectue donc aucune requête réseau de télémétrie. FEEDBACK_ONLY active le partage des journaux de session déclenché par les retours. FULL autorise également les rapports du launcher. Le flux de session peut exporter le contenu des sessions, les données des outils, les prompts et les chemins des workspaces. Considérez donc FULL comme l’envoi de votre travail à DeepSeek.
Pour un arrêt complet qui ne dépend pas d’une valeur correcte du mode, définissez DSH_TELEMETRY_DISABLED=1. Toute valeur non vide constitue un refus explicite. Elle est lue avant le démarrage de l’exécution. Le code du projet ne peut donc pas réactiver la télémétrie pendant la session. L’adresse par défaut du collector est harness-telemetry.deepseeksvc.com. Ce nom est utile à connaître lorsque vous consultez les journaux de votre propre firewall.
Vérifiez le paramètre au lieu de lui faire confiance. Lorsqu’une tâche est en cours d’exécution, listez les connexions sortantes détenues par le processus.
sudo ss -tnp | grep -i nodeEn mode modèle local, vous devez voir la connexion loopback vers 11434 et aucune connexion vers une adresse publique. Toute autre connexion doit être identifiée avant de continuer. Ce qu’un agent de programmation envoie à l’extérieur effectue le même contrôle avec d’autres harnesses et explique comment interpréter le résultat.
Où ne pas stocker les secrets
- Historique du shell.
export DEEPSEEK_API_KEY=sk-...est écrit en clair dans~/.bash_historyet y reste longtemps après la rotation de la clé. Préfixez la commande par une espace lorsqueHISTCONTROL=ignorespaceest défini, ou évitez le shell et écrivez directement la valeur dans un fichier avec le mode 600. - Fichiers dotfiles versionnés. Une clé dans
~/.bashrcou~/.zshrcn’est qu’à ungit addd’un dépôt public si vous versionnez les dotfiles avec git. Exécutezgit grep -I -n 'sk-'dans ce dépôt avant le push. settings.yaml. UtilisezapiKeyEnvpour les providers personnalisés, afin que le fichier contienne un nom de variable plutôt qu’un secret. Les fichiers de configuration sont souvent copiés dans les rapports d’incident et les échanges avec le support. Pas les fichiers de credentials.- Sortie de
envet captures d’écran du terminal. Toute commande qui affiche l’environnement complet affiche également la clé. - Sauvegardes.
~/.dshdoit être sauvegardé, mais.credentials.yamlqu’il contient est un secret actif. Excluez ce fichier ou chiffrez l’archive.
Ces règles ne sont pas propres à dsh, et garder les secrets hors des fichiers env de Compose couvre le même problème côté conteneurs sur le même serveur.
Utiliser une version en préversion
Verrouillez la version que vous avez testée, car une préversion peut modifier une clé de configuration dans une mise à jour corrective et votre provider ne se charge alors plus. Si l’installation avec version verrouillée refuse ensuite de démarrer, ou si npx continue de vous fournir un build que vous n’avez pas demandé, les erreurs d’installation et de version produites par une préversion expliquent le cache de npx et la version de npm fournie avec votre version de Node. Conservez settings.yaml et cordis.patch.yml dans le contrôle de version, en excluant le fichier de credentials, afin de voir ce qui a changé après une mise à niveau.
Deux flags sont utiles lorsqu’un profile ne se comporte pas comme prévu. --dump-default-config affiche la configuration par défaut composée sans démarrer le service, et --dump-config affiche de la même manière la configuration composée pour votre profile. La comparaison montre ce que votre couche de surcharge a réellement modifié. C’est plus rapide que de lire les différentes couches manuellement.
dsh --profile web --dump-configLorsqu’un problème apparaît après une mise à niveau, exécutez d’abord cette commande. Une clé déplacée entre deux releases apparaît comme une branche manquante dans le dump. La correction consiste alors à modifier une seule ligne plutôt qu’à réinstaller le logiciel.
FAQ
Où dsh stocke-t-il ma clé API DeepSeek ?
Dans $DSH_HOME/.credentials.yaml, c’est-à-dire ~/.dsh/.credentials.yaml sauf si vous définissez vous-même DSH_HOME. La page Models y écrit la clé, et vos paramètres ne contiennent qu’une référence vers celle-ci. Le secret se trouve donc dans un seul fichier. Vérifiez le mode avec stat -c '%a %n' ~/.dsh/.credentials.yaml et définissez-le sur 600 s’il est moins restrictif. Un fournisseur personnalisé peut éviter complètement ce fichier en indiquant une variable d’environnement avec apiKeyEnv.
Comment faire utiliser à dsh un modèle local au lieu de l’API DeepSeek ?
Ajoutez un fournisseur personnalisé dont l’URL de base pointe vers votre endpoint local compatible avec OpenAI. Pour Ollama, il s’agit de http://127.0.0.1:11434/v1, avec api: openai-completions et un modèle id copié exactement depuis ollama list. Ollama exige une valeur de clé API, mais l’ignore. Toute chaîne non vide convient donc. Vérifiez que l’endpoint répond avec curl -s http://127.0.0.1:11434/v1/models avant de modifier la configuration de dsh, car un endpoint injoignable et une mauvaise configuration produisent des erreurs similaires.
dsh envoie-t-il mon code quelque part par défaut ?
Avec un modèle hébergé, oui. Votre prompt et le contenu des fichiers lus par l’agent se trouvent dans la requête API envoyée à ce fournisseur. Avec un endpoint local, cette requête va vers loopback et reste sur la machine. La télémétrie est un flux distinct et elle est désactivée par défaut : DSH_TELEMETRY_MODE renvoie DISABLED lorsqu’elle n’est pas définie, et aucun exporter n’est créé dans cet état. Définissez DSH_TELEMETRY_DISABLED=1 pour désactiver la télémétrie ; cette valeur est lue avant le démarrage de l’exécution.
Pourquoi dsh signale-t-il MISSING_CREDENTIAL alors que ma variable est définie ?
Parce que dsh lit la variable indiquée par apiKeyEnv dans l’environnement de son propre processus. Une variable exportée dans votre shell n’est pas transmise à un service systemd, à la session d’un autre utilisateur ou à un processus démarré avant son exportation. Placez la valeur dans un EnvironmentFile avec le mode 600 pour l’unité, ou exportez-la dans le même shell que celui qui démarre dsh. Vérifiez ce que contient réellement le processus en cours avec sudo tr '\0' '\n' < /proc/$(pgrep -f dsh | head -1)/environ.
De quelle version de Node.js dsh a-t-il besoin ?
De Node.js 22.19 ou d’une version ultérieure de la ligne 22, ou de Node.js 24 ou ultérieur. Node 23 ne fait pas partie des versions prises en charge. Exécutez node -v avant toute autre chose, car un échec au démarrage dû à un runtime non pris en charge ressemble à une installation défectueuse et incite à réinstaller le package au lieu du runtime.