Configurar dsh con claves API, modelos y endpoints
Aprenda dónde guarda dsh su configuración en Linux, cómo usar una clave de DeepSeek o un endpoint local de Ollama y qué datos salen del equipo en cada modo.
Dónde guarda dsh su configuración
dsh (DeepSeek Harness) guarda su configuración en un único directorio: $DSH_HOME, cuyo valor predeterminado es ~/.dsh. Todo lo que configure en la Web UI se escribe allí como archivos de texto sin formato. Copie ese directorio a otro servidor y el nuevo equipo se comportará como el anterior.
Cuatro rutas contienen todo lo que modificará.
~/.dsh/settings.yamlcontiene la configuración escrita manualmente y desde la UI, incluidas las rutas de proveedores y modelos.~/.dsh/.credentials.yamlcontiene los secretos. La configuración sólo conserva una referencia a una credencial, por lo que el valor de la clave se almacena en un único archivo.~/.dsh/profiles/contiene los perfiles con nombre y~/.dsh/storages/contiene las sesiones guardadas.~/.dsh/cordis.patch.ymles su propia capa de cambios. Se aplica sobre la configuración integrada para cada perfil.
DeepSeek anunció el harness como una versión preliminar para desarrolladores con licencia MIT el 17 August 2026, y el README indica que habrá cambios incompatibles. Los nombres de los campos y las rutas de esta guía coinciden con la documentación del repositorio a fecha de August 2026. Compruébelos en la documentación de la versión instalada antes de copiar la configuración desde cualquier guía, incluida esta, porque una versión preliminar puede cambiar los nombres entre releases.
El mínimo real para obtener la primera salida
dsh necesita Node.js 22.19 o posterior de la línea 22, o Node 24 o posterior. Node 23 queda fuera de ese rango. Compruebe primero la versión, porque una incompatibilidad de versión provoca un fallo durante el arranque y el error parece indicar que el paquete está dañado.
node -v
npx @deepseek-ai/dsh webnpx descarga el paquete del registro de npm e inicia la interfaz web en http://127.0.0.1:3080. Se enlaza a la dirección de loopback, por lo que el puerto no es accesible desde otra máquina aunque el firewall lo permita. En un VPS, reenvíe el puerto mediante SSH en lugar de abrir 3080 a Internet.
ssh -N -L 3080:127.0.0.1:3080 you@your-serverAbra http://127.0.0.1:3080 en su portátil y vaya a Settings y Models. La tarjeta de DeepSeek tiene un único campo para la clave de API. Pegue la clave de platform.deepseek.com y guárdela. La ruta del modelo queda disponible inmediatamente, sin reiniciar, porque el servidor en ejecución almacena la credencial y resuelve la referencia en tiempo real. Acceso a la interfaz web de dsh en un servidor remoto explica el túnel y el caso del reverse proxy, y instalación de DeepSeek Harness en un VPS explica la preparación del servidor que presupone esta guía.
Después de guardar los cambios, revise lo que creó la aplicación.
ls -la ~/.dsh
stat -c '%a %n' ~/.dsh/.credentials.yamlDebería ver settings.yaml, .credentials.yaml y profiles/. Si stat muestra un modo distinto de 600, ejecute chmod 600 ~/.dsh/.credentials.yaml. Un archivo de credenciales legible por el grupo o por cualquier usuario entrega su clave a todas las demás cuentas del servidor.
Para una primera ejecución sin navegador, basta con un comando.
npx @deepseek-ai/dsh --profile headless "summarise the files in this directory"El perfil sin interfaz gráfica ejecuta una única sesión y muestra la respuesta final.
Variables de entorno o archivo de configuración
Hay dos formas de proporcionar una clave a dsh y no son intercambiables.
Un proveedor del catálogo (DeepSeek, Anthropic, OpenAI y el resto de la lista integrada) recibe la clave mediante la página Models. El valor se guarda en ~/.dsh/.credentials.yaml y la configuración sólo conserva una referencia. La Web UI no vuelve a mostrar la clave después de guardarla.
En su lugar, un proveedor personalizado puede indicar una variable de entorno mediante apiKeyEnv. Este es el formato que la documentación proporciona para ~/.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]Añada primero un proveedor mediante la Web UI. Después, abra ~/.dsh/settings.yaml y copie la estructura que se haya escrito. Durante una vista previa para desarrolladores, la anidación es el elemento con más probabilidades de cambiar. El archivo que acaba de escribir la aplicación siempre está actualizado.
apiKeyEnv se lee del entorno del proceso dsh, no del shell de inicio de sesión. Una clave exportada en una sesión interactiva no es visible para una unidad de systemd. Por eso, la misma configuración que funciona al escribir dsh web manualmente devuelve MISSING_CREDENTIAL cuando se ejecuta como servicio. Proporcione a la unidad su propio archivo.
[Service]
EnvironmentFile=/etc/dsh/dsh.envMantenga ese archivo con el modo 600 y asígnelo al usuario con el que se ejecuta el servicio.
Elección de modelos y el ID que no se puede cambiar de nombre
Todos los proveedores configurados aparecen en el selector de modelos. Al seleccionar un modelo, también se establece como predeterminado para las sesiones nuevas. Las sesiones que ya existen conservan el modelo registrado en ellas, por lo que el cambio no modifica una conversación anterior.
El Provider ID es permanente. Las solicitudes, las sesiones guardadas, los modelos predeterminados y las referencias a credenciales apuntan a él, por lo que no existe ningún botón para cambiarle el nombre. Cambiarlo implica crear un proveedor nuevo y eliminar el anterior. Elija un nombre que pueda mantener: local-ollama en lugar de test2.
Los modelos sólo admiten texto, salvo que se indique lo contrario. Añada input: [text, image] a una entrada de modelo para declarar que admite imágenes, o establezca defaultInput en el nivel de la ruta como alternativa para los modelos que no estén descritos en el catálogo. La ruta propia de DeepSeek para chat-completions sólo admite texto y no se puede configurar de otro modo, por lo que una imagen adjunta a esa ruta se rechaza antes de enviar nada.
Apunte dsh a un endpoint local para que el código permanezca en el servidor
Ollama ofrece una API compatible con OpenAI en http://127.0.0.1:11434/v1. dsh puede comunicarse con cualquier URL base compatible con OpenAI mediante un proveedor personalizado, por lo que ambos se conectan directamente. Configure primero el servidor del modelo: alojar un LLM en un VPS con Ollama explica la instalación y la descarga del modelo.
Confirme que el endpoint responde antes de modificar dsh.
ollama list
curl -s http://127.0.0.1:11434/v1/modelsollama list muestra la etiqueta exacta de cada modelo descargado. Copie esa cadena. curl devuelve los mismos modelos en formato JSON. Una lista vacía significa que Ollama está en ejecución, pero no tiene ningún modelo descargado. Connection refused significa que Ollama no está en ejecución o no está escuchando en 11434.
Ahora añada el proveedor. Ollama requiere un campo de clave de API e ignora su valor, por lo que sirve cualquier cadena no vacía.
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>Exporte la variable en un entorno que el proceso de dsh pueda leer.
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.envTres fallos cubren casi todos los intentos de configuración. MISSING_CREDENTIAL significa que dsh no pudo leer la variable cuyo nombre indica apiKeyEnv, así que compruebe el entorno del proceso, no el entorno de su terminal. UNKNOWN_MODEL significa que id no coincide con ningún modelo configurado, así que compárelo con ollama list carácter por carácter, incluida la etiqueta posterior a los dos puntos. Un 401 al obtener los modelos disponibles procede del descubrimiento de modelos, que llama a GET /models en su URL base; los endpoints que no ofrecen esa ruta requieren que los modelos se introduzcan manualmente.
La URL base plantea otro problema frecuente. No omita /v1: las solicitudes llegarían a rutas que Ollama no ofrece, la llamada devolvería un 404 y el modelo no se ejecutaría. El sufijo forma parte de la interfaz compatible con OpenAI; no es decorativo.
Si Ollama se ejecuta en otra máquina, la dirección de esa máquina se convierte en la URL base y las solicitudes cruzan la red en texto claro mediante HTTP sin cifrar. Manténgalo en el mismo servidor o colóquelo detrás de TLS (seguridad de la capa de transporte) y autenticación: proteger un endpoint de Ollama expuesto.
Qué sale del equipo en cada modo
Con una clave de DeepSeek, cada solicitud se envía a la API de DeepSeek. La solicitud contiene el prompt, el contenido de los archivos que el agente leyó para responder, la salida de los comandos que ejecutó y cualquier resultado de herramientas que decidiera incluir. El código fuente queda dentro de esa carga cuando el agente abre un archivo. Así funciona un modelo alojado, y por eso debe tener en cuenta en qué directorio inicia el agente.
Con otro proveedor del catálogo o con una puerta de enlace de la empresa, la misma carga se envía a ese proveedor. La URL base indica exactamente adónde.
Con un endpoint local, la solicitud al modelo se envía a 127.0.0.1:11434 y permanece en el equipo. Ninguna parte del código llega a un proveedor de modelos. Aun así, tres elementos atraviesan la red. npx descarga el paquete del registro de npm. Cualquier herramienta que ejecute el agente puede acceder a Internet por su cuenta, incluidos los servidores MCP (model context protocol) que haya conectado. Ejecutar servidores MCP en un VPS lo explica en detalle. También se envía telemetría si la activa.
La telemetría está desactivada hasta que usted da su consentimiento. DSH_TELEMETRY_MODE es el selector de consentimiento, y los valores no definidos, vacíos o no reconocidos se resuelven en DISABLED. En ese estado, dsh no crea ningún proveedor, procesador ni exportador de OpenTelemetry (OTel), por lo que un perfil nuevo no realiza ninguna solicitud de telemetría a través de la red. FEEDBACK_ONLY activa el uso compartido de registros de sesión cuando se envían comentarios. FULL también permite los informes del lanzador. El flujo de sesión puede exportar contenido de la sesión, datos de herramientas, prompts y rutas del espacio de trabajo. Por tanto, considere que FULL envía su trabajo a DeepSeek.
Para detenerlo por completo sin depender de escribir correctamente la cadena del modo, establezca DSH_TELEMETRY_DISABLED=1. Cualquier valor no vacío es una exclusión voluntaria explícita. Se lee antes de iniciar la ejecución, por lo que el código del proyecto no puede volver a activarla durante la sesión. La dirección predeterminada del colector es harness-telemetry.deepseeksvc.com. Es útil conocerla al revisar sus propios registros del firewall.
Verifique el comportamiento en lugar de confiar en la configuración. Con una tarea en ejecución, muestre las conexiones salientes que mantiene el proceso.
sudo ss -tnp | grep -i nodeEn el modo de modelo local debería ver la conexión de loopback a 11434 y ninguna conexión a una dirección pública. Conviene identificar cualquier otra conexión antes de continuar. Qué envía un agente de programación realiza la misma comprobación con otros harnesses y explica cómo interpretar el resultado.
Dónde no deben almacenarse los secretos
- Historial del shell.
export DEEPSEEK_API_KEY=sk-...se escribe en~/.bash_historyen texto plano y permanece allí mucho después de rotar la clave. Antepon una barra espaciadora al comando cuandoHISTCONTROL=ignorespaceesté establecido, o evita el shell y escribe el valor directamente en un archivo con modo 600. - Archivos dotfiles confirmados en el repositorio. Una clave en
~/.bashrco~/.zshrcestá a ungit addde distancia de un repositorio público si mantienes los dotfiles en git. Ejecutagit grep -I -n 'sk-'en ese repositorio antes de hacer push. settings.yaml. UsaapiKeyEnvpara proveedores personalizados, de modo que el archivo contenga un nombre de variable en lugar de un secreto. Los archivos de configuración se pegan en informes de incidencias y chats de soporte. Los archivos de credenciales no.- La salida de
envy las capturas de pantalla del terminal. Todo lo que muestra el entorno completo también muestra la clave. - Copias de seguridad. Conviene hacer una copia de seguridad de
~/.dsh, pero.credentials.yamlcontiene un secreto activo. Excluye ese archivo o cifra el archivo comprimido.
Estas reglas no son específicas de dsh, y mantener los secretos fuera de los archivos env de Compose aborda el mismo problema en el lado de los contenedores del mismo servidor.
Convivir con una versión preliminar para desarrolladores
Fije la versión que ha probado, porque una versión preliminar puede cambiar una clave de configuración en una versión de corrección y el proveedor puede dejar de cargarse. Mantenga settings.yaml y cordis.patch.yml en el control de versiones, y excluya el archivo de credenciales, para poder ver qué cambió después de una actualización.
Dos opciones ayudan cuando un perfil no se comporta como espera. --dump-default-config muestra la configuración predeterminada compuesta sin iniciar el servicio, y --dump-config muestra del mismo modo la configuración compuesta para su perfil. Compararlas permite ver qué cambió realmente la capa de modificaciones, lo que es más rápido que leer las capas manualmente.
dsh --profile web --dump-configCuando algo se rompe después de una actualización, ejecute primero ese comando. Una clave que se haya movido entre versiones aparece como una rama ausente en el volcado, y la corrección consiste en editar una sola línea en lugar de reinstalar.
FAQ
¿Dónde almacena dsh mi clave de API de DeepSeek?
En $DSH_HOME/.credentials.yaml, que es ~/.dsh/.credentials.yaml salvo que defina DSH_HOME manualmente. La página Models escribe la clave allí y la configuración sólo conserva una referencia, por lo que el secreto queda en un único archivo. Compruebe los permisos con stat -c '%a %n' ~/.dsh/.credentials.yaml y establézcalos en 600 si son menos restrictivos. Un proveedor personalizado puede evitar por completo el archivo si se especifica una variable de entorno con apiKeyEnv.
¿Cómo hago que dsh use un modelo local en lugar de la API de DeepSeek?
Añada un proveedor personalizado cuya URL base sea su endpoint local compatible con OpenAI. Para Ollama es http://127.0.0.1:11434/v1, con api: openai-completions y un modelo id copiado exactamente de ollama list. Ollama requiere un valor para la clave de API, pero lo ignora, por lo que sirve cualquier cadena no vacía. Confirme que el endpoint responde con curl -s http://127.0.0.1:11434/v1/models antes de editar la configuración de dsh, porque un endpoint inactivo y una configuración incorrecta producen errores similares.
¿Envía dsh mi código a algún sitio de forma predeterminada?
Con un modelo alojado, sí. El prompt y el contenido de los archivos que lee el agente se incluyen en la solicitud de API enviada a ese proveedor. Con un endpoint local, la solicitud se dirige a loopback y permanece en el equipo. La telemetría es un flujo independiente y está desactivada de forma predeterminada: DSH_TELEMETRY_MODE se resuelve en DISABLED cuando no está definida y, en ese estado, no se crea ningún exportador. Establezca DSH_TELEMETRY_DISABLED=1 para aplicar una exclusión voluntaria que se lea antes de iniciar la ejecución.
¿Por qué dsh informa de MISSING_CREDENTIAL si mi variable está definida?
Porque dsh lee la variable indicada por apiKeyEnv desde el entorno de su propio proceso. Una variable exportada en su shell no llega a un servicio de systemd, a la sesión de otro usuario ni a un proceso iniciado antes de exportarla. Guarde el valor en un EnvironmentFile con permisos 600 para la unidad o expórtelo en el mismo shell que inicia dsh. Confirme qué contiene realmente el proceso en ejecución con sudo tr '\0' '\n' < /proc/$(pgrep -f dsh | head -1)/environ.
¿Qué versión de Node.js necesita dsh?
Node.js 22.19 o posterior de la línea 22, o 24 y posteriores. Node 23 queda fuera del intervalo compatible. Ejecute node -v antes de cualquier otra acción, porque un fallo de arranque causado por un runtime no compatible parece una instalación dañada y puede llevar a reinstalar el paquete en lugar del runtime.