npx @deepseek-ai/dsh web就行。我照着敲了。回车。
然后……就没然后了。
npx 弹了一句"这个包没装过,我给你装一下",之后光标一闪一闪,等了五分钟、十分钟。
我也不想跟它耗,干脆把这活儿丢给了 AI 助手:"你帮我装上,跑起来。"
它折腾了四十多分钟,中间反复试错、自我怀疑,最后总算把它弄通了。这篇文章,就是把这四十分钟里到底发生了什么,原原本本记下来。
一、AI 的第一反应:是不是网的问题
AI 助手接手后,第一反应跟我一样——是不是网慢?
它去翻 npm 的日志,发现 npm 确实在一个一个地拉包的元数据,每个请求都要等上好几秒。而这个 @deepseek-ai/dsh 背后挂着一百多个子包(全是 @deepseek-ai/dsh-* 这种连号包),一百多个包、每个请求几秒,串行拉下去,光元数据就要拉到地老天荒。
"行,网络的问题。"它大概心里是这么判定的。
但等它把网络这关过了,再跑——还是卡。一模一样地卡。
这是排障里最骗人的一刻:你觉得自己找到答案了,其实只扒开了第一层。
二、第二层:npm 没在等网,它在原地"想"
AI 助手换了个角度,盯着任务管理器里那个 node 进程看。
这一看,破案了一半:那个进程,内存一路涨到了 657MB,CPU 疯转,但——这时候网络流量是零。
它根本没在下载,它是在"想"。
想什么呢?想怎么把这一百多个子包摆进依赖树里。npm 有个叫 placeDep 的步骤,专门干这个。日志就冻在 placeDep 那几行,之后再也没动过。
换句话说:网络再快,也救不了一个在原地打转的脑子。
三、解法:换 pnpm
找到"是 npm 的脑子卡住"之后,AI 助手又折腾了好一阵——清缓存、调并发参数、换各种姿势,都没用。npm 那棵依赖树就是算不完。
最后它换了个思路:换一个包管理器,pnpm。
pnpm 用的是另一套解析逻辑,不走 npm 那套来回试错的路子。换过去,8 分钟,445 个包,全部装完,一次过。
同样是"装包",工具不同,结局天差地别。
跑起来的那一刻,它吐出一行:
dsh web: http://127.0.0.1:3080
浏览器打开,DeepSeek Harness 的 Web 界面,安安静静地在那等着。四十分钟,总算落地。

四、不是我一个人:npm 到底为什么卡死
装好之后我好奇:npm 到底为什么卡死?翻了翻社区,发现 GitHub 上早就有人报了几乎一模一样的问题——同样的命令、同样的卡死、同样的 placeDep 冻结、内存涨到几百 MB、卡死时网络零流量,连最后用 pnpm 解开都一样。
链接放这儿,碰上同样情况的可以去对照:
👉 https://github.com/deepseek-ai/deepseek-harness/discussions/3786
那篇讨论还把根因钉得更死:DeepSeek Harness 这套包,子包之间互相声明了大量的"同伴依赖"(peerDependencies),据统计有 110 个,而且互相交叉引用、还有循环。npm 的解析器面对这种结构,会一遍遍回溯、组合爆炸,永远算不完。所以它不是慢,是死循环了。
有个很硬的佐证:同样的命令,只要加一个 --legacy-peer-deps(让 npm 跳过同伴依赖的解析),25 秒就装完了。唯一变的变量就是"解不解析同伴依赖"——这基本等于实锤。
不过 --legacy-peer-deps 不能拿来直接用:跳过之后有十几个"只在同伴依赖里出现"的包不会被装,跑到一半会崩。所以它是个佐证,不是解法。真要省心,还是 pnpm。
所以如果你也打算照着 DeepSeek Harness 的官方文档,用 npx 把它跑起来,结果死活没反应——先别怀疑自己的网,也别跟它死磕。
记住一句话:卡住你的,多半不是网,是 npm 的脑子。换 pnpm 试试:
pnpm dlx @deepseek-ai/dsh web
八成就通了。
排障这事儿最有意思的地方在于:每一层看上去都像是"真相大白",但真正的根因总在更里面。网络是假象,npm 的解析器才是骨头。
夜雨聆风