SSD Nodes Learn Hosting plans →
指南 Matt Connor作者: Matt Connor · 更新于 2026-08-25

dsh 配置:API 密钥、模型与端点怎么设置

了解 dsh 在 Linux 中的配置路径,配置 DeepSeek API 密钥或本地 Ollama 端点,并确认两种模式下哪些数据会离开本机。注意 Node.js 仅支持 22.19+ 或 24+,不支持 Node 23。

dsh 的配置存放位置

dsh(DeepSeek Harness)将配置存放在一个目录中:$DSH_HOME,默认路径为 ~/.dsh。您在 Web UI 中设置的任何内容都会以纯文本文件形式写入该目录。将此目录复制到另一台服务器后,新服务器的行为就会与原服务器一致。

以下 4 个路径包含您会用到的全部内容。

  • ~/.dsh/settings.yaml 存放手动编写以及通过 Web UI 写入的设置,包括提供商和模型路由。
  • ~/.dsh/.credentials.yaml 存放密钥。设置中只保存凭据引用,密钥值本身位于其中的一个文件中。
  • ~/.dsh/profiles/ 存放命名配置文件,~/.dsh/storages/ 存放已保存的会话。
  • ~/.dsh/cordis.patch.yml 是您自己的补丁层。对于每个配置文件,它都会覆盖内置配置。

DeepSeek 于 17 August 2026 将该 harness 发布为采用 MIT 许可证的开发者预览版,README 说明后续会有不兼容的变更。本指南中的字段名和路径与 2026 年 8 月的仓库文档一致。在从任何指南(包括本指南)复制配置之前,请根据您所安装版本的文档进行核对,因为预览版会在不同发行版本之间重命名配置项。

首次输出的最低实际要求

dsh 需要 22 系列中的 Node.js 22.19 或更高版本,或者 Node.js 24 及更高版本。Node 23 不在支持范围内。先检查版本,因为版本不匹配会导致启动失败,而错误信息看起来像软件包损坏。

node -v
npx @deepseek-ai/dsh web

npx 会从 npm 注册表下载软件包,并在 http://127.0.0.1:3080 上启动 Web UI。它绑定 loopback 地址,这意味着即使防火墙允许该端口,其他计算机也无法访问。在 VPS 上,应通过 SSH 转发,而不是将 3080 暴露到互联网。如果输出的 URL 令人困惑,dsh 为什么会在该地址启动会解释 loopback 绑定能防止什么,以及不能防止什么。

ssh -N -L 3080:127.0.0.1:3080 you@your-server

在笔记本电脑上打开 http://127.0.0.1:3080,然后进入 Settings 和 Models。DeepSeek 卡片中只有一个 API key 字段。粘贴来自 platform.deepseek.com 的密钥并保存。模型路由会立即可用,无需重启,因为运行中的服务器会保存凭据,并实时解析该引用。在远程服务器上访问 dsh Web UI介绍 SSH 隧道和反向代理场景,在 VPS 上安装 DeepSeek Harness介绍本指南假设已完成的服务器准备工作。

保存后,查看应用创建的内容。

ls -la ~/.dsh
stat -c '%a %n' ~/.dsh/.credentials.yaml

您应看到 settings.yaml、.credentials.yaml 和 profiles/。如果 stat 输出的模式不是 600,请运行 chmod 600 ~/.dsh/.credentials.yaml。组可读或全局可读的凭据文件会将您的密钥提供给服务器上的所有其他账户。

首次运行且不使用浏览器时,一个命令就足够了。

npx @deepseek-ai/dsh --profile headless "summarise the files in this directory"

无头配置文件会运行单个会话,并输出最终答案。

环境变量或配置文件

向 dsh 提供密钥有两种方式,二者不能互换。

目录中的提供商(DeepSeek、Anthropic、OpenAI 以及内置列表中的其他提供商)通过 Models 页面获取密钥。密钥值会写入 ~/.dsh/.credentials.yaml,设置中只保存对它的引用。保存后,Web UI 不会再次显示该密钥。

自定义提供商也可以改为指定环境变量,使用 apiKeyEnv。文档为 ~/.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]

先通过 Web UI 添加一个提供商,然后打开 ~/.dsh/settings.yaml,复制其中写入的结构。在开发者预览期间,最可能发生变化的是嵌套结构;应用刚刚写入的文件始终是最新格式。

apiKeyEnv 读取的是 dsh 进程的环境变量,而不是登录 shell 的环境变量。在交互式会话中导出的密钥对 systemd 单元不可见,因此手动输入 dsh web 时可以正常工作的相同配置,在服务中会返回 MISSING_CREDENTIAL。为该单元单独创建一个文件。

[Service]
EnvironmentFile=/etc/dsh/dsh.env

将该文件的权限设为 600,并将所有者设为运行服务的用户。

选择模型,以及无法重命名的 ID

每个已配置的提供商都会出现在模型选择器中。选择某个模型后,它也会成为新会话的默认模型。已经存在的会话会保留其中记录的模型,因此切换模型不会改写旧对话。

Provider ID 是永久的。请求、已保存的会话、模型默认值和凭据引用都指向该 ID,因此没有重命名按钮。更改它意味着创建新的提供商并删除旧的提供商。请选择一个长期可用的名称:local-ollama,而不是 test2。

除非另行声明,否则模型仅支持文本。在模型条目中添加 input: [text, image] 可声明其支持图像;也可以在路由级别设置 defaultInput,作为目录未描述的模型的回退配置。DeepSeek 自有的 chat-completions 路由仅支持文本,无法进行其他配置,因此发送到该路由的图像附件会在实际发送前被拒绝。

将 dsh 指向本地端点,让代码留在本机

Ollama 在 http://127.0.0.1:11434/v1 提供兼容 OpenAI 的 API。dsh 通过自定义 provider 连接到任意兼容 OpenAI 的基础 URL,因此两者之间无需额外组件。先设置模型服务器:在 VPS 上使用 Ollama 自托管 LLM介绍安装和拉取模型的步骤。

操作 dsh 前,先确认端点能够响应。

ollama list
curl -s http://127.0.0.1:11434/v1/models

ollama list 会输出已拉取的每个模型的确切标签。复制该字符串。curl 会以 JSON 返回相同的模型列表。空列表表示 Ollama 正在运行,但尚未拉取任何模型。Connection refused 表示 Ollama 未运行,或未监听 11434。

现在添加 provider。Ollama 要求填写 API key 字段,但会忽略其值,因此任意非空字符串都可以。

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>

在 dsh 进程能够读取的位置导出该变量。

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.env

几乎所有尝试都可归结为以下 3 类故障。MISSING_CREDENTIAL 表示 dsh 无法读取 apiKeyEnv 指定的变量,因此应检查进程的环境,而不是终端的环境。UNKNOWN_MODEL 表示 id 与已配置的模型不匹配,因此应逐字符与 ollama list 比较,包括冒号后的标签。获取可用模型时出现 401,原因是模型发现过程会在基础 URL 上调用 GET /models;不提供该路径的端点需要手动填写模型。

基础 URL 还有一个常见问题。不要省略其中的 /v1,否则请求会发送到 Ollama 未提供的路径,调用将返回 404,模型也不会运行。该后缀是兼容 OpenAI 接口的一部分,不是装饰性内容。

如果 Ollama 运行在另一台机器上,则将该机器的地址设为基础 URL;之后,提示词会通过未加密的普通 HTTP 在网络中传输。应让 Ollama 与 dsh 运行在同一主机上,或将其置于 TLS(传输层安全)和身份验证之后:保护暴露的 Ollama 端点。

每种模式下哪些内容会离开本机

使用 DeepSeek key 时,每个请求都会发送到 DeepSeek 的 API。请求中包含您的提示词、代理为回答提示词而读取的文件内容、代理执行的命令输出,以及代理选择包含的工具结果。只要代理打开过某个文件,您的源代码就会出现在该请求中。这是托管模型的工作方式,也是您需要考虑从哪个目录启动代理的原因。

使用其他目录中的 provider 或公司网关时,相同的请求内容会发送到对应的供应商。base URL 会明确告诉您请求的目标位置。

使用本地 endpoint 时,模型请求会发送到 127.0.0.1:11434,并留在本机。您的代码不会发送给任何模型供应商。但仍有 3 类内容会通过网络传输。npx 会从 npm registry 下载软件包。代理运行的任何工具都可能自行访问互联网,包括您连接的 MCP(model context protocol)服务器;在 VPS 上运行 MCP 服务器对此有详细说明。插件也属于同一类,因为安装插件会以代理的权限运行其他作者的代码。因此,安装前最好检查插件可以访问哪些内容。如果您启用了 telemetry,telemetry 也会产生网络传输。

在您主动选择加入前,telemetry 处于关闭状态。DSH_TELEMETRY_MODE是同意开关;如果该变量未设置、为空或值无法识别,结果都会解析为 DISABLED。在此状态下,dsh 不会构造 OpenTelemetry(OTel)provider、processor 或 exporter,因此新 profile 完全不会发起 telemetry 网络请求。FEEDBACK_ONLY表示选择加入由反馈触发的会话日志共享。FULL还会允许上报 launcher 信息。会话 feed 可以导出会话内容、工具数据、提示词和工作区路径,因此应将 FULL 视为把您的工作发送给 DeepSeek。

如果需要不依赖正确设置 mode 字符串的强制停用方式,请设置 DSH_TELEMETRY_DISABLED=1。任何非空值都会被视为明确退出,并且该值会在运行开始前读取,因此项目代码无法在会话期间重新启用它。默认 collector 地址是 harness-telemetry.deepseeksvc.com。查看自己的防火墙日志时,了解这个地址很有用。

不要只信任配置,应进行验证。运行任务时,列出该进程当前持有的出站连接。

sudo ss -tnp | grep -i node

在本地模型模式下,您应看到连接到 11434 的 loopback 连接,而不应看到连接到公网地址的连接。其他任何连接都应先确认用途,再继续操作。编程代理会向外发送哪些内容会对其他 harness 执行相同检查,并说明如何读取结果。

不应存放敏感信息的位置

  • Shell 历史记录。export DEEPSEEK_API_KEY=sk-... 会以明文写入 ~/.bash_history,即使轮换密钥后也会长期保留。设置 HISTCONTROL=ignorespace 时,在命令前加一个空格;或者跳过 Shell,直接将值写入权限模式为 600 的文件。
  • 已提交的点文件。如果将点文件纳入 git 管理,~/.bashrc 或 ~/.zshrc 中的密钥只需 git add 步就可能进入公共仓库。推送前,在该仓库中运行 git grep -I -n 'sk-'。
  • settings.yaml。对于自定义提供商,使用 apiKeyEnv,这样文件中保存的是变量名,而不是敏感信息。配置文件经常会被粘贴到问题报告和支持聊天中,凭据文件不会。
  • env 的输出和终端截图。任何会输出完整环境变量的命令,也会同时输出密钥。
  • 备份。~/.dsh 值得备份,但其中的 .credentials.yaml 是有效的敏感信息。排除该文件,或加密归档。

这些规则并非 dsh 特有,避免将敏感信息放入 Compose 环境文件介绍了同一台服务器容器侧的相同问题。

使用开发者预览版

请固定已测试的版本,因为预览版可能在补丁版本中更改配置键,导致您的 provider 无法加载。如果固定版本的安装随后拒绝启动,或者 npx 仍不断提供您未请求的构建版本,请参阅预览版产生的安装和版本错误,其中介绍 npx 缓存以及 Node 随附的 npm。将 settings.yaml 和 cordis.patch.yml 纳入版本控制,同时排除凭据文件,这样升级后即可查看具体发生了哪些变化。

配置文件的行为不符合预期时,以下两个标志很有帮助。--dump-default-config 会在不启动服务的情况下输出组合后的默认配置,--dump-config 则以相同方式输出您配置文件的组合配置。比较两者即可看出补丁层实际修改了哪些内容,比手动阅读各层配置更快。

dsh --profile web --dump-config

升级后出现问题时,先运行该命令。配置键在不同版本之间移动后,会在转储结果中显示为缺失的分支;此时只需修改一行,无需重新安装。

FAQ

dsh 将 DeepSeek API 密钥存储在哪里?

密钥存储在 $DSH_HOME/.credentials.yaml 中;如果未自行设置 DSH_HOME,其值就是 ~/.dsh/.credentials.yaml。Models 页面会将密钥写入该文件,而设置中只保存对它的引用,因此密钥只存在于一个文件中。使用 stat -c '%a %n' ~/.dsh/.credentials.yaml 检查文件权限;如果权限比 600 更宽松,请将其设置为 600。自定义 provider 可以通过 apiKeyEnv 指定环境变量,从而完全避免使用该文件。

如何让 dsh 使用本地模型,而不是 DeepSeek API?

添加一个自定义 provider,并将其 base URL 设置为本地的 OpenAI 兼容端点。对于 Ollama,该地址是 http://127.0.0.1:11434/v1;将 api: openai-completions 设置为从 ollama list 原样复制的模型名称 id。Ollama 要求提供 API key 值,但会忽略该值,因此使用任意非空字符串即可。在修改 dsh 配置前,使用 curl -s http://127.0.0.1:11434/v1/models 确认端点能够响应,因为端点不可用和配置错误会产生相似的错误。

dsh 默认会将我的代码发送到其他地方吗?

使用托管模型时,会发送。您的提示词以及代理读取的文件内容都会包含在发送给该供应商的 API 请求中。使用本地端点时,请求会发送到 loopback,并保留在本机上。Telemetry 是独立的数据流,默认关闭:未设置时,DSH_TELEMETRY_MODE 的值为 DISABLED,在这种状态下不会创建 exporter。设置 DSH_TELEMETRY_DISABLED=1 可选择退出;该设置会在运行开始前读取。

为什么 dsh 在我的变量已设置时仍报告 MISSING_CREDENTIAL?

因为 dsh 会从自身的进程环境中读取由 apiKeyEnv 指定名称的变量。在 shell 中导出的变量不会传递给 systemd 服务、其他用户的会话,或在导出变量之前启动的进程。将该值写入 EnvironmentFile,并为该 unit 设置 600 权限;或者在启动 dsh 的同一个 shell 中导出变量。使用 sudo tr '\0' '\n' < /proc/$(pgrep -f dsh | head -1)/environ 确认运行中的进程实际持有哪些环境变量。

dsh 需要哪个 Node.js 版本?

Node.js 22.19 或 22 系列中的更高版本,或者 Node.js 24 及更高版本。Node 23 不在支持范围内。首先运行 node -v,因为不受支持的运行时导致的启动失败看起来像安装损坏,可能会让用户重新安装 package,而不是修复运行时。