Skip to content

DeepSeek Harness 系列(三):从源码运行 Web UI

理解架构之后,下一步应该把工程跑起来。DeepSeek Harness 的运行方式分两类:直接用 npm 启动已发布的 dsh,或者从源码构建后启动。前者适合体验,后者适合读源码、改插件和验证架构判断。

本文以当前公开源码快照为依据,梳理从启动到 Web UI 使用的主路径,同时解释几个容易踩的点:Node 版本、profile 初始化、模型配置、工作区选择和配置 dump。

运行方式总览

根 README 给出的快速命令是:

sh
npx @deepseek-ai/dsh web

该命令会启动 Web UI,默认地址是:

text
http://127.0.0.1:3080

如果你要从源码运行,README 给出的流程是:

sh
git clone https://github.com/deepseek-ai/deepseek-harness.git
cd deepseek-harness
pnpm install
pnpm run build
pnpm dsh web

当前源码快照的 package.json 声明了两个重要约束:

当前源码声明
包管理器pnpm@11.7.0
Node 版本`^22.19.0

如果你用 Node 20 启动,后面遇到 node:sqlite 或构建相关问题,不要先怀疑业务代码。先看 Node 版本是否满足根 package.jsonengines 要求。

从源码启动时发生了什么

pnpm dsh web 并不是“直接启动前端”。它会走 CLI,解析 profile,组合 Cordis 配置树,然后启动 Web 表层。

这里有一个很实用的判断:如果服务器没起来,不要只看最后一行报错。启动失败可能来自不同层。

失败位置常见表现应该检查
CLI 参数层flag 不生效、帮助信息不符合预期启动器 flag 必须写在应用参数前面。
profile 层找不到 profile 或 bundle$DSH_HOME/profiles/<name>dsh.profile.bundles
patch 层配置项覆盖后缺字段patch 会替换整条 config,不是深度合并。
Loader 层插件无法加载或依赖等待插件包是否存在,inject 的服务是否挂载。
Web 层前端 dist 不存在是否执行了 pnpm run build
模型层会话无法请求模型设置页模型与凭据配置是否完整。

用配置 dump 看运行真相

DeepSeek Harness 提供了查看最终配置树的方式。

sh
dsh --profile web --dump-config

对于源码运行,也可以通过项目脚本转发:

sh
pnpm dsh --profile web --dump-config

这条命令的意义很大。Profile、bundle、profile patch、home patch、CLI patch 都叠加后,最终到底启用了哪些插件,以 dump 出来的树为准。

我建议把 --dump-config 当成排障入口,而不是最后手段。插件化系统最怕“我以为启用了”,dump 能把猜测变成事实。

配置模型

Web UI 启动后,先进入:

text
设置 -> 模型

DeepSeek 卡片提供 API 密钥字段。保存后,模型路由会在下一次请求生效,不需要重启服务器。源码文档里还有一个值得注意的安全细节:密钥是只写的,保存后页面只拿到脱敏描述符,明文密钥存储在 $DSH_HOME/.credentials.yaml,settings 保存凭据引用。

如果你使用企业网关、自建模型服务或 OpenAI 兼容端点,可以走“添加自定义提供方”。关键字段通常包括:

字段含义
Provider ID稳定路由 id,保存会话和默认模型会引用它。
Base URL模型服务地址。
API 协议例如 OpenAI 兼容协议。
CredentialAPI Key 或环境变量引用。
Models至少声明一个模型 id。

自定义提供方的 Provider ID 不建议随便改。源码文档明确说,它会被请求、已保存会话、默认模型和凭据引用使用。要重命名时,更稳妥的方式是新增提供方,再删除旧提供方。

选择工作区

Web UI 启动时,dsh 进程会把调用目录作为默认文件系统位置,但新的 Web UI 在添加工作区前不会选中任何工作区。你需要在页面里点击“选择工作区”,添加并选中项目目录。

这一步很容易被忽略。没有选中工作区时,会话输入框不可用;这不是模型坏了,而是 Agent 还没有明确的工作空间。

一个最小验证任务

工作区选好后,可以先发送一个低风险任务:

text
Summarize this repository and identify its main packages.

这个任务能验证几件事:

  • 模型路由可用。
  • Agent 能读取工作区。
  • 会话事件能正常渲染。
  • 工具调用权限策略能正常触发。
  • Web UI 能从 session/event 更新状态。

如果这个任务失败,比直接让它改代码更容易定位问题。

Web 模式与 Headless 模式的区别

webheadless 都建立在 dsh-base 上,但表层不同。

Web 模式适合交互式阅读、开发和调试。Headless 模式适合一次性自动化任务:

sh
dsh --profile headless "run the tests and summarize failures"

Headless 不挂 HTTP server,不打开 Web UI。它创建一个新的持久化 Agent,把命令行任务作为普通用户消息提交,等 Agent 停稳后把最后一条非空助手文本写到 stdout。

开发插件时的推荐路径

如果你要基于源码开发插件,不建议一上来就改默认 Agent Loop。更稳的路线是:

这条路线符合 Harness 的架构意图。新增行为尽量作为插件挂入 profile,借助 --dump-config 和 Web UI 验证,而不是在默认循环里加分支。

常见问题速查

问题优先检查
pnpm install 或构建异常Node 是否满足 `^22.19.0
Web URL 没打印配置树可能结算失败,查看启动错误和 Web bundle 是否构建。
页面打开但不能输入是否已添加并选中工作区。
模型报 MISSING_CREDENTIAL设置页是否保存了提供方密钥,或环境变量是否存在。
自定义模型不支持图片自定义模型默认按文本处理,需要在 settings 里声明 input: [text, image]
覆盖配置后启动失败patch 替换整条配置,检查是否遗漏原有必需字段。
某插件似乎没挂上--dump-config,再看条目是否启用、依赖是否满足。

小结

运行 DeepSeek Harness 不难,难的是理解“我启动的到底是哪棵树”。web 不是一个固定内核,而是 dsh-base 加 Web bundle 再叠加用户 patch 的结果。模型配置、工作区选择、工具权限、Web 渲染都只是这棵树上的插件能力。

真正开始做企业接入前,建议先完成三步:能从源码构建并启动 Web;能用设置页配置一个模型;能用 --dump-config 看懂最终配置树。下一篇就用一个匿名化真实业务模式,讨论如何把企业的 AI 任务补偿和异常巡检包装成 Harness 可控工具,而不是让 Agent 直接越过业务系统。

系列导航:上一篇:核心架构与运行时骨架下一篇:接入真实业务的工具化方法