Como configurar o dsh: chaves, modelos e endpoints
Veja onde o dsh salva a configuração no Linux, como usar uma chave DeepSeek ou um endpoint Ollama local e o que sai da máquina em cada modo.
Onde o dsh mantém a configuração
O dsh (DeepSeek Harness) mantém a configuração num único diretório: $DSH_HOME, que por predefinição é ~/.dsh. Tudo o que definir na Web UI é gravado nesse diretório como ficheiros de texto simples. Copie esse diretório para outro servidor e o novo sistema comporta-se como o anterior.
Quatro caminhos contêm tudo o que irá utilizar.
~/.dsh/settings.yamlcontém as definições escritas manualmente e pela UI, incluindo as rotas do seu fornecedor e dos modelos.~/.dsh/.credentials.yamlcontém os segredos. As definições guardam apenas uma referência a uma credencial, pelo que o valor da chave fica num único ficheiro.~/.dsh/profiles/contém os perfis nomeados, e~/.dsh/storages/contém as sessões guardadas.~/.dsh/cordis.patch.ymlé a sua própria camada de patches. Ela é aplicada sobre a configuração integrada para cada perfil.
A DeepSeek anunciou o harness como uma versão de pré-visualização para programadores, licenciada ao abrigo da MIT, em 17 August 2026, e o README indica que haverá alterações incompatíveis. Os nomes dos campos e os caminhos deste guia correspondem à documentação do repositório em August 2026. Compare-os com a documentação da versão que instalou antes de copiar a configuração de qualquer guia, incluindo este, porque uma versão de pré-visualização pode mudar os nomes entre releases.
O mínimo honesto até à primeira saída
dsh requer Node.js 22.19 ou posterior na linha 22, ou Node 24 ou superior. Node 23 fica fora desse intervalo. Verifique primeiro a versão, porque uma incompatibilidade de versão faz o arranque falhar e o erro parece indicar um pacote danificado.
node -v
npx @deepseek-ai/dsh webnpx descarrega o pacote do registo npm e inicia a Web UI em http://127.0.0.1:3080. Faz bind ao endereço de loopback, o que significa que a porta não fica acessível a partir de outra máquina, mesmo quando a firewall permite o acesso. Num VPS, encaminhe a porta através de SSH em vez de expor 3080 à Internet.
ssh -N -L 3080:127.0.0.1:3080 you@your-serverAbra http://127.0.0.1:3080 no seu portátil e aceda a Settings e Models. O cartão DeepSeek tem um único campo para a chave da API. Cole a chave obtida em platform.deepseek.com e guarde-a. A rota do modelo fica imediatamente utilizável, sem reinício, porque o servidor em execução armazena a credencial e resolve a referência em tempo real. Aceder à Web UI do dsh num servidor remoto aborda o túnel e o caso do reverse proxy, e instalar o DeepSeek Harness num VPS aborda a preparação do servidor pressuposta por este guia.
Depois de guardar, verifique o que a aplicação criou.
ls -la ~/.dsh
stat -c '%a %n' ~/.dsh/.credentials.yamlDeverá ver settings.yaml, .credentials.yaml e profiles/. Se stat apresentar um modo diferente de 600, execute chmod 600 ~/.dsh/.credentials.yaml. Um ficheiro de credenciais legível pelo grupo ou por todos os utilizadores expõe a sua chave a todas as outras contas do sistema.
Para a primeira execução sem navegador, basta um comando.
npx @deepseek-ai/dsh --profile headless "summarise the files in this directory"O perfil headless executa uma única sessão e apresenta a resposta final.
Variáveis de ambiente ou ficheiro de configuração
Existem duas formas de fornecer uma chave ao dsh, e não são intercambiáveis.
Um provedor de catálogo (DeepSeek, Anthropic, OpenAI e os restantes da lista integrada) recebe a chave através da página Models. O valor é guardado em ~/.dsh/.credentials.yaml, e as suas definições mantêm apenas uma referência a esse valor. A Web UI nunca volta a mostrar a chave depois de a guardar.
Em alternativa, um provedor personalizado pode indicar uma variável de ambiente através de apiKeyEnv. Esta é a estrutura apresentada pela documentação 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]Adicione primeiro um provedor através da Web UI. Depois, abra ~/.dsh/settings.yaml e copie a estrutura que foi gravada. Durante uma pré-visualização para programadores, o aninhamento é a parte com maior probabilidade de sofrer alterações. O ficheiro que a aplicação acabou de gravar está sempre atualizado.
apiKeyEnv é lido a partir do ambiente do processo dsh, não da sua shell de login. Uma chave exportada numa sessão interativa não fica disponível para uma unidade systemd. Por isso, a mesma configuração que funciona quando escreve dsh web manualmente devolve MISSING_CREDENTIAL num serviço. Forneça à unidade o seu próprio ficheiro.
[Service]
EnvironmentFile=/etc/dsh/dsh.envMantenha esse ficheiro com o modo 600 e atribua-o ao utilizador com que o serviço é executado.
Escolher modelos e o ID que não pode ser renomeado
Todos os provedores configurados aparecem no seletor de modelos. Selecionar um modelo também o define como padrão para novas sessões. As sessões que já existem mantêm o modelo registado nelas, por isso a alteração não reescreve uma conversa antiga.
O Provider ID é permanente. Os pedidos, as sessões guardadas, os modelos predefinidos e as referências a credenciais apontam todos para esse ID, por isso não existe um botão para o renomear. Alterá-lo implica criar um novo provedor e eliminar o antigo. Escolha um nome que possa manter: local-ollama em vez de test2.
Os modelos são apenas de texto, exceto se declarar o contrário. Adicione input: [text, image] a uma entrada de modelo para declarar o suporte a imagens ou defina defaultInput ao nível da rota como fallback para modelos que o catálogo não descreve. A própria rota de chat-completions do DeepSeek aceita apenas texto e não pode ser configurada de outra forma, por isso uma imagem anexada a essa rota é recusada antes de qualquer envio.
Aponte o dsh para um endpoint local para manter o código no servidor
Ollama disponibiliza uma API compatível com OpenAI em http://127.0.0.1:11434/v1. O dsh comunica com qualquer URL base compatível com OpenAI através de um provider personalizado, pelo que os dois comunicam diretamente. Configure primeiro o servidor do modelo: alojar um LLM com Ollama numa VPS explica a instalação e o download do modelo.
Confirme que o endpoint responde antes de configurar o dsh.
ollama list
curl -s http://127.0.0.1:11434/v1/modelsollama list apresenta a tag exata de cada modelo que descarregou. Copie essa string. curl devolve os mesmos modelos em JSON. Uma lista vazia significa que o Ollama está a ser executado sem modelos descarregados. Connection refused significa que o Ollama não está a ser executado ou não está a escutar na porta 11434.
Agora adicione o provider. O Ollama exige um campo de API key e ignora o respetivo valor, pelo que qualquer string não vazia funciona.
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 a variável no ambiente onde o processo dsh a consiga ver.
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.envTrês falhas abrangem quase todas as tentativas. MISSING_CREDENTIAL significa que o dsh não conseguiu ler a variável indicada por apiKeyEnv, por isso verifique o ambiente do processo, não o ambiente do seu terminal. UNKNOWN_MODEL significa que id não corresponde a um modelo configurado, por isso compare-o com ollama list carácter a carácter, incluindo a tag depois dos dois-pontos. Um erro 401 ao obter os modelos disponíveis vem da descoberta de modelos, que chama GET /models na sua URL base; os endpoints que não disponibilizam esse caminho precisam que os modelos sejam introduzidos manualmente.
Existe ainda outro problema comum com a URL base. Não inclua /v1 nela. Caso contrário, os pedidos são enviados para caminhos que o Ollama não disponibiliza, a chamada devolve 404 e o modelo nunca é executado. O sufixo faz parte da superfície compatível com OpenAI; não é apenas decoração.
Se o Ollama for executado noutra máquina, o endereço dessa máquina torna-se a URL base, e os seus prompts atravessam a rede em texto simples através de HTTP sem TLS. Mantenha-o no mesmo host ou coloque-o atrás de TLS (transport layer security) e autenticação: proteger um endpoint Ollama exposto.
O que sai da máquina em cada modo
Com uma chave DeepSeek, cada pedido é enviado para a API da DeepSeek. Esse pedido inclui o seu prompt, o conteúdo dos ficheiros que o agente leu para responder, a saída dos comandos que executou e quaisquer resultados de ferramentas que tenha decidido incluir. O seu código-fonte fica dentro desse conteúdo sempre que o agente abre um ficheiro. É assim que funciona um modelo alojado, e é por isso que deve considerar em que diretório inicia o agente.
Com outro fornecedor do catálogo ou com um gateway da empresa, o mesmo conteúdo é enviado para esse fornecedor. O URL base indica exatamente para onde.
Com um endpoint local, o pedido ao modelo vai para 127.0.0.1:11434 e permanece na máquina. Nenhuma parte do seu código chega a um fornecedor de modelos. Ainda assim, três tipos de tráfego atravessam a rede. npx transfere o pacote do registo npm. Qualquer ferramenta executada pelo agente pode aceder à Internet por conta própria, incluindo servidores MCP (model context protocol) que tenha ligado; executar servidores MCP num VPS explica este caso em detalhe. E existe a telemetria, se a ativar.
A telemetria fica desativada até optar por ativá-la. DSH_TELEMETRY_MODE é a variável de consentimento, e valores não definidos, vazios ou não reconhecidos são resolvidos para DISABLED. Nesse estado, o dsh não cria nenhum fornecedor, processador ou exportador OpenTelemetry (OTel), pelo que um perfil novo não faz qualquer pedido de rede de telemetria. FEEDBACK_ONLY ativa a partilha dos logs da sessão quando há feedback. FULL também permite o envio de relatórios do launcher. O feed da sessão pode exportar conteúdo da sessão, dados das ferramentas, prompts e caminhos do workspace; por isso, considere FULL como o envio do seu trabalho para a DeepSeek.
Para uma interrupção completa que não dependa de definir corretamente a string do modo, defina DSH_TELEMETRY_DISABLED=1. Qualquer valor não vazio é uma desativação explícita, e a variável é lida antes do início da execução; por isso, o código do projeto não a pode reativar durante a sessão. O endereço predefinido do coletor é harness-telemetry.deepseeksvc.com, um nome útil para reconhecer ao consultar os seus próprios logs da firewall.
Verifique em vez de confiar na configuração. Com uma tarefa em execução, liste as ligações de saída mantidas pelo processo.
sudo ss -tnp | grep -i nodeNo modo de modelo local, deverá ver a ligação de loopback para 11434 e nenhuma ligação para um endereço público. Qualquer outra ligação deve ser identificada antes de continuar. O que um agente de programação envia para fora executa a mesma verificação noutros harnesses e explica como interpretar o resultado.
Onde os segredos não devem ser armazenados
- Histórico da shell.
export DEEPSEEK_API_KEY=sk-...é gravado em~/.bash_historyem texto simples e permanece aí muito tempo depois de a chave ser renovada. Prefixe o comando com um espaço quandoHISTCONTROL=ignorespaceestiver definido ou ignore a shell e grave o valor diretamente num ficheiro com modo 600. - Ficheiros dot versionados. Uma chave em
~/.bashrcou~/.zshrcfica a uma alteração degit addde distância de um repositório público se mantiver os ficheiros dot no git. Executegit grep -I -n 'sk-'nesse repositório antes de fazer push. settings.yaml. UseapiKeyEnvpara fornecedores personalizados, para que o ficheiro contenha um nome de variável em vez de um segredo. Os ficheiros de configuração acabam colados em relatórios de problemas e conversas de suporte. Os ficheiros de credenciais não.- Saída de
enve capturas de ecrã do terminal. Tudo o que imprimir o ambiente completo imprimirá também a chave. - Cópias de segurança.
~/.dshdeve ser incluído nas cópias de segurança, mas.credentials.yamldentro dele é um segredo ativo. Exclua esse ficheiro ou encripte o arquivo.
Estas regras não são específicas do dsh, e manter os segredos fora dos ficheiros env do Compose aborda o mesmo problema no lado dos contentores do mesmo servidor.
Trabalhar com uma versão de pré-lançamento
Fixe a versão que testou, porque uma versão de pré-lançamento pode alterar uma chave de configuração numa versão de correção e o seu provider deixa de conseguir carregar. Mantenha settings.yaml e cordis.patch.yml no controlo de versões, excluindo o ficheiro de credenciais, para poder ver o que mudou depois de uma atualização.
Duas flags ajudam quando um perfil não se comporta como esperado. --dump-default-config imprime a configuração padrão composta sem iniciar o serviço, e --dump-config imprime a configuração composta do seu perfil da mesma forma. Comparar as duas mostra o que a sua camada de alterações realmente modificou. Isto é mais rápido do que ler as camadas manualmente.
dsh --profile web --dump-configQuando algo falhar depois de uma atualização, execute primeiro esse comando. Uma chave que mudou de lugar entre versões aparece como uma ramificação ausente no dump. A correção resume-se a editar uma linha, em vez de reinstalar.
FAQ
Onde o dsh armazena a minha chave da API DeepSeek?
Em $DSH_HOME/.credentials.yaml, que é ~/.dsh/.credentials.yaml, a menos que defina DSH_HOME manualmente. A página Models grava a chave nesse local, e as suas definições guardam apenas uma referência para ela. Assim, o segredo fica num único ficheiro. Verifique o modo com stat -c '%a %n' ~/.dsh/.credentials.yaml e defina-o como 600 se for menos restritivo. Um fornecedor personalizado pode evitar completamente o ficheiro ao indicar uma variável de ambiente com apiKeyEnv.
Como faço o dsh usar um modelo local em vez da API DeepSeek?
Adicione um fornecedor personalizado cujo URL base seja o seu endpoint local compatível com OpenAI. No Ollama, esse URL é http://127.0.0.1:11434/v1, com api: openai-completions e um modelo id copiado exatamente de ollama list. O Ollama exige um valor para a chave da API, mas ignora-o. Qualquer cadeia não vazia funciona. Confirme que o endpoint responde com curl -s http://127.0.0.1:11434/v1/models antes de editar qualquer configuração do dsh, porque um endpoint indisponível e uma configuração incorreta produzem erros semelhantes.
O dsh envia o meu código para algum local por predefinição?
Com um modelo alojado, sim. O seu prompt e o conteúdo dos ficheiros lidos pelo agente estão incluídos no pedido enviado à API desse fornecedor. Com um endpoint local, esse pedido vai para o loopback e permanece na máquina. A telemetria é um fluxo separado e está desativada por predefinição: DSH_TELEMETRY_MODE resolve para DISABLED quando não está definida e, nesse estado, não é criado nenhum exporter. Defina DSH_TELEMETRY_DISABLED=1 para optar por não participar; essa opção é lida antes do início da execução.
Por que motivo o dsh comunica MISSING_CREDENTIAL quando a minha variável está definida?
Porque o dsh lê a variável indicada por apiKeyEnv a partir do ambiente do seu próprio processo. Uma variável exportada na sua shell não chega a um serviço systemd, à sessão de outro utilizador ou a um processo iniciado antes da exportação. Coloque o valor num EnvironmentFile com modo 600 para a unidade ou exporte-o na mesma shell que inicia o dsh. Confirme o valor efetivamente disponível no processo em execução com sudo tr '\0' '\n' < /proc/$(pgrep -f dsh | head -1)/environ.
De que versão do Node.js o dsh precisa?
Do Node.js 22.19 ou posterior na linha 22, ou da versão 24 ou posterior. O Node 23 está fora do intervalo suportado. Execute node -v antes de qualquer outra ação, porque uma falha de arranque causada por um runtime não suportado parece uma instalação danificada e leva à reinstalação do pacote, em vez do runtime.