1. 为什么要在 Linux 服务器上跑 DeepSeek HarnessDeepSeek Harness命令行入口dsh是 DeepSeek 官方开源的 agent harness核心卖点是“一切皆插件”底层由 Cordis 驱动MIT 协议。它能做什么简单说它把“让模型读代码、改文件、跑命令”这件事封装成一个可托管、可扩展的服务Web UI 里发任务agent 在指定 workspace 里干活无头模式下一条命令跑完 CI 任务。适合谁适合手里有一台 Linux 服务器、想让 agent 常驻而不是每次本地开终端的人也适合要接自建网关、统一管理模型 Key 的团队。但真到上线这一步坑往往不在 agent 本身而在“模型通道怎么统一”。默认它读DEEPSEEK_API_KEY可你一旦同时用 Claude Code、Cline、CC Switch 这些工具Key 就会散落在四五个配置文件里换一次额度要改一圈。这篇就按“一行命令拉起 → 源码部署 → 无头任务 → Linux 上线 → 统一 Key 骨架”的顺序写配置全部可复制最后给一套用 TaoToken 做统一通道的config.toml与settings.json骨架。需要先说明Harness 目前是开发者预览阶段版本迭代快官方明确提示后续会有破坏兼容性的变更。所以下面的命令我都标了版本前提升级前先备份$DSH_HOME。2. 部署前准备与环境校验先确认 Node 版本这是最容易翻车的一步。项目要求^22.19.0或24.0.0Node 20 会直接报错退出。node -v npm -v如果你要跑源码或开发插件再补 pnpmcorepack enable corepack prepare pnpm11.7.0 --activate pnpm -v运行目录建议单独开一个 workspace不要让 agent 直接操作系统根目录。我一般用/srv/dsh-workspace权限单独给一个系统用户。另外提前想清楚模型通道是直连官方还是走统一网关。如果打算多工具共用一套 Key建议一开始就把DEEPSEEK_BASE_URL留出来后面接 TaoToken 的 OpenAI 兼容端点时不用改结构。注意Harness 的 Web UI 会执行代码、改文件、跑命令所以它天然是一个“高权限进程”。任何把它暴露到公网的操作都要先想清楚认证和隔离。3. 最快路径一行命令拉起 Web UI官方推荐的第一条命令就是它npx deepseek-ai/dsh web首次运行会通过 npm 下载deepseek-ai/dsh并初始化 web profile默认监听http://127.0.0.1:3080。浏览器打开后三步跑通第一个任务打开“设置 → 模型”填 Key 并保存点“选择工作区”添加你启动 dsh 时所在的目录新建会话发一条任务比如“Summarize this repository and identify its main packages”。密钥保存在$DSH_HOME/.credentials.yamlWeb UI 只展示脱敏描述符不回显明文保存后不需要重启服务。3080 被占用就换端口npx deepseek-ai/dsh web --port 8080长期用建议全局装别每次走 npxnpm install -g deepseek-ai/dsh dsh --version dsh web源码部署适合二次开发和插件调试注意必须先 build仓库不会在启动时自动构建前端产物git clone https://github.com/deepseek-ai/deepseek-harness.git cd deepseek-harness pnpm install pnpm run build pnpm dsh web --port 8080无头模式不需要浏览器把最终答案打到 stdout任务正常完成以 0 退出否则以 1 退出适合接 CIexport DEEPSEEK_API_KEYsk-your-key-here dsh --profile headless run the tests任务文本必须作为位置参数直接跟在命令后面headless profile 不接受--port这类 Web UI 参数。排查组合配置时可以不启动服务直接打印配置树dsh --profile web --dump-default-config dsh --profile web --patch ./extra.yml --dump-config4. TaoToken 前置把模型通道收成一条到这一步 Harness 已经能跑了但模型 Key 还是散的。我的做法是把它接到 TaoToken 的统一通道上官网入口在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 基址是 https://taotoken.net/api 这个地址不加 UTM。它的作用是给你一个 OpenAI 兼容的入口Harness、Cline、CC Switch 都指向同一个 base_urlKey 只维护一份。先去控制台建 Key入口是 https://taotoken.net/console?utm_sourcetaotoken_aicg_blog_endutm_contentconsoleutm_campaignrewrite Key 管理页在 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 。拿到sk-开头的串之后先别急着写进 Harness用一条 curl 验证通道本身是通的curl -s https://taotoken.net/api/v1/chat/completions \ -H Authorization: Bearer $TAOTOKEN_API_KEY \ -H Content-Type: application/json \ -d { model: deepseek-chat, messages: [{role: user, content: reply with ok}] }返回体里能看到choices[0].message.content就说明通道没问题。这一步很关键因为后面 Harness 报MISSING_CREDENTIAL或UNKNOWN_MODEL时你要能分清是通道问题还是 Harness 配置问题。模型名以你控制台里实际可用的为准别照抄。想先在网页里试模型可以用模型对话页 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chatutm_campaignrewrite 。5. 可复制配置config.toml 与 settings.json 骨架Harness 的模型配置支持自定义 OpenAI 兼容提供方所以把 base_url 指到 TaoToken 即可。下面这份config.toml骨架放在$DSH_HOME下字段按你实际环境替换# $DSH_HOME/config.toml [providers.taotoken] type openai-compatible base_url https://taotoken.net/api/v1 api_key_env TAOTOKEN_API_KEY default_model deepseek-chat [profiles.web] provider taotoken workspace /srv/dsh-workspace trusted_host [dsh.example.com] [profiles.headless] provider taotoken permission_mode workspace-write对应的settings.json骨架给 Cline / CC Switch 这类工具共用同一套通道{ provider: openai-compatible, baseUrl: https://taotoken.net/api/v1, apiKeyEnv: TAOTOKEN_API_KEY, model: deepseek-chat, models: [ { id: deepseek-chat, label: DeepSeek Chat }, { id: deepseek-reasoner, label: DeepSeek Reasoner } ], requestTimeoutMs: 120000 }环境变量统一写进/etc/dsh.env权限收紧到 600sudo tee /etc/dsh.env /dev/null EOF DSH_HOME/var/lib/dsh TAOTOKEN_API_KEYsk-your-taotoken-key DEEPSEEK_BASE_URLhttps://taotoken.net/api/v1 EOF sudo chmod 600 /etc/dsh.envCC Switch 里新增一个 providerBase URL 填https://taotoken.net/api/v1Key 填同一个TAOTOKEN_API_KEY模型 id 与上面models数组保持一致。这样 Harness、Cline、CC Switch 三处指向同一通道换额度只改一个地方。如果你要长期跑编码和 Agent 任务可以看下 Coding Plan https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 接入细节在文档 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。6. Linux 服务器上线systemd 与 NginxHarness 的 Web 服务器本身不提供 TLS、认证或来源策略CLI 层故意拒绝--host 0.0.0.0就是为了避免把远程代码执行能力直接暴露到网络。正确姿势是服务只监听回环前面放 HTTPS 反向代理再加一层认证。先建专用用户和目录sudo useradd --system --create-home --home-dir /var/lib/dsh dsh sudo mkdir -p /srv/dsh-workspace sudo chown -R dsh:dsh /srv/dsh-workspace /var/lib/dsh sudo npm install -g deepseek-ai/dsh which dshsystemd 单元假设 dsh 在/usr/local/bin/dsh[Unit] DescriptionDeepSeek Harness Web Afternetwork-online.target [Service] Userdsh Groupdsh WorkingDirectory/srv/dsh-workspace EnvironmentFile/etc/dsh.env ExecStart/usr/local/bin/dsh web --port 3080 --trusted-host dsh.example.com Restarton-failure RestartSec5 TimeoutStopSec10 NoNewPrivilegestrue PrivateTmptrue [Install] WantedBymulti-user.target写入并启动sudo nano /etc/systemd/system/dsh-web.service sudo systemctl daemon-reload sudo systemctl enable --now dsh-web sudo systemctl status dsh-web--trusted-host把浏览器访问的域名加入/api信任围栏可重复传入。WorkingDirectory是 agent 的默认 workspace务必是专门目录。Nginx 反向代理骨架server { listen 443 ssl http2; server_name dsh.example.com; ssl_certificate /etc/letsencrypt/live/dsh.example.com/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/dsh.example.com/privkey.pem; auth_basic dsh; auth_basic_user_file /etc/nginx/.dsh_htpasswd; location / { proxy_pass http://127.0.0.1:3080; proxy_http_version 1.1; proxy_set_header Host $host; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection upgrade; proxy_set_header X-Forwarded-Proto $scheme; } }Web UI 需要 WebSocket反向代理必须转发Upgrade和Connection否则页面能开但会话不刷新。没有内置认证务必在代理层加 Basic Auth、SSO 或只允许内网 IP。7. 验证请求与成功结果回显上线后按顺序验三件事。第一服务活着systemctl is-active dsh-web ss -lntp | grep 3080应该看到监听在127.0.0.1:3080不是0.0.0.0。第二通道活着用第 4 节那条 curl 再跑一次确认返回ok。第三Harness 内部能拿到凭据并选到模型用无头模式跑一条最小任务sudo -u dsh env $(cat /etc/dsh.env | xargs) \ dsh --profile headless print the current working directory成功时 stdout 会输出 workspace 路径退出码为 0echo $? # 0如果走 Web UI打开https://dsh.example.com新建会话发“list files in workspace”能看到 agent 返回文件列表就说明整条链路通了。这一步的返回内容会直接回显在会话里方便你确认模型确实是被 Harness 调起来的而不是本地缓存。8. 本篇常见错排查启动后打不开页面默认地址是http://127.0.0.1:3080先确认进程还在、端口没被占。端口冲突用dsh web --port 8080。如果走 Nginx检查Upgrade头有没有转发。提示MISSING_CREDENTIAL密钥解析顺序是环境变量、$DSH_HOME/.credentials.yaml、调用目录.env、$DSH_HOME/.env。systemd 托管时最容易漏EnvironmentFile确认/etc/dsh.env里TAOTOKEN_API_KEY拼写正确、权限 600、属主可读。提示UNKNOWN_MODEL自定义 OpenAI 兼容端点需要手动补模型 idconfig.toml里的default_model和settings.json里的model必须与控制台可用模型一致。改完记得systemctl restart dsh-web。为什么不能--host 0.0.0.0CLI 有意拒绝因为 Web UI 会执行代码、改文件、跑命令直接绑全网卡等于把远程代码执行暴露到网络。保持回环监听用反向代理转发。备份与更新至少备份整个$DSH_HOME里面包含密钥、settings、profiles 和会话数据。sudo tar czf /backup/dsh-$(date %F).tar.gz /var/lib/dsh sudo npm update -g deepseek-ai/dsh sudo systemctl restart dsh-web因为是开发者预览升级前先看官方发布说明确认没有破坏性变更再动。源码部署则git pull pnpm install pnpm run build后重启。9. 统一 Key 之后接入与排障走这两条路把 Harness 接到统一通道之后剩下的事基本都围绕 Key 和接入文档转。Key 的创建、轮换、额度查看都在 API Keys 页 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi-keysutm_campaignrewrite 接入参数、base_url 写法、OpenAI 兼容细节在文档 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。遇到MISSING_CREDENTIAL、UNKNOWN_MODEL这类报错先回第 4 节的 curl 确认通道再回第 5 节核对config.toml与settings.json的模型 id 是否一致最后看 systemd 的EnvironmentFile有没有被正确加载。想先在网页里验证模型可用性用模型对话页 https://taotoken.net/chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel-chatutm_campaignrewrite 最快长期跑编码和 Agent 任务Coding Plan https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding-planutm_campaignrewrite 里能直接看到通道配置方式。Claude Code 相关的接入示例在 https://taotoken.net/claude-code-anthropic?utm_sourcetaotoken_aicg_blog_endutm_contentclaude-code-anthropicutm_campaignrewrite 和 Harness 共用同一个 Key 即可。