SSD Nodes Learn 🎉 VPS $5.50/月起
指南 Matt Connor作者: Matt Connor · 更新于 2026-08-21

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

了解 dsh 在 Linux 中的配置路径,配置 DeepSeek API 密钥或本地 Ollama 端点,并确认两种模式下究竟有哪些数据会离开本机。

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 需要 Node.js 22.19 或更高的 22.x 版本,或 24 及更高版本。Node 23 不在支持范围内。请先检查版本,因为版本不匹配会导致启动失败,而错误信息看起来像是软件包损坏。

node -v
npx @deepseek-ai/dsh web

npx 从 npm registry 下载软件包,并在 http://127.0.0.1:3080 启动 Web UI。它绑定到 loopback 地址,因此即使防火墙允许该端口,其他机器也无法访问。在 VPS 上,应通过 SSH 转发,而不是将 3080 暴露到互联网。

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介绍隧道和反向代理场景,在 VPS 上安装 DeepSeek Harness介绍本指南假定的服务器准备步骤。

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

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

你应该会看到 settings.yaml.credentials.yamlprofiles/。如果 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,因此没有重命名按钮。更改 ID 就意味着创建新的提供商并删除旧提供商。请选择一个长期使用的名称:local-ollama,而不是 test2

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

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

Ollama 在 http://127.0.0.1:11434/v1 提供兼容 OpenAI 的 API。dsh 可通过自定义提供程序连接到任意兼容 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。

现在添加提供程序。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 密钥时,每个请求都会发送到 DeepSeek API。请求中包含您的提示词、代理为回答提示词而读取的文件内容、代理执行的命令输出,以及代理选择包含的工具结果。只要代理打开过某个文件,您的源代码就会包含在该请求中。这是托管模型的工作方式,因此您需要考虑从哪个目录启动代理。

使用目录中的其他服务商或公司网关时,相同的请求载荷会发送到相应服务商。基础 URL 会明确告知您请求的目标位置。

使用本地端点时,模型请求会发送到 127.0.0.1:11434,并留在本机。您的代码不会到达任何模型服务商。仍有 3 类数据会经过网络。npx 会从 npm registry 下载软件包。代理运行的任何工具都可以自行访问互联网,包括您连接的 MCP(模型上下文协议)服务器;在 VPS 上运行 MCP 服务器对此有详细说明。此外,如果您启用了遥测,遥测数据也会经过网络。

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

如果要执行不依赖正确模式字符串的强制停用,请设置 DSH_TELEMETRY_DISABLED=1。任何非空值都会被视为明确的退出选择。该值会在运行开始前读取,因此项目代码无法在会话中途重新启用遥测。默认 collector 地址为 harness-telemetry.deepseeksvc.com;查看您自己的防火墙日志时,记住这个名称会很有用。

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

sudo ss -tnp | grep -i node

在本地模型模式下,您应看到连接到 11434 的回环连接,且不应看到连接到公网地址的连接。发现其他连接时,应先确认其用途,再继续操作。编程代理会向外发送哪些数据会对其他 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 无法加载。将 settings.yamlcordis.patch.yml 纳入版本控制,但排除凭据文件,这样升级后可以查看具体变化。

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

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。自定义 provider 可以通过使用 apiKeyEnv 指定环境变量来完全避免使用该文件。

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

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

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

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

为什么我已经设置变量,dsh 仍报告 MISSING_CREDENTIAL?

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

dsh 需要哪个 Node.js 版本?

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