1. 手机跑 DeepSeek Harness 到底卡在哪Android Termux 部署的真实门槛DeepSeek Harness社区简称 dsh是 DeepSeek AI 开源的一套 agent harnessTypeScript 写的MIT 协议目前还是开发者预览版。它的定位不是安卓 App而是一个 Node.js 命令行工具加一个本地 Web UI。也就是说你不需要等官方出安卓客户端只要手机能跑 Node.js理论上就能把它的 Web 界面跑起来然后用手机浏览器访问http://127.0.0.1:3080。那为什么很多人一试就失败核心矛盾在于Android 上的 Node.js 运行环境和标准 Linux 差异很大。Termux 虽然提供了接近 Linux 的包管理但 Google Play 版 Termux 里的 Node 会把process.platform报告成android而不是linux。这个细节直接导致 node-gyp 在编译原生模块时找不到android_ndk_path变量报出gyp: Undefined variable android_ndk_path。dsh 依赖三个需要从源码编译的原生模块node-pty终端子进程、koffiFFI用于文件系统和目录选择、sharp图像处理。Android 上没有 glibc/musl 的预编译二进制所以这三个都得现场编译门槛就卡在这里。这篇内容适合谁适合手上有安卓手机、装了 Termux、想在不买云服务器的情况下把 DeepSeek Harness 的 Web UI 跑起来的人。全程只需要在 Termux 里敲命令不需要 root不需要额外硬件。我会把依赖安装、Node 头文件修补、dsh 安装、Web UI 启动、以及几个高频报错的排查都走一遍。实测下来一台中端安卓机大概 5 到 10 分钟能装完占用存储约 1GB编译工具链加 node 依赖。需要提前说清楚dsh 本身只是个“空壳”harness不配模型它跑不了实际任务。安装阶段不需要 API key但真正用 agent 功能时你得准备一个 DeepSeek API key。另外Termux 进程挂在手机后台系统回收是常态后面会讲怎么让它活得久一点。2. TaoToken 前置准备给 Harness 配一个稳定的模型入口dsh 的 Web UI 起来之后第一件事是配置模型。它支持填 DeepSeek 官方 API key也支持自定义 Base URL。如果你希望把模型调用统一走一个入口方便在多个工具之间切换可以先把 TaoToken 的配置准备好。TaoToken 是一个模型调用聚合入口官网是 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 地址是 https://taotoken.net/api 。在 dsh 的模型配置页里你需要填三样东西Base URL、API Key、Model ID。Base URL 填https://taotoken.net/apiAPI Key 在控制台的 API Keys 页面生成Model ID 按你要用的模型填比如deepseek-chat或deepseek-reasoner。这三件套是后面所有验证动作的基础缺一个都会在请求阶段报错。如果你还没生成 Key可以走这个路径先打开 https://taotoken.net/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 创建然后回到 dsh 的配置界面粘贴。想先确认模型能不能正常对话可以用模型对话页 https://taotoken.net/model-chat?utm_sourcetaotoken_aicg_blog_endutm_contentmodel_chatutm_campaignrewrite 发一条测试消息确认返回正常再回到 dsh 里配。如果你打算长期在手机上跑 agent 任务Coding Plan 页面 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 里有更细的额度说明可以先看一眼再决定用哪种方式。这里要提醒一点dsh 的 Web UI 配置模型时Base URL 不要带末尾斜杠也不要带/v1之外的路径直接填https://taotoken.net/api即可。填错路径最常见的表现是请求返回 404 或者reading choices报错后面排障章节会细说。3. 可复制配置Termux 里从零装到 dsh web 启动这一节是全文最核心的部分所有命令都可以直接复制粘贴。建议按顺序执行不要跳步。整个过程分五段基础环境、Node 头文件修补、安装 dsh、安装 sharp 的 wasm 回退、验证安装。3.1 基础环境安装先更新包索引并安装编译工具链pkg update -y pkg install -y nodejs clang make python binutils pkg-config cmake ninja为什么装这么多node-pty 走 node-gyp需要 clang、make、pythonkoffi 走 cmake所以 cmake 和 ninja 也要。binutils 和 pkg-config 是编译链接阶段的基础工具。这一步大概 2 到 3 分钟取决于网络。3.2 修补 Node 头文件关键步骤Google Play 版 Termux 的 Node 报告process.platform android导致 node-gyp 编译时android_ndk_path变量未定义。解决办法是下载对应版本的 Node 头文件然后删掉那一行引用NODE_VER$(node -v | tr -d v) HEADER_DIR$HOME/.cache/node-gyp/$NODE_VER if [ ! -f $HEADER_DIR/include/node/common.gypi ]; then mkdir -p $HOME/.cache/node-gyp curl -fsSL https://nodejs.org/download/release/v$NODE_VER/node-v$NODE_VER-headers.tar.gz -o /tmp/node-headers.tgz tar -xzf /tmp/node-headers.tgz -C $HOME/.cache/node-gyp mv $HOME/.cache/node-gyp/node-v$NODE_VER $HEADER_DIR rm -f /tmp/node-headers.tgz fi sed -i s#, -I(android_ndk_path)/sources/android/cpufeatures## $HEADER_DIR/include/node/common.gypi echo 头文件已就绪并修补$HEADER_DIR执行完看到头文件已就绪并修补就对了。这一步是整篇教程里最容易漏掉的漏了后面装 dsh 必报gyp: Undefined variable android_ndk_path。3.3 安装 dsh 并放行原生模块脚本npm 11.17 起有allow-scripts安全特性默认拦截所有 install 脚本。dsh 依赖的几个包需要编译或初始化必须显式放行npm install -g --allow-scriptsdeepseek-ai/dsh-subprocess-local,koffi,node-pty,google/genai,protobufjs deepseek-ai/dsh这里放行了 5 个包deepseek-ai/dsh-subprocess-local、koffi、node-pty、google/genai、protobufjs。node-pty 和 koffi 需要从源码编译不放行就会跳过编译运行时直接报模块加载失败。3.4 安装 sharp 的 WebAssembly 回退sharp 没有 Android 预编译二进制装 wasm 版作为运行时回退npm install -g img/sharp-wasm323.5 验证安装dsh --version输出0.1.0-rc.7或更高版本号即安装成功。如果这一步报错先回看 3.2 的头文件修补是否执行成功。3.6 启动 Web UI推荐先创建一个启动脚本之后每次只需一条命令cat $PREFIX/bin/dsh-web EOF #!/data/data/com.termux/files/usr/bin/bash pkill -f dsh/lib/bin.js 2/dev/null sleep 1 nohup node --expose-internals /data/data/com.termux/files/usr/lib/node_modules/deepseek-ai/dsh/lib/bin.js web /sdcard/Download/dsh-web.log 21 sleep 2 echo DeepSeek Harness 已启动: http://127.0.0.1:3080 tail -3 /sdcard/Download/dsh-web.log EOF chmod x $PREFIX/bin/dsh-web以后启动只需输入dsh-web注意--expose-internals这个参数不能省。dsh 的 web profile 里 HMR 插件要求这个 Node 启动参数用npx dsh web默认启动会崩。启动成功的标志是日志里出现dsh web: http://127.0.0.1:3080。4. 验证请求确认 Harness 服务真的在响应装完不等于跑通得验证服务确实在响应。分三步确认进程在跑、确认端口在听、确认浏览器能打开并完成一次模型对话。4.1 确认进程和端口在 Termux 里执行ps aux | grep dsh/lib/bin.js | grep -v grep应该能看到一个 node 进程。再看端口curl -s -o /dev/null -w %{http_code} http://127.0.0.1:3080返回200说明 Web 服务已经在监听。如果返回000说明进程没起来或者端口没绑上回看 3.6 的日志。4.2 浏览器访问并配置模型手机浏览器打开http://127.0.0.1:3080。欢迎页点「继续」选择工作区进入「标准模式」然后配置模型。这里填三件套配置项填写内容Base URLhttps://taotoken.net/apiAPI Key在控制台生成的sk-开头的 KeyModel IDdeepseek-chat或deepseek-reasoner填完保存发一条测试消息比如「你好请回复 OK」。如果返回正常说明整条链路通了。4.3 用 curl 直接验证模型接口如果浏览器里报错但不确定是 dsh 的问题还是模型接口的问题可以在 Termux 里直接用 curl 打一次模型接口curl -s https://taotoken.net/api/chat/completions \ -H Content-Type: application/json \ -H Authorization: Bearer 你的Key \ -d {model:deepseek-chat,messages:[{role:user,content:回复OK}]}返回 JSON 里带choices字段就说明模型接口正常。这一步能把「dsh 配置问题」和「模型接口问题」分开定位。5. 本篇常见错排查401、local proxy failed、reading choices、OAuth这一节按真实报错来对照每个都给出原因和动作。报错一gyp: Undefined variable android_ndk_path原因Google Play 版 Node 报platformandroidnode-gyp 找不到 NDK 路径变量。解决回到 3.2 执行头文件修补确认common.gypi里那一行已经被 sed 删掉。F-Droid 版如果报linux则不需要这步。报错二Error: CMake does not seem to be available原因koffi 需要 cmake。解决pkg install -y cmake ninja然后重新执行 3.3 的安装命令。报错三npm 提示 allow-scripts ... not yet covered原因npm 11.17 拦截了 install 脚本。解决在安装命令里加--allow-scripts...放行对应包参考 3.3。报错四sharp 报 Could not load the sharp module原因Android 没有 sharp 预编译二进制。解决npm install -g img/sharp-wasm32参考 3.4。报错五listen EADDRINUSE ... 127.0.0.1:3080原因3080 端口被占用通常是旧进程没退干净。解决pkill -f dsh/lib/bin.js后重新跑dsh-web。报错六浏览器打不开127.0.0.1:3080原因dsh 没在跑或者 Termux 被系统后台回收了。解决回 Termux 再跑一次dsh-web。建议启动后下拉通知栏点Acquire wakelock减少被 Doze 杀掉。报错七401 Unauthorized原因API Key 填错、过期或者 Base URL 路径不对。解决确认 Key 是sk-开头且没过期Base URL 填https://taotoken.net/api不要带多余路径。如果用的是自定义入口确认 Key 和入口是配套的。报错八local proxy failed原因dsh 在请求模型接口时连接失败常见于 Base URL 写错或者网络环境异常。解决先用 4.3 的 curl 命令直接打接口确认接口本身可达。如果 curl 通但 dsh 不通检查 dsh 配置里的 Base URL 是否和 curl 用的一致。报错九reading choices相关报错原因模型接口返回的 JSON 结构不符合预期通常是 Base URL 路径错了请求打到了非 completions 端点。解决确认 Base URL 是https://taotoken.net/api不要写成https://taotoken.net/api/v1或其他变体。如果用的是其他入口确认端点路径。报错十OAuth 相关报错原因某些模型入口需要 OAuth 流程而 dsh 里填的是 API Key 方式。解决确认你用的入口支持 API Key 直连。如果报 OAuth 错误说明当前配置走的是 OAuth 路径需要换成支持 Key 的入口或者按入口文档完成 OAuth 授权。排查顺序建议先 curl 打模型接口确认接口通再确认 dsh 进程和端口最后看 dsh 配置三件套。这样能最快定位问题在哪一层。6. 长期在手机上跑 Harness把模型入口固定下来手机端跑 dsh 最大的不确定性不是安装而是进程存活和模型入口的稳定性。Termux 被系统回收是常态所以dsh-web脚本里带了pkill和nohup每次启动前先清旧进程再拉新的。日志写到/sdcard/Download/dsh-web.log出问题直接看这个文件比在 Termux 里翻屏方便。模型入口这块如果你只是偶尔测试用模型对话页手动发消息就够了。如果打算长期在手机上跑 agent 任务建议把 Base URL、Key、Model ID 三件套固定下来写在一个笔记里换设备或者重装 Termux 时直接复用。Coding Plan 页面里有额度说明长期跑之前先确认额度够用。还有一个实用技巧dsh 更新很频繁开发者预览版可能有破坏性变更。更新前先看 changelog更新命令是npm update -g deepseek-ai/dsh更新完重新跑dsh-web如果启动失败先看日志里是不是又出现了原生模块编译问题必要时重跑 3.2 的头文件修补。最后说一个我踩过的坑Termux 里node -v的版本号和头文件版本必须一致否则 3.2 下载的头文件对不上编译还是会失败。如果换了 Node 版本记得把$HOME/.cache/node-gyp/下旧版本目录删掉再重跑 3.2。整个流程走通之后手机浏览器访问http://127.0.0.1:3080就能看到 dsh 的 Web UI配置好模型三件套就能开始跑任务了。