dsh 更新后怎么验证有没有生效?DeepSeek Harness 升级顺序与回归验证清单

更新与升级发布于 2026-09-24作者: DeepSeek Plugin 插件市场
DeepSeek HarnessDSH plugindsh 更新回归验证版本快照
dsh 更新不是一条命令的事:先定顺序(先本体后插件,一次只动一类),升级前拍一份版本快照,升级后跑同一条最小回归路径。本文给出快照命令、四步回归清单,以及升级后才出现的版本漂移类次生故障怎么判定与恢复。

dsh 更新要做对两件事:顺序(先本体、后插件,一次只动一类)和验证(升级前拍版本快照,升级后跑同一条最小回归路径)。 少了任一件,升级成功与升级引入的故障就分不开——尤其版本漂移这类只在升级后才出现的崩溃,靠「能启动」是查不出来的。

dsh 更新三步概览:快照、升级顺序、回归

把 dsh 更新当成一次有前后对照的操作,而不是敲一条命令看它跑完。 三步各自不可省(来源):

阶段做什么少了它会怎样
升级前记录版本快照 + 备份数据目录回归失败时没有对照基准,也说不清哪层变了
升级中先本体、后插件,一次只动一类出问题时无法归因,容易反复重装
升级后跑固定四步回归「能启动」被当成「升级成功」,缺陷留到干活时才炸

三步里最容易被跳过的是第一步和第三步。命令细节(npx 自动 / npm update -g / git pull 三条路)已经单独写过,见《dsh 怎么更新》;本文只讲顺序与验证。

第一步:dsh 更新前拍一份版本快照

快照的价值在于「升级后能逐项对照」,所以记的是三层版本,不是只记本体版本。

  1. 记本体版本:
bash
dsh --version          # 全局安装
npx @deepseek-ai/dsh --version   # npx 方式

预期:拿到一个明确版本号,作为回退目标; 2. 记 profile 内的版本清单:

bash
dsh plugin --profile web list

预期:输出当前 profile 的插件包名与版本,这是插件侧的回退目标(来源); 3. 备份数据目录(含配置、会话与插件清单):

bash
cp -r ~/.dsh ~/.dsh.backup-$(date +%Y%m%d)

预期:出现备份目录,出问题时有退路; 4. 把快照存成一处文本 —— 把上面两条命令的输出粘进一个文件。预期:升级后不必靠记忆对比。

第二步:dsh 更新顺序——先本体,后插件

顺序规则只有一条:一次只动一类。 按三步走:

  1. 先升本体:按你当初的安装方式执行(npx 方式每次运行即最新、全局安装 npm update -g @deepseek-ai/dsh、源码 git pull 后重新构建);
  2. 重启并确认进程真的换了:更新改的是磁盘上的包,已在跑的进程仍持有旧代码。预期:重启后 dsh --version 显示新版本;仍显示旧版时按《dsh 更新了版本没变》排 PATH 与缓存,别在这时继续叠加插件更新;
  3. 确认本体回归通过后,再升插件:dsh plugin --profile web update(只升一个插件就带包名)。预期:插件升级是本轮唯一的变化,出了事直接指向插件侧。

为什么不能一起升:本体升级引入的问题与插件升级引入的问题症状高度相似(功能消失、加载报错、工具异常),两类同时变,就只能靠逐个回退来二分,代价远高于分两次做。批量更新的命令与注意事项见《DSH plugin 怎么批量更新》。

第三步:dsh 更新后跑四步回归

回归路径要固定,每一步都有一句可验证的预期——四步全过才算升级完成。

  1. 服务能起来 —— 启动后打开 http://127.0.0.1:3080,或直接探活:
bash
curl -s -o /dev/null -w "HTTP %{http_code}\n" http://127.0.0.1:3080/

预期:页面打得开、返回 HTTP 200;起不来按端口占用与启动失败排查; 2. 模型能回 —— 在会话里发一条不含工具的短消息。预期:正常拿到回复,说明模型与 provider 链路健康(这一步是后面判断「是不是工具层问题」的基线); 3. 工具能跑 —— 让它读一个工作区文件,或执行一条简单的命令。预期:tool/call 有配对的 tool/result,没有报错。这一步是升级回归的关键点:工具分发层的故障常常只在工具调用时才暴露,纯文本回合完全正常(讨论原文); 4. 插件在位 —— 打开「设置 → 插件市场 → 已安装」核对插件仍在、版本与快照对得上;再确认它进了生效层:

bash
dsh --profile web --dump-config | grep -n "^# =="

预期:生效层里仍能看到该插件,层数与升级前一致;插件消失或层数变化,说明升级动到了组合配置。

dsh 更新后才出现的次生故障:版本漂移

有一类崩溃只在升级后才出现,且症状与「更新没生效」完全不像:纯文本正常,一调工具就崩(来源)。 典型表现与判定:

  1. 症状:报错固定为 Cannot read properties of undefined (reading 'prepare'),出现在工具调用之后;会话日志里 tool/call 后面从未写出 tool/result,且连续多个 turn 复现;
  2. 根因:第三方插件把核心包 @deepseek-ai/dsh-tools 声明成直接依赖,profile 里因此解析出一份旧版核心包副本;而调度器键是普通 Symbol() 而非 Symbol.for(),两份副本的键永远不相等,跨份读取就是 undefined(根因确认);
  3. 判定方法:对比本体与 profile 内的核心包版本——不一致即漂移:
bash
dsh --version
ls ~/.dsh/profiles/<name>/node_modules/@deepseek-ai/
  1. 恢复顺序:禁用可疑第三方插件 → 移走 profile 内漂移的核心包副本 → 重启后用新会话验证工具调用。崩溃 turn 遗留的 tool_calls 没有结果,旧会话可能被提供方以 400 INVALID_REQUEST 拒绝,别在同一会话里反复重试。

完整的二分禁用与逐包核对流程见《核心包版本漂移排查》、静态重复副本走《插件重复核心包排查》。这类故障正好说明第三步回归里「让它跑一次工具」不能省——省了它,你会以为升级很成功。

dsh 回归不通过时:单变量回退

回退的原则和升级一样——一次只动一层,把变化量压到最小(来源)。

  1. 先看快照定位变化层:只有本体版本变了,就先钉回本体旧版本(npx @deepseek-ai/dsh@<旧版本> web,或源码版 git checkout <旧 commit> 后重新构建);
  2. 只有某个插件变了,就单独钉回它:dsh plugin --profile web add <包名>@<旧版本>,其余插件保持不动;
  3. 别同时回退本体和插件:那样等于把问题重新盖住,下次升级还会复发;
  4. 留下现场再动手:会话日志与 --dump-config 输出各留一份,回退后才说得清是哪一层的问题。

回滚与降级的完整做法见《更新后不兼容与版本回滚》。

不想手工对快照:用 DSH Plugin Hub 界面核对版本与状态

把「升级前看版本、升级后看状态」交给界面,比手工比命令输出更省事(来源)。 装好 DSH Plugin Hub 后,「设置 → 插件市场 → 已安装」会列出每个 DSH插件的当前版本与「可更新」徽标,升级前先扫一眼就是一份现成的快照;点更新时会先弹出确认窗口,把要执行的操作与你确认一遍。

DSH Plugin Hub 确认更新弹窗

升级确认弹窗把「改哪个插件、从哪个版本到哪个版本」摆在一次确认里,比事后回翻终端输出更容易对照快照。访问 https://dsh-plugin.org/zh/ 即可了解详情。

注意事项:dsh 更新的五条硬约束

这五条是让 dsh 更新可归因、可回退的前提,少一条下次故障就说不清原因(来源)。

  1. 顺序别省:先本体、后插件,一次只动一类——这是让回退能归因的唯一前提。
  2. 快照别省:本体版本、profile 插件清单、数据目录备份,三样齐全才有对照基准。
  3. 回归里必须跑一次工具:只确认「能启动」会漏掉整个工具分发层的问题。
  4. 升级后崩溃先怀疑版本漂移:纯文本正常、工具一调就崩、报错里有 prepare,直接走漂移排查。
  5. 回退保持单变量:同时回退本体与插件,等于放弃了这次排查的全部信息。

来源:dsh CLI README、官方 Quickstart、Discussion #4601、Discussion #4529

常见问题

dsh 更新时先升本体还是先升插件?两者能不能一次性一起升完?

dsh 更新要先升本体、后升插件,而且一次只动一类。DSH 本体与 DSH plugin 走两套完全不同的命令,出问题时必须能归因到「只有一类变了」;在本体与插件之间夹一次批量更新,会让回归失败时无法判断是谁引入的。

dsh 更新后怎么验证是否真的正常生效?四步回归具体分别查什么?

dsh 更新后按四步回归:服务能起来(页面在 127.0.0.1:3080 打得开)、模型能回(发一条最短消息拿到回复)、工具能跑(读一个文件或执行一条命令)、插件在位(已安装列表与生效层里仍能对上)。四步都过才算升级完成。

dsh 升级前要记录哪几项版本信息,具体用什么命令把它们记下来?

dsh 升级前要记三项版本信息:本体版本(dsh --version 或 npx @deepseek-ai/dsh --version)、profile 里的核心包与插件版本(dsh plugin --profile <name> list,或进 profile 目录用 pnpm list)、以及数据目录备份。有了这三项,回归失败时才能判断到底哪一层变了。

dsh 更新后工具调用崩溃报 reading 'prepare',算升级引入的吗?

dsh 更新后工具调用崩溃报 reading 'prepare',只要升级前没有、升级后每次调用都崩,就该按版本漂移排查。根因是第三方插件把核心包声明为直接依赖,profile 解析到旧版核心包,而调度器键是普通 Symbol(),跨两份副本永远不相等,读取结果就是 undefined;禁用可疑插件并清掉副本即可恢复。

dsh 更新后回归不通过时,怎么判断是本体还是某个插件引起的?

dsh 回归不通过时用单变量原则:一次只回退一类,先看快照里哪一层变了——只有本体变了就先钉回本体旧版本;只有某个插件变了就把它单独钉回旧版本。别同时回退本体和插件,那样等于把问题重新盖住,下次还会复发。

相关术语

版本快照
版本快照是升级前记录的本体版本、profile 内核心包与插件版本清单。它是升级后回归失败时的对照基准,用来判断「哪一层变了」,也是回退时的目标版本来源。— dsh CLI README
回归验证
回归验证是升级后按固定的最小路径重跑一遍关键能力——起服务、发消息、跑工具、查插件,确认升级没有破坏原有行为。路径要固定,才能和升级前的状态逐项对照。— DeepSeek Harness 官方文档 - Quickstart
版本漂移
版本漂移指插件把核心包声明为直接依赖后,profile 里解析出一份旧版核心包副本,与本体自带的那份并存。由于调度器键是普通 Symbol(),两份副本的键不相等,导致工具调用时读取失败并崩溃。— deepseek-harness Discussion #4601
单变量回退
单变量回退指回退时一次只改一层——只回退本体,或只回退一个插件——把变化量压到最小,这样下一次回归的结果才能明确指向原因,而不是被新的变量污染。— dsh CLI README

来源