dsh 本地化部署:npm 私服、推理层与多 Subagent 运维手册
本节回答一个部署问题:在一台都不能出外网的内网里,把 DeepSeek Harness(dsh)完整跑起来——npm 私服(verdaccio)管包、vLLM / Ollama / 昇腾管推理、dsh 管 agent,最后开启多 Subagent 协作。全部命令与配置经 2026-10-06 一手核实(官方文档 / npm registry / GitHub 源码),版本快照见文末;标注"未核实"的条目使用前自行验证。
架构总览
四类机器角色,一台机器可以身兼多角:
[出网中转机] [私服机] [推理服务器] [开发机]
有外网,仅一台 verdaccio :4873 vLLM :8000 / Ollama :11434 dsh CLI / dsh web
预热 npm 包、下载 (npm 仓库, (OpenAI 兼容端点, registry 指私服
模型权重、导出镜像 断网/代理两模式) GPU/NPU 服务器) baseURL 指推理端点
text
数据流:开发机 dsh --registry--> 私服机 verdaccio;dsh 模型流量 --baseURL--> vLLM/Ollama。两条链完全独立——包走 registry,模型流量走 baseURL,排查问题时先分清是哪条链。
第一章:verdaccio——内网 npm 私服
1.1 安装与首次启动
verdaccio 稳定版 v7.0.2(2026-10-26 发布;本节撰写时为 v6.10.5,官方注明 6.x 只修不加、2FA 等新特性在 7.x——7.x 已转正,本节配置 6.x/7.x 通用。MIT,17,980 stars,2026-11-07 核实)。默认端口 4873。
# 方式一:CLI(需要机器上已有 Node/npm——内网第一台可用离线 node 包安装)
npm i -g verdaccio && verdaccio # 首次运行自动生成 ~/.config/verdaccio/config.yaml
# 方式二:Docker(内网推荐,镜像可 docker save 离线导入)
docker run -d --name verdaccio -p 4873:4873 \
-v $V_PATH/conf:/verdaccio/conf \
-v $V_PATH/storage:/verdaccio/storage \
-v $V_PATH/plugins:/verdaccio/plugins \
verdaccio/verdaccio
bash
Docker 两个坑(官方文档原文):容器内以非 root uid=10001 运行,bind mount 的目录要 chown -R 10001;容器里 config.yaml 的 listen 被忽略,改端口用环境变量 VERDACCIO_PORT。
1.2 默认配置与断网改造
首次启动生成的默认 config.yaml(官方文档原文):
storage: ./storage
auth:
htpasswd:
file: ./htpasswd
uplinks:
npmjs:
url: https://registry.npmjs.org/
packages:
'@*/*':
access: $all # 匿名可安装
publish: $authenticated
proxy: npmjs # 未命中本地则回源 npmjs 并缓存
'**':
access: $all
publish: $authenticated
proxy: npmjs
web:
enable: true
publish:
allow_offline: true # 默认 false!断网导入 tgz 必开
yaml
运维要点:
- 对外服务:CLI 场景加
listen: 0.0.0.0:4873 - 完全断网:两件事——删掉
uplinks段(或去掉 packages 的proxy),开publish.allow_offline: true - 账号:匿名可
npm install,只有 publish 需要用户:npm adduser --registry http://npm.corp.local:4873 --auth-type=legacy(verdaccio 不支持 web 登录)
1.3 模式一:上游代理(有一台能出网的机器)
默认配置天然就是代理缓存——客户端请求未命中的包时经 uplink 回源 npmjs 并落盘 storage,之后命中直接走缓存:
npm install --registry http://npm.corp.local:4873 # 第一次回源,之后走缓存
bash
这台 verdaccio 保持默认 uplinks 即可;内网其余机器 registry 全部指向它。注意:这台机器本身能出网,对"代码不能出内网"级别的合规场景不适用——那种场景走模式二。
1.4 模式二:完全断网导入(三条路径)
npm pack 只导出单个包的 tgz,不含依赖树——dsh 连同依赖几十上百个包,三条路径按需选:
# 路径 A:tgz 逐个 publish(适合少量自研包)
npm pack @deepseek-ai/dsh && npm pack @deepseek-ai/dsh-base # 还需补齐全部依赖树
for f in *.tgz; do npm publish "$f" --registry http://npm.corp.local:4873; done
# 路径 B:storage 整体拷贝(推荐,最快)——元数据和 tarball 都是纯文件
# 出网机:先跑一遍预热(把 dsh 与插件全部 install 过),然后:
# tar czf verdaccio-storage.tgz -C $V_PATH storage
# 断网机:解压覆盖到同路径,重启 verdaccio
# 路径 C:pnpm store 离线(项目级安装场景)
pnpm fetch # 按 lockfile 把全部依赖拉进虚拟 store,忽略 manifest
# 拷走 store + package.json + pnpm-lock.yaml 到内网机
pnpm install --offline # 强制不访问任何 registry,缺包直接失败(适合 CI 强校验)
bash
verdaccio 没有官方批量导入工具(npm 上不存在 verdaccio-offline 包,实测确认)——路径 B 是社区与官方 Discussion 认可的气隙方案。
1.5 开发机 .npmrc 本地配置(npm/pnpm 通用)
npm 和 pnpm 读同一套 .npmrc,解析优先级从高到低:项目级(<项目>/.npmrc)→ 用户级(~/.npmrc)→ 全局(<prefix>/etc/npmrc),高优先级覆盖低优先级的同名键。
全套可用配置(按场景取用):
# ===== ~/.npmrc 用户级:内网全员标配 =====
registry=http://npm.corp.local:4873/
# scope 隔离:只有公司/工具 scope 走私服,其余包仍走公网(半内网场景)
@deepseek-ai:registry=http://npm.corp.local:4873/
@my-company:registry=http://npm.corp.local:4873/
# 私服用自签/企业 CA 证书时(否则 npm 报 SELF_SIGNED_CERT_IN_CHAIN)
cafile=/etc/corp/ca-cert.pem
strict-ssl=true
# 私服开了认证时
always-auth=true
//npm.corp.local:4873/:_authToken=<token>
# pnpm 11 坑:minimumReleaseAge 默认 1440 分钟,刚 publish 到私服的包会被隐藏
minimumReleaseAgeExclude[]=@deepseek-ai
ini
# ===== 命令行等价写法 =====
npm set registry http://npm.corp.local:4873/ # 写用户级
npm set registry http://npm.corp.local:4873/ --location project # 写项目级
pnpm config set registry http://npm.corp.local:4873/ --location project
npm config set @deepseek-ai:registry http://npm.corp.local:4873 # 仅该 scope 走私服
npm config get registry # 验证生效值
npm config list -l | grep -i registry # 查看三层来源
bash
三个实践要点:
- 优先用 scope 隔离而不是全局替换:开发机若还要构建其他开源项目,
@deepseek-ai:registry只让 dsh 系包走私服,互不干扰 - 环境变量临时覆盖:
npm_config_registry=http://npm.corp.local:4873优先级高于所有 .npmrc——CI 脚本与dsh plugin(转发 pnpm)都认这个变量,一次性场景用它最干净 - 锁版:内网统一在 .npmrc 或 package.json 的
engines/.npmrc save-exact=true固定版本,配合 verdaccio 版本锚点(19-03 更新流水线的口径)
第二章:推理层选型与国产 GPU 对接
2.1 选型:vLLM / Ollama / 昇腾三条线
| 维度 | vLLM | Ollama | 昇腾(vLLM-Ascend / MindIE) |
|---|---|---|---|
| 定位与体量(2026-11-07 核实) | 96,488 stars · Apache-2.0 · 双周发版 | 186,161 stars · MIT · patch 按天 | 合规国产线,910B 算力≈A100 |
| 部署形态 | K8s + Helm 成熟生产路径 | 单机即开即用 | 华为云/整机柜,交付排期制 |
| 适用分工 | 集中部署给全公司 | 个人与小组 | 合规硬约束的组织 |
| 硬件门槛 | 30B 级 MoE:单机多卡 A100 或几张 4090 起步 | 单机即可 | 8 卡 910B 整机 ≈¥70-100 万(约为 8 卡 H100 ¥230-262 万的一半以下) |
| 生态成熟度 | 事实标准,社区最大 | 极简,周边丰富 | 稳定性与软件生态尚不及英伟达(专家纪要口径),排错成本要预算 |
分工不互斥:小组内 Ollama 起步、全公司上 vLLM、合规场景走昇腾,可分阶段演进。
2.2 vLLM-Ascend:vLLM 官方昇腾后端
vLLM-Ascend 是 vLLM 官方支持的昇腾 NPU 推理后端(vllm-project/vllm-ascend),OpenAI 兼容接口不变——对 dsh 侧完全透明,baseURL 照旧。以包形式安装到 vLLM 环境(具体命令与参数以官方 README 当前版为准,此处为方向性口径):
# 方向性口径(以 github.com/vllm-project/vllm-ascend README 为准):
pip install vllm-ascend # vLLM 插件形式,注册 NPU 平台后端
vllm serve <model> --device npu # NPU 设备参数,具体拼写见官方文档
bash
适配清单是硬约束(社区实测 2026-09):vLLM-Ascend 部分版本 model-restricted——仅保证 KimiK3 / GLM-5.2 / V4Flash 等清单内模型;追新模型可能要等官方适配。社区那篇实测的标题说得很直白:"能跑起来 ≠ 能在生产跑稳"——上线前按清单锁模型版本。
2.3 MindIE:华为官方推理引擎
MindIE 是华为自己的推理引擎,DeepSeek 系模型发布当天即支持昇腾(昇腾 ModelZoo 提供部署包与说明:gitee.com/ascend/ModelZoo-PyTorch → MindIE/LLM/)。与 vLLM-Ascend 二选一:要 OpenAI 兼容接口和 vLLM 生态延续性选 vLLM-Ascend;要官方支持深度与 ModelZoo 现成部署包选 MindIE。
2.4 昇腾采购与租赁口径(2026-10 核实)
- 8 卡 910B 整机 ≈ ¥70-100 万(8 张卡成本约 70 万,满配整机可达百万级);对照 8 卡 H100 现货 ¥230-262 万——一半以下
- 云租:8 卡 910B 月租约 ¥1-4 万(区域平台/一体机口径,渠道差异大)
- 910C 提升算力与互联;交付订单已排至 2027,采购要趁早锁货,租赁价 2026 年还涨过一波
- 其他国产线(海光 DCU / 寒武纪 MLU):本节未核实部署口径,选型前单独调研
第三章:vLLM——集中部署的推理层
3.1 安装(三口径)
撰写时稳定版 v0.31.0(2026-10-05 发布,严格双周发版;2026-11-07 GitHub 最新 release 已到 v0.33.0rc3,稳定线按双周推进)。要求:Linux 原生(Windows 走 WSL)、Python 3.10–3.13、GPU 算力 ≥7.5(T4/A100/H100…)、官方二进制默认 CUDA 12.9(另有 12.8/13.0 变体)。
# 方式一:uv(官方当前首选,可按驱动自动选 PyTorch 源)
uv venv --python 3.12 --seed --managed-python && source .venv/bin/activate
uv pip install vllm --torch-backend=auto
# 方式二:pip(固定 CUDA 12.9 源)
pip install vllm --extra-index-url https://download.pytorch.org/whl/cu129
# 方式三:Docker(OpenAI 兼容服务一体)
docker run --runtime nvidia --gpus all \
-v ~/.cache/huggingface:/root/.cache/huggingface \
-p 8000:8000 --ipc=host \
vllm/vllm-openai:latest \
--model Qwen/Qwen3-0.6B
bash
官方强调:装进全新虚拟环境(二进制与 CUDA/PyTorch 强绑定);conda 装的 PyTorch 会静态链 NCCL 有已知问题。
3.2 vllm serve 关键参数(默认值逐一对照 v0.31.0 源码核实)
| 参数 | 默认值 | 说明 |
|---|---|---|
--host / --port | None / 8000 | 对外服务必设 --host 0.0.0.0 |
--served-model-name | = --model 值 | API 里 model 字段的别名,dsh 侧对齐 |
--max-model-len | 取模型 config | 支持 32k / 1m 人类可读后缀 |
--gpu-memory-utilization | 0.92(v0.28 起;旧教程写 0.9 已过时) | 显存占用上限 |
--tensor-parallel-size | 1 | 多卡张量并行 |
--dtype | auto | BF16 权重跑 BF16 |
--quantization | 读模型 quantization_config | 支持 fp8 / awq / gptq / int8 / marlin |
vllm serve /data/models/Qwen2.5-14B-Instruct \
--host 0.0.0.0 --port 8000 \
--served-model-name qwen2.5-14b \
--max-model-len 32768 --gpu-memory-utilization 0.92 \
--tensor-parallel-size 2 --quantization fp8 \
--api-key sk-internal # 或环境变量 VLLM_API_KEY
bash
3.3 内网离线部署
官方无专门"离线安装"页,以下是 pip/Docker 标准机制 + 社区实测(方法本身非 vLLM 官方条款):
# 包离线:有网机全量 wheel(torch 在 pytorch 源,--extra-index-url 必带)
pip download vllm -d ./wheels --extra-index-url https://download.pytorch.org/whl/cu129
# 内网机:
pip install vllm --no-index --find-links=/opt/wheels
# 镜像离线:
docker pull vllm/vllm-openai:v0.31.0 && docker save vllm/vllm-openai:v0.31.0 | gzip > vllm.tar.gz
# 内网机:docker load < vllm.tar.gz
# 权重离线:HF 格式目录 + 本地路径启动
export HF_ENDPOINT=https://hf-mirror.com # 有网机国内镜像下载(2026-10 实测可达)
huggingface-cli download Qwen/Qwen2.5-14B-Instruct --local-dir /data/models/qwen
# 内网机:
export HF_HUB_OFFLINE=1 # HF 官方:禁止一切 Hub 网络请求,只用本地
export VLLM_NO_USAGE_STATS=1 # 关 vLLM 遥测,内网必设(或 DO_NOT_TRACK=1)
vllm serve /data/models/qwen --served-model-name qwen
bash
2026 口径修正:HF 官方已废弃 HF_HUB_ENABLE_HF_TRANSFER(hf_transfer)——Hub 全面转向 Xet 存储后端,大文件提速改用 pip install hf-xet + HF_XET_HIGH_PERFORMANCE=1。旧教程的 hf_transfer 写法已失效。
3.4 运维坑(报错原文对照)
- KV cache 不足拒绝启动(源码原文):
"To serve at least one request with the model's max seq len (X), (Y GiB KV cache is needed, which is larger than the available KV cache memory…)"→ 调大--gpu-memory-utilization或调小--max-model-len,或降精度/量化 - 共享内存:容器必须
--ipc=host或--shm-size(PyTorch 靠共享内存做进程间交换,TP 场景尤其),否则 NCCL 挂死 - 启动慢:torch.compile 编译缓存挂卷持久化;
--load-format dummy可跳过权重加载做排查;v0.31 新增vllm preload+--load-format ipc_cache实现引擎秒级重启 - 驱动过旧:容器加
-e VLLM_ENABLE_CUDA_COMPATIBILITY=1(仅部分数据中心卡) - 模型放本地盘而非 NFS(官方 troubleshooting 建议)
第四章:Ollama——小组级推理层
4.1 安装与 systemd
撰写时稳定版 v0.35.1(2026-09-29;2026-11-07 已推进到 v0.40.15);9 月单月 7 个稳定版,节奏快于"1-2 周一版",patch 常按天发。186.2K stars、MIT(2026-11-07 核实)。
curl -fsSL https://ollama.com/install.sh | sh # 一键脚本
curl -fsSL https://ollama.com/install.sh | OLLAMA_VERSION=0.35.1 sh # 锁版本
# 脚本行为(已读 install.sh 源码):建系统用户 ollama(home=/usr/share/ollama,加 render/video 组)
# → 写 /etc/systemd/system/ollama.service → enable + start
journalctl -e -u ollama # 看日志
bash
4.2 环境变量(systemd 用 override,别改主 unit)
# /etc/systemd/system/ollama.service.d/override.conf
[Service]
Environment="OLLAMA_HOST=0.0.0.0:11434" # 默认 127.0.0.1,对外服务必改
Environment="OLLAMA_MODELS=/data/ollama" # 默认 /usr/share/ollama/.ollama/models,改数据盘
Environment="OLLAMA_ORIGINS=*" # CORS,默认仅放行本机来源
Environment="OLLAMA_KEEP_ALIVE=-1" # 模型常驻内存(默认 5m 卸载)
Environment="OLLAMA_CONTEXT_LENGTH=8192" # 默认 4096,agent 场景建议调大
# 常用还有:OLLAMA_NUM_PARALLEL(1) OLLAMA_MAX_LOADED_MODELS(3×GPU数)
# OLLAMA_MAX_QUEUE(512) OLLAMA_FLASH_ATTENTION=1 OLLAMA_KV_CACHE_TYPE=q8_0
ini
sudo chown -R ollama:ollama /data/ollama # 官方提示:改路径必须给 ollama 用户权限
sudo systemctl daemon-reload && sudo systemctl restart ollama
sudo ufw allow 11434/tcp # 防火墙(firewalld: --add-port=11434/tcp --permanent)
bash
4.3 模型管理与离线搬运
ollama pull qwen3:8b && ollama list && ollama ps && ollama rm qwen3:8b && ollama stop qwen3:8b
# 离线方案 A:整目录搬运(manifests + blobs 结构)
# 有网机:tar czf models.tgz -C /usr/share/ollama/.ollama models
# 内网机:解压到 OLLAMA_MODELS 指向目录,chown ollama:ollama
# 离线方案 B:GGUF 本地构建(2026 口径:Ollama 不再代做量化,先 llama-quantize 量化好)
printf 'FROM /data/gguf/qwen3-8b-q4_k_m.gguf' > Modelfile
ollama create qwen3-8b-local -f Modelfile # 分片 GGUF 用 FROM /path/model-*.gguf 通配
bash
4.4 OpenAI 兼容端点(dsh/网关直接指它)
http://<host>:11434/v1,已核实支持 /v1/models、/v1/chat/completions、/v1/completions、/v1/embeddings、/v1/responses(新增);api_key 必填但被忽略。另发现官方新增 Anthropic 兼容 API——意味着 dsh 的 anthropic-messages 协议也能直连 Ollama。
curl http://192.168.1.10:11434/v1/chat/completions -H "Content-Type: application/json" \
-d '{"model":"qwen3:8b","messages":[{"role":"user","content":"hi"}]}'
bash
第五章:dsh 安装、接端点与排错
5.1 从私服安装
npm i -g @deepseek-ai/dsh --registry http://npm.corp.local:4873
dsh # CLI:profile / 插件 / 配置
dsh web # Web UI,默认 127.0.0.1:3080
bash
DSH_HOME 默认 ~/.dsh,profiles 在 $DSH_HOME/profiles/<name>/(内含 package.json + cordis.patch.yml)。
5.2 插件安装的 registry 继承(关键)
dsh plugin 官方原话 "forwards to pnpm in the profile directory, so every pnpm verb works"——它在 profile 目录跑 pnpm,registry 继承 pnpm 自身配置:
export npm_config_registry=http://npm.corp.local:4873 # 或写 ~/.npmrc,二选一
dsh plugin --profile web add @deepseek-ai/dsh-experimental-agent-team-profile
# 也支持本地路径 / tarball(断网最稳,跳过 registry 预检):
dsh plugin --profile demo add ./hello-plugin
bash
两个官方保证:plugin-manager 逐次用 pnpm config get registry 读取配置(.npmrc / 环境变量都认);"a private registry never falls through to a public one"(私服绝不回退公网,默认 fallback 仅 npmmirror)。注意:首次 dsh plugin 会先装 @deepseek-ai/dsh-base——私服必须已含该包及依赖(路径 B 的 storage 预热已覆盖)。
5.3 接内网推理端点(cordis.patch.yml)
- id: llm-pi-ai
config:
providers:
my-vllm:
api: openai-completions # vLLM :8000
baseURL: http://10.0.0.5:8000/v1
my-ollama:
api: openai-completions # Ollama :11434(也支持 anthropic-messages 协议)
baseURL: http://10.0.0.6:11434/v1
compat:
supportsDeveloperRole: false
maxTokensField: max_tokens
yaml
字段口径:Provider ID 小写、永久不可改;协议三选一(openai-completions / openai-responses / anthropic-messages),一个 provider 只绑一种;模型可用「获取可用模型」走 GET /models 探测(vLLM/Ollama 都实现了)。直改 $DSH_HOME/profiles/<profile>/cordis.patch.yml 与表单等价,改完下次请求生效,无需重启。
compat 排错两条(内网网关/引擎高频):
| 症状 | 开关 |
|---|---|
| 密钥地址都通,请求却被拒 | compat.supportsDeveloperRole: false + compat.maxTokensField: max_tokens(请求形状问题,不是鉴权) |
| 推理模型思考关不掉,off 不生效 | compat.thinkingFormat: deepseek |
5.4 Web UI
npx @deepseek-ai/dsh web → 127.0.0.1:3080。token-URL 认证首跑必撞:裸开域名 401,必须开终端打印的带 token 地址。会话/工作区树:⌘N、/ 指令、@ 引用。
第六章:DSH 常见插件安装与多 Subagent
6.1 常用插件安装清单
官方 Web UI 插件面板自带 7 个插件;npm scope 统一 @deepseek-ai/。已核实包名的协作类三件:
| 面板显示名 | npm 包 | 安装命令 |
|---|---|---|
| 智能体团队 | dsh-experimental-agent-team-profile (0.1.5-alpha.2) | dsh plugin --profile web add @deepseek-ai/dsh-experimental-agent-team-profile |
| 子智能体 | dsh-subagent (0.0.1-rc.1) + 后端 + 工具 | 同上格式(按需选后端包:-spawn-in-process / -fork-in-process / -acp / -codex / -claude-code / -dsh-sdk) |
| Agent 循环 | dsh-agent-loop (0.1.0-rc.6) | dsh-base 内核已含、无需安装;面板卡是设置页(管 maxParallelToolCalls);长循环自主运行另装 dsh-tool-ralph |
效率与语音类四件(自动授权审查 / 语音输入 SenseVoice / 终端 / 网页搜索——包名未逐一核实),两种装法:
# 装法一:Web UI 插件面板(dshmarket,官方插件集合)一键安装——安装源可切中国大陆镜像
# 装法二:npm 检索后命令行装(registry.npmjs.org 搜 "dsh speech-to-text" 等关键词,
# 内网经私服:dsh plugin --profile web add <包名>)
bash
社区生态:聚合目录 awesome-deepseek-harness(github.com/0xsline/awesome-deepseek-harness)与 npm 检索 dsh 前缀;高人气社区插件如 @nanmicoder/dsh-agent-teams (0.1.22):dsh plugin --profile web add --save-exact @nanmicoder/dsh-agent-teams,支持 /agent-teams 斜杠命令与花名册式配置。
安装三形态回顾:npm 发布(最省事)/ GitHub 直装(内网不可达,改 tarball 搬运)/ 本地路径与 tarball(断网最稳)。allowBuilds 授权 = 允许安装时执行代码,权限要审。组合包 bundle(dsh.bundle + cordis.patch.yml 配置层)经 dsh plugin --profile <name> add <包> 装进 profile;层叠顺序 base → bundle 按安装序 → profile patch → home 级 → --patch overlay,后层整行覆盖不深度合并。
6.2 多 Subagent 配置(cordis.patch.yml)
官方最小组合(团队特性需持久化会话存储):
- name: '@deepseek-ai/dsh-session-persistence-jsonl'
- name: '@deepseek-ai/dsh-experimental-agent-team'
- name: '@deepseek-ai/dsh-experimental-tool-agent-team'
yaml
常用限额字段(启动时校验):maxMembers(默认 16)/ maxTasks(256)/ maxPendingMessagesPerMember(64)/ maxMessageBytes / disposalTimeoutMs;tool-agent-team 可配 freshProvider(spawn)/ forkProvider(fork)。tool-subagent 字段:provider / toolName / backgroundMode(one-shot|continuable)/ agentOptions / persona / toolFilter / maxDepth(默认 1)。全部字段以官方 docs/config-catalog.md 为准。
6.3 子 agent 绑定不同模型 / provider(与第五章衔接)
tool-subagent 的 agentOptions 可给每个子 agent 配 child provider + model + reasoningEffort + maxTokens;开 modelSelectionSettings: true 后工具暴露精确 provider/model 路由。此处 provider 即 cordis.patch.yml providers: 下的自定义三协议条目——子 agent 按引用取名,不同子 agent 可挂不同推理端点(例如 coder 挂 vLLM 的大杯、reviewer 挂 Ollama 的小杯)。社区佐证:@nanmicoder 的 members[].model 跨 LLM 路由、dsh-subagent-router(按调用选 provider)、@lolkda/dsh-agent-team-model-pin(团队钉模型)。
6.4 用法
# headless 一条龙(官方 README 原文)
dsh --profile headless "Use Agent Teams to split this task between two teammates, wait, and summarize."
bash
Web 路径:装 profile bundle 后在 Web/Desktop 的 Plugins 页开启 Agent Teams(bundle 默认关闭),会话内自然语言驱动——官方示例 "create a teammate named reviewer to check the diff, then send reviewer the change summary":Lead 调 spawn_teammate(仅 Lead 可调,参数 name/description/initial task)再发消息;所有成员共享同 9 个工具,消息与任务状态崩溃重启后可恢复。无 CLI 直接创建 subagent 的命令——子 agent 由模型在会话内经工具调用创建,CLI 只管插件装卸与 profile。experimental 包官方明示无稳定性承诺。
第七章:RAG 与向量数据库(内网知识检索线)
推理层跑起来之后,内网知识库(文档、代码库说明、运维手册)要被 agent 用上,还差一条 RAG 线:embedding 服务 + 向量库 + 应用层检索工具。与前面两章的关系:embedding 服务复用同一套推理部署方式(Ollama / vLLM),向量库是新增的一个组件。
[文档 .md/.pdf] --切块+向量化--> [embedding 服务] --> [向量数据库] <--检索-- [应用层 search 工具] <--工具调用-- dsh/agent
bge-m3 等 LibSQL/Qdrant… (如课程 ai-chat-ui 的 search_docs)
text
7.1 embedding 服务:两种起法
# 方式一:Ollama(小组场景,与第四章同一套部署)
ollama pull bge-m3 # 约 1.2GB;1024 维、8192 token、100+ 语言
curl http://10.0.0.6:11434/v1/embeddings -H "Content-Type: application/json" \
-d '{"model":"bge-m3","input":["内网知识检索测试"]}' # OpenAI 兼容(已核实支持)
# 原生接口:POST /api/embed
# 方式二:vLLM 起 embedding 模型(集中部署场景;参数拼写以 docs.vllm.ai 当前版为准)
vllm serve Qwen/Qwen3-Embedding-0.6B --task embed --host 0.0.0.0 --port 8001
bash
换模型 = 换维度 = 必须重建索引(bge-m3 1024 维、Qwen3-Embedding 支持 MRL 自定义维度、OpenAI text-embedding-3-small 1536 维),入库与查询必须同模型。
向量模型选型(口径来自 17-04 节核实):
| 模型 | 形态 | 维度/上下文 | 内网适配 |
|---|---|---|---|
| bge-m3 | 本地开源 567M | 1024 / 8192 | 内网事实标杆:Ollama 一条命令、完全离线 |
| Qwen3-Embedding 0.6B-8B | 本地开源 | MRL 自定义 | 曾登 MTEB 多语言第一 |
| OpenAI text-embedding-3-small | API | 1536 | 需出网,合规场景不适用 |
| 智谱 embedding-3 | API | 默认 2048 | 国内无墙,半内网可用 |
7.2 向量库选型:内网小组首选嵌入式
| 类别 | 代表 | 适用 | 内网代价 |
|---|---|---|---|
| 嵌入式 | LibSQL(vector 扩展)、sqlite-vec、Chroma | 几十万向量以内、单机 | 零新增服务——一个文件库 |
| 专用 | Qdrant、Milvus、Weaviate | 千万级/多实例 | 新增常驻服务与运维 |
| 数据库扩展 | PgVector | 已有 PG 的团队 | PG 运维成本 |
判断标准(17-04 口径):百万向量以内嵌入式性价比最高;团队文档知识库(几百到几千篇文档、切块后几千到几万向量)差专用库六个数量级——不要为知识库上 Milvus。课程 ai-chat-ui 的真实落地:@mastra/libsql 同包导出 LibSQLVector,与 Mastra 的 MastraVector 统一接口(createIndex/upsert/query/deleteVector 同签名)——将来换 Qdrant 只动初始化一行,业务代码零改动。
7.3 LibSQLVector 落地与两个实测坑
import { LibSQLVector } from '@mastra/libsql';
// 文件库放数据盘(别用 :memory:)
const vector = new LibSQLVector({ url: 'file:/var/lib/ai-chat/vectors.db' });
await vector.createIndex({ indexName: 'docs', dimension: 1024 });
await vector.upsert('docs', embeddings, { metadata: [{ source: 'runbook.md' }] });
const hits = await vector.query('docs', queryEmbedding, { topK: 5 });
ts
两个实测坑(课程项目踩过):
:memory:模式写事务丢表——向量库必须用文件库(上例的file:路径),且提前mkdir -p父目录- truncate 后重插报 shadow row——全量重建走
dropIndex+createIndex,不要 truncate 表后直接重插
7.4 与 dsh 的衔接
- 已核实:dsh Web UI 会话支持
@引用文档/工作区文件(上下文注入,非向量检索);dsh 生态的 RAG/知识库插件未核实——不要按传闻选型 - 可靠路径是应用层 RAG:像课程 ai-chat-ui 那样,在网关/应用层做
search_docs工具(向量检索返回带 source 出处的结构化结果),dsh/agent 经工具调用消费——工具输入输出形状稳定,引擎置换(关键词 → 向量)对 agent 透明 - 知识库更新流水线:文档变更 → 重新切块 embedding → upsert;换 embedding 模型时整库 drop + create 重建(见 7.3 坑二)
第八章:k3s + vLLM 多模型推理集群扩展
单机 vLLM 跑稳之后,下一步是集群化:多模型共存(小杯给补全、大杯给重构)、同模型多副本扩吞吐、节点扩容不停服。内网轻量路径选 k3s——单二进制 <70MB、默认 SQLite 存储(etcd 可选),比完整 K8s 的运维面小一个量级。
8.1 k3s 离线(airgap)安装
官方流程三步:Load Images → Install K3s → Upgrade。有网机下载三件套(版本必须一致;v1.37.1+k3s1 的 release 提供 .tar/.tar.gz/.tar.zst 三种格式):
# 有网机
V=v1.37.1+k3s1
curl -LO "https://github.com/k3s-io/k3s/releases/download/${V}/k3s"
curl -LO "https://github.com/k3s-io/k3s/releases/download/${V}/k3s-airgap-images-amd64.tar.zst"
curl -Lo install.sh https://get.k3s.io
# 拷到内网每台节点后
sudo cp k3s /usr/local/bin/k3s && sudo chmod +x /usr/local/bin/k3s
sudo mkdir -p /var/lib/rancher/k3s/agent/images/
sudo cp k3s-airgap-images-amd64.tar.zst /var/lib/rancher/k3s/agent/images/
# server 节点
INSTALL_K3S_SKIP_DOWNLOAD=true ./install.sh
# agent 节点
INSTALL_K3S_SKIP_DOWNLOAD=true K3S_URL=https://<SERVER_IP>:6443 K3S_TOKEN=<TOKEN> ./install.sh
bash
要点(官方 airgap 页):SELinux 节点需手动装 k3s-selinux RPM;无默认路由的节点配 dummy 路由;DNS 无上游用 --resolv-conf;升级 = 新 tar 放 images 目录删旧 tar + 替换二进制 + 重跑 install.sh;touch /var/lib/rancher/k3s/agent/images/.cache.json 跳过未变更 tar 的重复导入。多节点免私仓方案:--embedded-registry(内嵌 Spegel,任一节点的镜像可被全集群拉取)。纠错:网上流传的 --airgap-compact flag 在当前代码库与 CLI 参考中 0 命中,不存在。
8.2 GPU 支持(containerd 自动探测)
k3s 基于 containerd,自动探测 nvidia / nvidia-cdi / nvidia-experimental 三种 runtime 并写入 containerd 配置,无需手改 config.toml:
sudo apt install -y nvidia-container-runtime cuda-drivers-fabricmanager-515 nvidia-headless-515-server # 按发行版换包名
# 装好或重启 k3s 后验证 runtime 已注册:
grep nvidia /var/lib/rancher/k3s/agent/etc/containerd/config.toml
bash
Pod 侧两件套:runtimeClassName: nvidia(除非全局 --default-runtime)+ resources.limits.nvidia.com/gpu;配 NVIDIA/k8s-device-plugin 使用。--docker(cri-dockerd)路径的 GPU 配置官方未文档化(未核实),内网 GPU 节点用默认 containerd。
8.3 vLLM 多模型部署:每模型一个 Deployment + Service
官方 K8s 文档的标准形态。合并 k3s 差异点(runtimeClassName)与内网差异点(权重 hostPath 本地挂载、镜像走私仓)的骨架:
apiVersion: apps/v1
kind: Deployment
metadata:
name: qwen3-32b
labels: { app: qwen3-32b }
spec:
replicas: 1 # 同模型扩吞吐:加副本(每副本占 1 卡),配 HPA 按队列自动扩
selector: { matchLabels: { app: qwen3-32b } }
template:
metadata: { labels: { app: qwen3-32b } }
spec:
runtimeClassName: nvidia # k3s 必需(未改 --default-runtime 时)
nodeSelector: { nvidia.com/gpu.present: "true" }
volumes:
- name: shm # 张量并行需要 /dev/shm(容器 --ipc=host 的 K8s 等价物)
emptyDir: { medium: Memory, sizeLimit: "2Gi" }
- name: model-cache
hostPath: { path: /data/models/qwen3-32b, type: Directory } # 内网权重本地挂载
containers:
- name: vllm
image: registry.corp.local/ai/vllm-openai:v0.31.0 # 内网私仓 retag 后地址
command: ["/bin/sh", "-c"]
args: ["vllm serve /data/models/qwen3-32b --served-model-name qwen3-32b --max-model-len 32768"]
ports: [ { containerPort: 8000 } ]
resources:
limits: { cpu: "10", memory: 20G, nvidia.com/gpu: "1" }
requests: { cpu: "2", memory: 6G, nvidia.com/gpu: "1" }
volumeMounts:
- { name: shm, mountPath: /dev/shm }
- { name: model-cache, mountPath: /data/models/qwen3-32b }
readinessProbe: { httpGet: { path: /health, port: 8000 }, initialDelaySeconds: 60, periodSeconds: 5 }
livenessProbe: { httpGet: { path: /health, port: 8000 }, initialDelaySeconds: 60, periodSeconds: 10 }
---
apiVersion: v1
kind: Service
metadata: { name: qwen3-32b }
spec:
selector: { app: qwen3-32b }
ports: [ { protocol: TCP, port: 8000, targetPort: 8000 } ]
type: ClusterIP
yaml
另一个模型(如 deepseek-v3)复制一份改 name/image/权重路径即可。裸 YAML 与 Helm 的取舍:内网选裸 YAML——无额外依赖、manifest 可审计;要会话亲和/KV cache 复用路由与模型别名再上 vllm-project/production-stack(vllm/vllm-stack chart v0.1.13,多引擎 + 路由器 + 监控,2.7k stars)。
8.4 多模型统一入口:网关聚合 → dsh 单 baseURL
多个 vLLM Service 对 dsh 暴露一个入口,按请求 model 字段路由——LiteLLM proxy 有官方 K8s Helm(oci://ghcr.io/berriai/litellm-helm,探针 /health/readiness 端口 4000):
# LiteLLM config.yaml(ConfigMap 挂载)——按 model 路由到两个 vLLM service
model_list:
- model_name: qwen3-32b
litellm_params:
model: openai/qwen3-32b # 对应各 vLLM 的 --served-model-name
api_base: http://qwen3-32b.default.svc.cluster.local:8000/v1
api_key: os.environ/VLLM_API_KEY
- model_name: deepseek-v3
litellm_params:
model: openai/deepseek-v3
api_base: http://deepseek-v3.default.svc.cluster.local:8000/v1
api_key: os.environ/VLLM_API_KEY
yaml
dsh 侧回到第五章的 Provider 配置:baseURL 指网关 Service 的 OpenAI 兼容端点,一个 provider 吃下全部模型(配合 6.3 的 agentOptions 给子 agent 指不同 model)。new-api 无官方 Helm(未核实),K8s 内用通用 Deployment 跑镜像。
版本锚点(2026-10-06):k3s 最新稳定 v1.37.1+k3s1(并行维护 v1.36.5/v1.35.9/v1.34.12,建议锚 v1.36.x 或 v1.37.x);vLLM v0.31.0 双周节奏——两者都走私服/私仓版本锚点,按季度评估升级。
第九章:全链路验收清单
# 1. 私服
curl http://npm.corp.local:4873/-/whoami # 200
npm view @deepseek-ai/dsh version --registry http://npm.corp.local:4873
# 2. 推理层
curl http://10.0.0.5:8000/v1/models -H "Authorization: Bearer sk-internal" # vLLM
curl http://10.0.0.6:11434/v1/models # Ollama
curl http://10.0.0.6:11434/v1/embeddings -H "Content-Type: application/json" \
-d '{"model":"bge-m3","input":["探活"]}' | head -c 200 # embedding(RAG 线)
# 3. dsh 端到端
dsh --profile web "用一句话确认你能访问 my-vllm 并列出模型" # 模型流量走通
# 4. 多 Subagent
dsh --profile headless "Use Agent Teams to split this task between two teammates, wait, and summarize."
# 5. 集群(k3s 路线)
kubectl get pods -o wide # vLLM 各模型 Pod 就绪
kubectl get svc | grep -E 'qwen|litellm' # Service 就位
curl http://<litellm-svc>:4000/v1/models -H "Authorization: Bearer $KEY" # 网关聚合模型列表
bash
版本快照(2026-10-06 核实)
| 组件 | 版本 | 发布 | 节奏 |
|---|---|---|---|
| verdaccio | v6.10.5 | 2026-10-03 | 活跃(7.x 预发布并行) |
| vLLM | v0.31.0 | 2026-10-05 | 严格双周 |
| Ollama | v0.35.1 | 2026-09-29 | 快于双周,patch 按天 |
| dsh | 0.2.0-rc.2 | 2026-10-03 更新 | developer preview |
内网策略:锁 Docker tag(vllm/vllm-openai:v0.31.0)/ 锁 OLLAMA_VERSION / dsh 走私服版本锚点,按季度评估升级(详见 19-03 更新流水线)。2026-11-07 复核:verdaccio 已发 7.0.2 正式版、dsh 最新 0.2.2-rc.1(2026-11-04)、Ollama 已到 v0.40.15、vLLM 稳定线持续推进——快照供对账,升级走 19-03 流水线评估。
小结
- 两条链分清:包走 registry(verdaccio,断网开
allow_offline,导入首选 storage 整体拷贝),模型流量走 baseURL(vLLM :8000 / Ollama :11434) - .npmrc 三层优先级 + scope 隔离 +
npm_config_registry临时覆盖:开发机、CI、dsh plugin(转发 pnpm)三处共用一套配置心智 - 推理层选型:小组 Ollama、全公司 vLLM、合规走昇腾(vLLM-Ascend 适配清单是硬约束,MindIE 官方深度支持);国产 8 卡 910B 约为 8 卡 H100 一半以下,代价是生态成熟度与交付等待
- dsh 私服友好度超预期:官方保证私服绝不回退公网;
npm pack不含依赖树是最大的坑,预热+拷 storage 一次解决 - 插件安装心法:三形态中 npm 发布最省事、tarball 断网最稳;协作类三件(agent-team-profile / dsh-subagent / agent-loop 内核已含)是核心,效率类四件走 dshmarket 面板;
agentOptions.provider给每个子 agent 挂不同推理端点 - RAG 线单独算:embedding 服务复用推理部署(Ollama bge-m3 / vLLM --task embed),向量库内网小组首选嵌入式 LibSQL(零新增服务),换模型必须整库重建
- 集群扩展路线:k3s airgap 三件套离线装、containerd 自动探测 nvidia runtime、每模型一个 Deployment+Service、LiteLLM 网关聚合成单 baseURL——dsh 一个 provider 吃下全部模型
- 版本口径两条修正(2026):vLLM 显存参数默认已是 0.92;HF 提速用 hf-xet,hf_transfer 已废弃;k3s 流传的 --airgap-compact flag 不存在
主要来源
- verdaccio:verdaccio.org/docs(configuration / docker / installation / setup-npm / setup-pnpm / cli-registry);GitHub Discussion #5484(气隙 storage 拷贝);pnpm.io/cli/fetch
- vLLM:docs.vllm.ai(installation/gpu、quickstart、conserving_memory、troubleshooting);v0.31.0 源码(cli_args.py / cache.py / kv_cache_utils.py 默认值与报错原文)
- vLLM-Ascend / 昇腾:github.com/vllm-project/vllm-ascend;gitee.com/ascend/ModelZoo-PyTorch(MindIE/LLM);社区生产实测文(2026-09,适配清单口径);算力专家纪要与一体机交流(910B 价格口径,2026-10)
- Ollama:ollama.com/install.sh(源码直读);github.com/ollama/ollama docs/(linux.mdx / faq.mdx / cli.mdx / import.mdx / api/openai-compatibility.mdx);GitHub Releases API
- dsh:github.com/deepseek-ai/deepseek-harness(README、docs/user/develop/basic/publish.md、packages/boot/plugin-manager/README.md、apps/cli/reference/README.md、packages/subagent 与 experimental/agent-team* README、docs/config-catalog.md);npm registry 实测包名;社区 @nanmicoder/dsh-agent-teams
- k3s:docs.k3s.io(installation/airgap 中英文、advanced#nvidia-container-runtime、cli/server、registry-mirror);github.com/k3s-io/k3s releases(v1.37.1+k3s1 资产清单)
- vLLM K8s 生态:docs.vllm.ai/en/latest/deployment/k8s.html 与 frameworks/helm.html;github.com/vllm-project/production-stack(vllm-stack chart v0.1.13)
- LiteLLM K8s:docs.litellm.ai/docs/proxy/deploy(Helm 与裸 manifest);new-api:github.com/QuantumNous/new-api;NVIDIA device plugin:github.com/NVIDIA/k8s-device-plugin
- HF:huggingface.co/docs/huggingface_hub(环境变量、Xet/hf-xet 口径);hf-mirror.com
- RAG/向量库:本节 17-04 节已核实口径(向量模型版图/向量库选型/MastraVector 统一接口)+ 课程 ai-chat-ui 真实落地实测
↑