引言:dsh 是什么,为什么值得折腾
如果你在过去一个月里刷到过"三天十几万 Star"的开源项目,那大概率就是它。
DeepSeek Harness(命令行名字 dsh,也常写作 DSH)是 DeepSeek AI 于 2026 年 8 月 13 日发布并开源的 Agent 运行框架,采用 MIT 协议。它的核心设计理念有两个关键词:
everything-is-a-plugin(一切皆插件):模型接入、界面、工具、存储、会话管理全部是插件,可按需挂载与卸载;
Cordis 微内核:内核只负责插件的加载、卸载与依赖解析,能力全部由插件提供。
官方对这个项目有一句提纲挈领的概括:Agent = Model + Harness。模型负责"思考",Harness 负责把模型接入真实环境——注册工具、管理会话、调度任务、提供界面。你可以把它理解成一个"Agent 的操作系统",而不是一个固定的产品。
不过在动手之前,有三件事必须先说清楚:
第一,它还在 developer preview 阶段。 迭代速度极快,官方明确提示会有破坏性兼容变更(breaking changes)。这意味着两件事:一是运行前请务必读一遍仓库里的 SAFETY.md;二是不要把生产环境的命脉押在预览版上。
第二,官方渠道只有两个。 一个是 npm 包 @deepseek-ai/dsh,一个是 GitHub 仓库 deepseek-ai/deepseek-harness。dsh 没有提供 .exe 或 .dmg 之类的图形化安装包,网上任何号称"官方下载站""绿色破解版"的第三方站点都与官方无关,请不要下载。
第三,也是本文的重点——dsh 的 Web 服务默认只监听本机 127.0.0.1:3080,而且作者刻意禁止监听 0.0.0.0。这不是偷懒,而是安全设计。所以"怎么在服务器上装 dsh、然后在笔记本上访问"这个需求,需要一个正确的姿势,本文会用一整章来讲。
一、装之前:环境准备与版本选择
1.1 运行时与工具链
dsh 本身是一个 Node.js 项目,不同安装方式对环境的依赖并不相同:
关于 Node.js 版本,这里必须提醒一句。 我在整理资料时发现各来源的说法并不统一:插件市场文档写的是 18+,部分入门教程用的是 Node 20,云厂商的部署教程则要求 >= 22.19 或 24+,多篇远程访问实战文章也普遍推荐 Node 22 及以上。
这种分歧在快速迭代的预览版项目中很常见。实践建议是:直接使用 Node.js 22 LTS 或更高版本,一次性绕开版本兼容的坑,不要卡在 18 或 20 上省事。
node -v # 建议 v22.x 及以上
npm -v1.2 操作系统支持
Linux、macOS、Windows 均可运行 CLI 与 Web UI。唯一有平台限制的是 Python SDK——它仅支持 Linux(x64 / arm64)与 macOS 14+(arm64),Windows 用户走 SDK 路线需要借助 WSL。
1.3 一个 API 密钥
三种安装方式都绕不开模型接入这一步。你需要准备 DeepSeek 官方 API 密钥,或者任意 OpenAI 兼容端点的密钥(云厂商托管的模型、本地推理服务都可以,后文会给百炼的配置示例)。
准备就绪,开始安装。
二、三种安装方式,按需选择
2.1 方式一:npx 零安装试跑
只想先看看它长什么样,不想污染全局环境:
npx @deepseek-ai/dsh webnpx 会临时下载并执行包,跑完即走。适合"三分钟看看值不值得深入"的场景。
2.2 方式二:npm 全局安装(推荐日常使用)
这是最省心的方式,装完之后随时敲 dsh 就能用:
npm install -g @deepseek-ai/dsh
dsh --version # 验证安装
dsh web # 启动 Web UI配套的日常运维命令也一并记住:
npm view @deepseek-ai/dsh version # 查看最新版本号
npm ls -g @deepseek-ai/dsh # 查看本地已装版本
npm update -g @deepseek-ai/dsh # 更新到最新版(预览版迭代快,建议常更)
npm uninstall -g @deepseek-ai/dsh # 卸载小提示:全局安装时如果遇到权限报错,不要急着 sudo(在 Linux/macOS 上会带来后续权限混乱)。更稳妥的做法是用 nvm 之类的版本管理器,把全局包目录放在用户目录下。
2.3 方式三:源码安装(二次开发与深度调试)
想读源码、改插件、给项目提 PR,或者需要跑仓库里尚未发版的能力,就用源码方式:
npm install -g pnpm
git clone https://github.com/deepseek-ai/deepseek-harness.git
cd deepseek-harness
pnpm install
pnpm run build # 必须先构建
pnpm dsh web # 用工作区内的 dsh 运行源码模式下的几个关键点:
pnpm run build 不能省。没构建就直接跑,会遇到找不到产物的报错。
运行入口用 pnpm dsh <args>,这样会走仓库里的 TypeScript 入口,改动即时可见。
如果 pnpm install 阶段插件构建被安全策略拦截,进入对应 profile 目录执行 pnpm approve-builds 放行即可。
若下载缓慢,配置国内镜像源能显著提速。
2.4 附加选项:Python SDK
如果你的主战场是 Python,官方也提供了 SDK 封装,自带运行时,不依赖系统 Node.js:
python -m venv .venv
. .venv/bin/activate
python -m pip install deepseek-harness-sdk
export DEEPSEEK_API_KEY=sk-your-key-here
# 可选:接入自建或兼容端点
export DEEPSEEK_BASE_URL=http://127.0.0.1:8000/v1
# 可选:指定模型
export DSH_MODEL=deepseek-v4-flashfrom deepseek_harness import DeepSeekHarness注意 SDK 依赖完整的运行时包,如果报"运行时缺失",说明装的是精简包,换成完整版即可。
三、首次启动与三步配置
不管用哪种方式装上,dsh web 启动后默认会打开 Web 界面,地址是:
http://127.0.0.1:3080如果是通过 SSH 连接启动的,dsh 不会尝试自动拉起浏览器(也拉不起来),需要你自己在本地浏览器访问。加 --no-open 可以主动禁用自动打开。
界面起来之后,有三步配置必须走完,否则你会发现输入框是灰的。
第一步:配置模型
进入「设置 → 模型」,填入 API Key,选择模型与 Provider。
这一步的体验设计得不错:模型路由改动立即生效,无需重启服务,可以边试边调。
第二步:选择工作区
添加一个工作区目录,并选中它。这里的"工作区"通常就是你启动 dsh 时所在的目录。
⚠️ 最常见的坑就在这里:在未选中任何工作区之前,会话输入框是不可用的。很多新手以为程序卡住了,其实只是没选目录。
第三步:跑第一个任务
官方推荐的第一个任务非常适合用来验证整条链路:
Summarize this repository and identify its main packages.如果它能正确读取仓库结构并给出合理的总结,说明模型接入、工作区权限、工具调用三件事全部打通了。
顺便认识两个核心概念
配置过程中你会反复遇到两个词,理解它们能省下大量困惑:
Profile(配置文件):一个独立的 Agent 运行环境,包含模型配置、插件集合、会话与存储。可以理解为"一套可切换的 Agent 配置档案"。启动时用 dsh --profile <name> 指定,档案存放在 $DSH_HOME/profiles/ 下。
Bundle(插件包):插件的打包与分发单元,一个 Profile 就是一组有序 Bundle 的集合。
每个 Profile 目录下有两个关键文件:package.json(其中 dsh.profile 字段声明了有序的 bundles 列表与 reload 生命周期)和 cordis.patch.yml(补丁式配置)。
常用的 Profile 与运行命令:
dsh profile create/list/use/remove/export/import <name> # 档案管理
dsh --profile <name> # 启动指定档案
dsh --profile <name> --from-default-profile web # 从模板创建新档案
dsh web # 等价于 --profile web
dsh --profile headless "job" # 一次性运行,适合脚本/CI
dsh --profile acp # ACP 协议档案
dsh --profile sdk / sdk-minimal # SDK 相关档案调试配置时,这两条命令比翻文件快得多:
dsh --profile web --dump-config # 查看合并后的实际配置树
dsh --profile web --dump-default-config # 查看默认配置还有两个容易踩的参数细节:
启动参数在前,应用参数在后。第一个无法识别的 token 起,后面的都当作应用参数透传。比如换端口要这样写:dsh --profile web --port 8080,--port 属于 web 应用而非 dsh 本身。
desktop 是 Electron 的保留档案名,CLI 会拒绝使用。
插件管理统一走 dsh plugin:
dsh plugin --profile web add <包名或仓库地址> # 给档案加插件
dsh plugin --profile <name> <pnpm 参数> # 透传 pnpm 参数四、远程访问:先理解它为什么"不能"直接暴露
这是本文最核心的一节,也是大多数人真正卡住的地方。
4.1 一个刻意的安全设计
dsh 的 Web 服务只监听 127.0.0.1:3080,并且作者故意禁止了 --host 0.0.0.0 这类监听全部网卡的操作,同时没有内置任何认证鉴权机制。
这不是缺陷,是权衡。原因很直白:dsh 是一个能执行代码、读写文件、调用工具的 Agent 运行时。把它以无鉴权状态暴露在公网,等同于把服务器的 shell 权限挂上公网——一旦被扫描到,就是一次远程代码执行(RCE)。作者选择从设计上堵死这条路,把暴露方式的选择权交给用户。
所以你不可能通过"改配置让它监听 0.0.0.0"来实现远程访问。正确的思路是:dsh 老老实实待在本机回环,在它之外叠加一层隧道或组网,并在那一层补上认证。
4.2 那个绕不开的 --trusted-host
在动手之前,还有一个机制必须知道。
dsh 的 /api 接口有一道主机名信任门禁:当请求的 Host 不是回环地址时,必须在启动时用 --trusted-host <domain> 显式声明,请求才会被接受。这也是官方推荐的远程访问方式——先声明信任域,再走隧道。
dsh web --trusted-host your-domain.example.com记住这条命令,下面四套方案都要用到它。
4.3 方案一:SSH 隧道(最省事、最安全)
适用场景:你有一台能 SSH 登录的服务器,只用自己的电脑访问。
原理很简单:把服务器的 3080 端口,"接"到本地某个端口上。
ssh -N -L 13080:127.0.0.1:3080 用户名@服务器IP参数含义:-N 表示只做端口转发不开远程 shell,-L 声明本地转发。执行后保持这个终端不动,在本地浏览器打开:
http://127.0.0.1:13080因为请求从服务器本地回环发起,天然满足 127.0.0.1 约束,连 --trusted-host 都省了(除非你用的是自定义域名)。
让它常驻后台:可以把隧道交给 systemd 托管,实现后台常驻与开机自启。核心是一个 dsh.service 单元,把上面那条 ssh 命令写进 ExecStart,并配置自动重连即可。
Windows 用户的一键脚本:可以写个 .bat,双击就拉起隧道并打开浏览器。不过前提是配置好密钥登录,免去每次输密码:
ssh-keygen -t ed25519
# 然后把公钥追加到服务器的 ~/.ssh/authorized_keys优点:零额外组件、不暴露任何新端口、安全性最高。 缺点:只适合单人单机;隧道断了就得重连;手机等设备不好接。
4.4 方案二:Tailscale(多设备组网 + 自动 HTTPS)
适用场景:你有手机、平板、多台电脑,想让它们都能访问。
Tailscale 基于 WireGuard 组网,会给每台设备分配一个私有 IP,无需公网 IP、无需端口映射。
# 服务器端
curl -fsSL https://tailscale.com/install.sh | sh
sudo tailscale up
tailscale status # 查看组网状态
tailscale ip # 查看分配到的 IP关键一步:Tailscale 可以帮你代理本地服务并自动签发 HTTPS 证书:
tailscale serve --bg 127.0.0.1:3080执行后会得到一个形如 https://<机器名>.<你的tailnet>.ts.net 的地址。
不过要让它真正工作,还有几处必须处理:
先在 Tailscale 后台开启 HTTPS Certificates 功能,否则证书签不出来。
告诉 dsh 你的公网域名。编辑 ~/.dsh/settings.yaml:
remote-web-ui:
publicBaseUrl: "https://<机器名>.<你的tailnet>.ts.net"以信任域重启:
dsh web --trusted-host <机器名>.<你的tailnet>.ts.net首次访问需要设备配对。这是 dsh 内建的一道安全闸。在服务器上执行:
curl -X POST http://127.0.0.1:3080/api/pair/issue -d '{}'会返回一个一次性配对链接,默认 10 分钟有效。用目标设备打开它完成配对。配套的接口还有 /api/pair/status、/api/pair/stop、/api/pair/revoke,可用于查询与管理配对状态。
一个已知坑:如果你跳过配对、直接用 Tailscale 域名访问,可能会遇到 HTTP 403(表现为工作区读取受限)。别慌,这通常不是配置错误,而是信任域或配对未完成的信号,回头检查上面第 3、4 步即可。
顺带一提,tailscale serve 也能代理其他本地服务,换个端口就行:
tailscale serve --bg --https=1145 127.0.0.1:8800优点:多设备统一访问、自动 HTTPS、无需公网 IP、稳定性好。 缺点:需要注册 Tailscale 账号;第一次配 --trusted-host + 配对略繁琐。
4.5 方案三:ZeroNews 内网穿透(不想组网的轻量选择)
适用场景:想用域名访问,又不想折腾 VPN 组网。
流程是标准的内网穿透三步:装客户端 → 用 authtoken 登录 → 在控制台配置隧道。
# 安装后配置
zero news config <your-authtoken>
zero news service install
zero news service start然后在 ZeroNews 控制台添加一个自定义域名,创建指向 127.0.0.1:3080 的 HTTPS 隧道,最后以该域名重启 dsh:
dsh web --trusted-host <你的域名>⚠️ 这里有个绝对不能省的动作:必须叠加 Basic Auth。 内网穿透的域名是暴露在公网的,而 dsh 自身没有鉴权。仅靠 --trusted-host 挡不住扫描器——它只校验 Host 头,伪造起来毫无难度。在此基础上,建议再开启** IP 白名单 / 地址围栏**,把访问来源限制在可控范围。
优点:配置直观、有图形控制台、支持自定义域名。 缺点:流量经过第三方;必须自行补足认证层。
4.6 方案四:frp 反向隧道(不要域名、不要备案)
适用场景:你有一台 VPS,但既不想买域名,也不想折腾 ICP 备案。
思路是 frp 经典的双端结构:VPS 上跑 frps(服务端),内网的台式机上跑 frpc(客户端),由客户端主动外连,从而穿透 NAT。
服务端 frps.toml 关键配置:
bindPort = 7000 # 客户端接入端口
vhostHTTPPort = 7001 # HTTP 访问端口
auth.method = "token"
auth.token = "<你的强口令>"客户端侧用 frp 的 http 类型代理,并通过 httpUser / httpPassword 给反向代理层加上 Basic Auth。
这里有一个非常隐蔽但高频的坑,值得单独拎出来说。
dsh 的前端代码依赖浏览器的 crypto.randomUUID() API,而这个 API 只在安全上下文(HTTPS 或 localhost)下可用。当你通过 http://<公网IP>:<端口> 访问时,浏览器会把页面判定为不安全上下文,crypto.randomUUID 直接不存在,控制台报错:
crypto.randomUUID is not a function页面因此白屏或功能异常。解决方式有两个方向:一是老老实实上 HTTPS;二是向 index.html 注入一段补丁,提供 randomUUID 的降级实现。
关于备案:如果你只用 IP + 高位端口 + HTTP 的方式访问,不绑定域名,就不触发 ICP 备案要求。这也是这套方案最实际的卖点——但代价就是必须自己处理上面那个 crypto.randomUUID 问题。
社区里已经有完整的实践记录可供参考,包括 scripts/restart-dsh-remote.ps1 重启脚本和 docs/WALKTHROUGH.md 全流程说明,仓库地址是 github.com/iloosercontrol/dsh-remote-access。
优点:不需域名、不需备案、完全自控、延迟低。 缺点:需要自己维护 frp 双端;HTTP 下必须打前端补丁。
4.7 四套方案怎么选
一句话总结:自己一个人用,SSH 隧道;多设备用,Tailscale;要域名图省事,ZeroNews 但务必加 Basic Auth;只有 VPS 不想备案,frp。
五、常见问题排错
把踩坑经验整理成一张排查表,遇到问题按图索骥:
另外,dsh 内置了自检命令,遇到说不清的问题可以先跑一遍:
dsh doctor六、总结与展望
回顾整篇内容,dsh 的安装本身并不复杂——npm install -g @deepseek-ai/dsh 一行就能跑起来。真正需要花心思的是两个地方:
一是版本兼容。 项目处于 developer preview,Node.js 版本要求在不同资料里从 18 到 24 都有提及。别在这些细节上赌运气,直接用 Node 22 LTS 或更高,能避开绝大多数环境问题。
二是远程访问的设计哲学。 dsh 只监听 127.0.0.1、禁用 0.0.0.0、不内置鉴权,这不是未完成,而是有意为之的安全边界。它把一个 Agent 运行时的攻击面收敛到最小,然后明确地告诉你:要暴露,请你自己选择暴露的方式,并自己承担责任。
理解了这一点,四套方案的选择逻辑就非常清晰了——在 dsh 之外叠加一层受控的访问通道,并在那层补上认证。SSH 隧道和 Tailscale 之所以推荐度高,正是因为它们天然满足这个原则;而 ZeroNews 和 frp 需要你额外补 Basic Auth,这一步省不得。
展望未来,随着项目从预览走向稳定,有几件事值得期待:更明确的官方版本要求、对远程访问更完善的官方支持(目前 --trusted-host + 设备配对已经是个不错的雏形)、以及插件生态的成熟。dsh-plugin 话题和 dsh-plugin.org 插件市场已经在快速增长,everything-is-a-plugin 的架构优势正在逐步兑现。
现在,去装一个试试吧。第一个任务就用官方推荐的那句话:
Summarize this repository and identify its main packages.参考资料: