离线与内网里用 npx @deepseek-ai/dsh web:DSH plugin 镜像与缓存预热
在离线与内网环境里跑 DeepSeek Harness 的 npx @deepseek-ai/dsh web,本质是回答一个问题:包从哪来。 npx 假设能访问源,所以要么有私有 registry、要么提前预热缓存、要么把包体搬进去,三种路对应三种网络条件。还有一个很坑的细节:代理变量设成空字符串会被当成有效值,导致子进程静默直连。
DeepSeek Harness 离线前先分清三种「没网」
一句话结论:完全离线走缓存预热,有内网源走私有 registry,只能走代理就只解决代理变量——三者不是同一套方案,混着用会互相掩盖问题。
| 环境 | 网络条件 | 推荐方案 | 关键动作 |
|---|---|---|---|
| 完全离线 | 无任何外网,也无内网源 | 方案 B(缓存预热)或方案 C(离线介质) | 在有网机器上预下载,把缓存/包体搬进去 |
| 有内网源 | 能访问企业私有 registry | 方案 A(私有 registry) | 本体与插件包都同步进源 |
| 只能走代理 | 有外网但必须经代理 | 方案 A + 代理变量 | 代理变量填对、不留空 |
方案 A:私有 registry 镜像(企业首选)
一句话结论:把 registry 指向私有源,npx 与插件安装都会跟随——前提是本体与你要装的插件包(含依赖)都已同步进该源**,否则会出现「装得上本体、装不上插件」。**
- 配置源(项目级
.npmrc最稳,避免污染全局):
# .npmrc
registry=https://你的私有源地址/
- 验证源已生效:
npm config get registry
# 预期:输出你的私有源地址,而不是公网默认源
- 先装本体、再逐条装插件:
npx -y @deepseek-ai/dsh@0.2.0-rc.2 web --port 3080
# 预期:从私有源解析并启动;若报 404,说明该版本未同步进源
- 在私有源里补齐插件包:想装哪些 DSH plugin,先用 DSH Plugin Hub 挑定清单,再把这批包与依赖同步进私有源——清单先定、同步一次做完,比装一个补一个省事。
- 把「可装范围」写进内网文档:明确写清哪些包已同步、版本是什么,能避免同事反复试错。
方案 B:预下载 + 缓存预热(只能搬缓存时用)
一句话结论:在有网机器上把包下载进缓存目录,再把缓存整体搬到离线机器复用——不需要自建源,适合一次性交付或少量机器。
- 有网侧预热:
npm cache add @deepseek-ai/dsh@0.2.0-rc.2
npm cache verify
# 预期:缓存目录中出现该包条目
- 找到并搬走缓存目录(默认在用户目录下的 npm 缓存路径,可先用
npm config get cache确认)。 - 离线侧指定同一缓存目录后再执行:
npx --offline -y @deepseek-ai/dsh@0.2.0-rc.2 web --port 3080
# 预期:不发起网络请求即可启动;缺包时会明确报错而不是静默挂起
- 插件同样要预热:把要装的插件包一并
npm cache add进来,否则离线侧只有本体能跑。 - 取舍:预热缓存与机器/Node 版本绑定较松,但对原生模块不友好——离线机器架构与预热机器不同时,仍需在离线侧编译。
方案 C:把包体搬进去(最原始也最可靠)
一句话结论:把包体(.tgz)拷进去、用本地文件路径安装或执行,是网络隔离最严时的兜底做法。
- 有网侧打包:
npm pack @deepseek-ai/dsh@0.2.0-rc.2
# 预期:当前目录出现 @deepseek-ai-dsh-0.2.0-rc.2.tgz 一类文件
- 离线侧安装或直接执行本地包,不再依赖任何源:
npm i -g ./deepseek-ai-dsh-0.2.0-rc.2.tgz
dsh --version
- 插件同理,逐个
npm pack后带进去。 - 记一张「带进去了什么」的清单:包名 + 版本 + 数量,交付时和接收方对一次——这类场景最怕的是「以为带全了」。
DSH plugin 镜像与代理的环境变量:三种写法与那个空值坑
一句话结论:变量只有两条纪律——该有的填对、不该有的取消设置;最坑的不是填错,而是留空。
- 只在需要时设代理(示例,按你的实际代理地址替换):
export HTTPS_PROXY=http://127.0.0.1:7890
export HTTP_PROXY=http://127.0.0.1:7890
- 不需要代理就彻底取消设置,不要留空串:
unset HTTPS_PROXY HTTP_PROXY
env | grep -i proxy # 预期:无相关输出(而不是输出 "xxx_PROXY=")
- 空值的后果要说清:空字符串会被当成有效值传给子进程,并可能触发本为特定代理场景保留的清理逻辑,结果子进程静默直连——在离线与内网里表现为「明明配了代理却拉不到包」,而且在宿主侧看不出异常。
- 顺手排查一次全环境:
env | grep -iE '(proxy|no_proxy)=',把空值项找出来逐个处理。
怎么验证 DeepSeek Harness 真的走了镜像、真的离线可用
一句话结论:最硬的验证是把公网掐掉再跑一次**;最软的验证是看配置与日志里的地址——两者都做一遍才放心。**
- 查配置生效值:
npm config get registry与npm config list,确认没有更高优先级的配置覆盖你写的源。 - 看下载日志的请求地址:安装输出里出现私有源域名即正确;出现公网域名说明配置没生效。
- 断网验证(最硬):屏蔽公网后重跑一次——能装上就是真离线可用;报错则回到方案 A/B 补齐包。
--offline验证缓存:给 npx 加--offline强制只用缓存,用来确认预热是否完整。- 插件功能验一遍:本体能起不等于插件能用,装完实际调用一次插件功能再收工。
DSH plugin 离线排查注意事项
一句话结论:离线场景的失败几乎全是「包不在」,而不是「命令不对」——排查顺序是先确认包在不在,再看命令对不对。
- 先列清单再动手:本体 + 插件的包名与版本先写下来,同步/搬运完成后逐项核对。
- 区分「本体缺」与「插件缺」:报 404 的包名是哪一层,决定了你去补源还是补缓存。
- 代理变量的空值先排掉,它会让所有网络类排查失真。
- 原生依赖单独安排:离线机器架构不同时预编译产物不可复用,提前确认或改用纯 JS 插件。
- 别在离线环境里反复重试:重试不会让包出现,回头补包才是解法。
- 修复状态如实:本文方案基于 npm 官方 registry 与 npx 文档的机制说明;DeepSeek Harness 本体与插件的包名、版本请以你实际使用的为准,私有源的具体搭建方式因企业而异。
想装哪些 DSH plugin,先在 DSH Plugin Hub 里敲定清单,再一次性同步进私有源——比装一个补一个少跑很多趟。

要离线装的是插件包而不是本体,见内网离线怎么装 DSH plugin。
常见问题
npx 在离线环境必然要先解决「包从哪来」:把 DeepSeek Harness 的包体提前放进私有源或本地目录,再用私有源地址或本地路径执行,而不是让 npx 去公网解析。最省事的做法是在有网机器上预下载包与依赖、把缓存目录整体搬到离线机器,然后指定缓存使用,跳过所有网络解析。
在 DeepSeek Harness 里,在配置里把 registry 指向私有源(项目级或用户级 .npmrc 均可),npx 与插件安装就会跟随该源。要点是同一条源要同时承载 DeepSeek Harness 本体与你需要的插件包,否则会出现「本体装上了、插件拉不到」的半成品状态;插件清单可先在 DSH Plugin Hub 里选定,再统一同步进私有源。
在 DeepSeek Harness 里,因为「空值」和「未设置」在实现里常被区别对待:空字符串会被当成一个有效值传给子进程,并可能触发本为特定代理场景保留的清理逻辑,结果子进程完全不读代理变量、静默直连。正确做法是启动前把不需要的代理变量取消设置,或把它显式填成同一个可用地址,不要留空。
在 DeepSeek Harness 里,三个验证点:一是查配置生效值(查看 registry 当前解析结果),二是看下载日志里的请求地址是不是私有源域名,三是在断网或屏蔽公网的环境里执行一次——如果还能装上,说明确实走的私有源。第三条最硬。
在 DeepSeek Harness 里,本体的包只有一个,插件是一组:离线环境常出现本体能装、插件缺依赖的情况。排查重点是「私有源里到底有哪些包」——逐个核对插件包名与依赖包是否都已同步,而不是反复重试安装命令;同时注意插件的原生依赖在离线机器上可能需要预编译产物。
相关术语
- 私有 registry
- 私有 registry 是企业内网自建的 npm 源,用来缓存或托管包,使内网机器无需访问公网即可安装。DeepSeek Harness 与其 DSH plugin 依赖它时必须都已同步到该源,否则会出现部分可装的半成品状态。— https://docs.npmjs.com/cli/v10/using-npm/registry
- .npmrc
- .npmrc 是 npm 的配置文件,可设置 registry、代理、缓存目录等选项,支持项目级与用户级两层。它是让 npx 与插件安装统一走私有源或代理的主要手段。— https://docs.npmjs.com/cli/v10/using-npm/registry
- 缓存预热(cache warm-up)
- 缓存预热指在有网环境提前把包下载进缓存目录,再让离线环境复用同一份缓存,从而跳过网络解析。对 npx 而言,预热能同时解决「下载慢」与「完全无网」两个问题。— https://docs.npmjs.com/cli/v10/commands/npx
- npm 代理环境变量
- npm 代理环境变量指通过 HTTP_PROXY / HTTPS_PROXY 一类变量让 npm 走代理。它们对值敏感:留空会被当作有效值传递并可能导致子进程直连,因此离线与内网场景下要么取消设置、要么填成同一地址。— https://docs.npmjs.com/cli/v10/using-npm/registry