界面几乎和 Web 端一样,但源码里真正有意思的,是它没有启动本地 Web 服务

这个周末翻 DeepSeek Harness 官方仓库时,我发现 apps 目录里多了一个很难忽略的名字:desktop。
我这边也有一些AI Coding(SDD Agent AI工具等) 和 Node技术交流交流群,感兴趣的可以加微信 ikoala520 进群,一起学习,共同进步。
没错,DeepSeek Harness 已经有桌面客户端了。Git 历史显示,第一批 Electron 打包代码在 8 月 28 日进入仓库,随后又连续补上 Windows 构建、macOS 签名公证、自动更新和启动恢复,直到最近的 0.1.5-rc.2。
不过先别急着找下载按钮。截至 2026 年 9 月 13 日,项目仍处于 Developer Preview,GitHub Releases 里的现有版本没有附带安装包。 普通用户暂时还不能像安装成熟软件一样,下载一个 DMG 或 EXE 双击使用。
想尝鲜,目前最直接的方式是从源码启动开发版:
arduino
# 从源码启动开发版
pnpm install
pnpm run dev:desktop
最省脑子的办法,确实可以把官方 Desktop README 和报错信息一起丢给大模型,让它根据你的系统把依赖补齐、逐步完成编译。
但要提醒一句:源码运行和正式打包不是同一难度。仓库虽然提供了 pnpm run package:desktop 等完整流水线,但支持的发布目标只有 macOS arm64、macOS x64 和 Windows x64,Linux 暂不在范围内;正式 macOS 产物还涉及签名与公证,Windows 正式发布则需要 EV 签名。Windows 提供了未签名测试安装包命令,但这仍不是面向普通用户的一键安装体验。
更准确地说,DeepSeek 现在开源的不是一个"已经发售的桌面产品",而是一套相当完整的桌面端实现与发布流水线。
打开以后,居然和 Web 端几乎没区别
如果你已经用过:
bash
npx @deepseek-ai/dsh web
那么打开 Desktop 后,大概率会产生一种熟悉感:
这不就是 Web 端吗?
整体仍然是 DeepSeek Harness 那套克制的极简风格:左侧是工作区与历史会话,中间是对话区域,底部是输入框;没有复杂的 IDE 面板,也没有满屏按钮。
顶部可以在「对话」与「轨迹」之间切换。模型选择、权限模式、上下文占用和执行状态,都被压缩在输入区附近。
这个极简风,大家能打几分?
不过,"和 Web 端没区别"其实只说对了一半。
从界面看,它们确实高度一致;从运行方式看,Desktop 几乎重新做了一条本地链路。
Desktop 不是重新做了一套 UI,而是给同一套 Harness 前端换了宿主、通信通道和发行边界。
「对话」看结果,「轨迹」看过程
DeepSeek Harness 的界面并不只是一个聊天框。它提供了两种观察 Agent 的方式。
1. 对话:把复杂执行折叠成可读结果
「对话」适合正常使用。
你可以选择工作区、配置模型、输入任务,让 Agent 读取文件、修改代码、执行命令。运行过程中产生的内容会以不同节点进入对话:
- 系统提示词;
- 上下文注入;
- 模型推理;
- 工具调用与工具结果;
- 用户中途追加的指令;
- 最终回复;
- Token 用量与运行耗时。
这些信息不是简单拼成一大段日志。默认的「紧凑」显示会在任务完成后收起中间过程,保留最终答案;需要排查时,再展开工具调用、上下文注入或系统提示词。
尤其值得一提的是系统提示词。代码里的设计目标不是展示一份"近似 Prompt",而是尽可能展示当次请求中模型实际看到的文本。对于研究 Agent 行为、调试 Skill 注入和定位上下文污染,这比普通聊天 UI 有价值多了。
2. 轨迹:把 Agent 还原成事件时间线
「轨迹」更像 Agent 的飞行记录仪。
它会按 Turn 和 Step 组织用户消息、Assistant 输出、工具、嵌套子工具以及上下文压缩记录。点击一条记录,还可以查看:
- 输入和输出;
- Token 用量;
- 开始时间和耗时;
- 图片与附件摘要;
- 工具调用的参数与结果。
顶部还有一条交互式时间概览。Assistant 记录会区分首 Token 延迟与后续解码时间;长会话则采用按需加载和虚拟列表,只渲染当前可见的记录。
所以「轨迹」不是把对话换一种皮肤再显示一次。它直接投影持久化的 Session Event Log,目标是回答三个更工程化的问题:
Agent 当时看到了什么?
它为什么决定调用这个工具?
时间和 Token 到底花在了哪里?
这也是 DeepSeek Harness 最有辨识度的地方之一:它不只想让 Agent 帮你干活,还想让 Agent 的执行过程可以被回放、检查和解释。
桌面端目前具体多了什么?
如果只看主要业务功能,Desktop 和 Web 端确实没有明显断层。两者共享聊天、会话、模型、设置、权限、工具展示和轨迹等客户端能力。
Desktop 真正新增的功能主要在"桌面壳"这一层。
原生工作区选择
Web 组合原本会根据宿主环境,在本机原生选择器和远程可用的目录浏览器之间自适应。Desktop 则固定换成原生目录选择器:用户直接使用操作系统的文件夹选择窗口。
独立插件管理器
应用菜单里有单独的插件管理窗口,支持:
- 查看插件;
- 安装与删除;
- 更新版本;
- 启用或停用;
- 出错时禁用全部插件。
插件发生变化时,Desktop 会先停止 Host,直接修改当前 Desktop Profile,再重新启动。失败后不会偷偷回滚,而是保留现场,交给用户修复或重置。
启动失败恢复
桌面端拥有一个不依赖 Harness Host 的本地启动页。即使后端或插件启动失败,它仍然可以显示错误,并提供重启、禁用插件或重置 Desktop 配置等恢复动作。
这件事听起来很小,却是桌面 Agent 很重要的产品边界:不能因为 Agent Runtime 起不来,连"修复 Runtime"的界面也一起白屏。
自动更新
代码里已经接入 electron-updater。主窗口打开 10 秒后会检查更新,菜单里也提供手动检查入口。
更新的单位不是单独的 Electron 壳,而是:
diff
Electron Shell
+ 匹配版本的 dsh
+ Node.js
+ pnpm
+ 生产依赖树
它们被作为一个签名整体发布,避免桌面壳、Web 客户端、后端和插件依赖图出现版本错配。
它不是简单把 localhost 塞进 Electron

很多 Web 产品做桌面端时,会采用最直接的方式:Electron 启动一个本地 HTTP 服务,然后 BrowserWindow 打开 http://127.0.0.1:xxxx。
DeepSeek Harness Desktop 没这么做。
官方 README 写得很明确:桌面应用不打开监听端口。
它的实际链路可以简化为:
less
共享 Web UI
↓ fetch(dsh-app://app/...)
Electron 主进程的自定义协议处理器
↓ 带版本的分帧字节管道
内置上游 Node.js 子进程
↓
Desktop Host + dsh Runtime + Cordis 插件树
↓
模型、Session、工具、文件系统与权限策略
这里有几个很讲究的实现细节。
1. dsh-app:// 同时承载静态资源和 Fetch
Electron 注册了安全自定义协议 dsh-app://:
dsh-app://shell提供启动页和插件管理器;dsh-app://app提供与后端版本匹配的 Web 资源,并转发 API 与流式响应。
因此 Renderer 看到的仍然是熟悉的 Fetch 接口,但底下已经没有 HTTP 端口、CORS、Host 校验和本地服务端口争用。
2. Electron 不直接运行 dsh
真正的 dsh Runtime 运行在一个独立的上游 Node.js 子进程中,而不是 Electron 自带的 Node 环境。
原因也很现实:Electron 的 Node 带有自己的补丁、ABI、fuse 与生命周期约束,系统 Node 和系统包管理器的版本又不可控。于是 Desktop 把固定版本的 Node.js、pnpm 和完整 dsh 生产依赖树一起带进应用。
这会增加安装体积,却换来了更可预测的运行环境。
3. 数据流和生命周期控制走不同通道
Fetch 请求与流式响应通过带版本的二进制帧在两根管道中传输,单个数据帧上限为 64 KiB,并实现背压与取消。
Node IPC 只处理 ready、fatal、shutdown 这类生命周期消息,不承载大块请求与响应数据。
这是一个很专业的取舍:控制面保持简单,数据面专门为流式传输设计。
4. Renderer 的权限被刻意压窄
BrowserWindow 明确启用了:
vbnet
nodeIntegration: false
contextIsolation: true
sandbox: true
webSecurity: true
应用页面拿不到文件系统、原始 Electron IPC、Shell 或任意 pnpm 参数。普通 dsh 页面甚至只得到一个桌面协议版本标记;插件管理与恢复能力只暴露给 Electron 自己拥有的 Shell 页面。
所以它虽然复用了 Web UI,却没有把整个 Electron 主进程能力一股脑塞进网页。
Desktop 和 Web 端,到底有什么区别?
最直观的答案是:同一张脸,两套宿主。
| 对比项 | Web 端 | Desktop 端 |
|---|---|---|
| 前端界面 | @deepseek-ai/dsh-web-frontend |
复用同一套前端与客户端插件图 |
| 启动方式 | npx @deepseek-ai/dsh web |
Electron 应用或源码启动 |
| 通信方式 | 本地 HTTP/API,默认 127.0.0.1:3080 |
dsh-app:// + 分帧字节管道 |
| 是否监听端口 | 是 | 否 |
| 运行时 | 调用当前安装的 dsh 与 Node 环境 | 携带固定 Node、pnpm、dsh 与生产依赖 |
| 工作区选择 | 根据本机或远程环境自适应 | 固定使用原生系统目录选择器 |
| 插件状态 | Web Profile | 独占 $DSH_HOME/profiles/desktop |
| 远程使用 | 可通过 SSH 转发等方式访问 | 定位为本机桌面应用 |
| 「在本地应用中打开」 | 可由 Web Host 插件提供 | 当前禁用,因为没有 Web Server 路由 |
| 更新方式 | npm/CLI 版本更新 | 壳与完整 Runtime 作为一个签名更新单元 |
两端也不是完全割裂。Desktop 与 CLI 会共享 $DSH_HOME 下受支持的产品数据,例如会话、设置、凭据和工作区。
但它们不会共享可执行包、插件激活状态、锁文件和 node_modules。Desktop 独占自己的 Profile,并通过单实例锁避免两个桌面进程争用同一套插件环境。
这个边界很关键:共享用户数据,但隔离运行时依赖。
为什么界面不重做,反而是对的?
有人可能会觉得,既然做了 Desktop,至少应该换一套更"桌面化"的 UI。
但从工程角度看,DeepSeek 现在的选择更合理。
DeepSeek Harness 的核心定位不是编辑器,也不是把 VS Code 再做一遍。它更像一个可组合、可观察的 Agent Harness。桌面端当前首先解决的是:
- 用户不需要手动启动命令行和本地服务;
- Runtime、前端和依赖版本保持一致;
- 本地通信不暴露端口;
- 插件安装、失败恢复和更新有稳定归属;
- 同一套会话和工具能力获得一个长期运行的桌面入口。
如果为桌面端重新写一套 UI,反而会立刻制造两份交互逻辑、两套插件渲染和两条兼容性链路。
所以现在这种"几乎没区别",不是桌面端没做事,而是它把复杂度放在了用户看不见、但产品迟早绕不过去的地方。
好的桌面壳,不一定让页面变得陌生;它更重要的任务,是让本地 Runtime 变得可安装、可隔离、可恢复、可更新。
现在值得安装吗?
如果你是普通用户,我建议再等等。
当前版本还处于 Developer Preview,官方明确提醒会有破坏性兼容变更;GitHub Release 也没有现成安装资产。为了体验一个与 Web 端高度一致的界面,专门处理编译、签名和运行时依赖,性价比并不高。
但如果你是下面几类人,它已经非常值得读源码:
- 正在开发 Coding Agent 桌面客户端;
- 在研究 Electron 如何安全承载本地 Agent Runtime;
- 想解决本地端口、版本绑定、插件隔离和自动更新问题;
- 想知道"Web UI 复用到桌面端"怎样做得不只是套壳。
我最关注的也不是它现在长什么样,而是 DeepSeek 已经把 Web / CLI / SDK / Desktop 放进了同一套 Harness 组合体系里。
今天的 Desktop 还是一个克制的入口。未来只要继续沿着插件化架构扩展,它完全可能长出更原生的文件预览、系统集成、通知、托盘和跨应用能力,而不需要推翻 Agent Runtime。
我这边也有一些AI Coding(SDD Agent AI工具等) 和 Node技术交流交流群,感兴趣的可以加我微 ikoala520 进群,一起学习,共同进步。
所以,这次更新真正值得注意的不是"DeepSeek 也做 Electron 了"。
而是:
DeepSeek Harness 正在从一个需要命令行启动的开源 Agent 框架,变成一个有完整产品宿主边界的本地 Agent 平台。
至于这套极简界面,你会给几分?