全栈应用服务器

  • 全栈应用服务器 > 使用指南 > 沙箱服务概述 > AI Agents > DeepSeek Harness

    DeepSeek Harness

    最近更新时间: 2026-09-09 14:17:58

    概述

    deepseek-harness 是预构建的 DeepSeek Harness Web UI 运行环境。它在隔离的 Sandbox 中启动 dsh web,通过浏览器访问 Harness 的会话、任务和工具界面,适合需要把 Harness 作为临时开发工作区交给开发者或自动化流程的场景。

    模板基于 agents-base,内置 Node.js、Python、Git 和常用排障工具;不内置任何 DeepSeek API key。每个 Sandbox 创建时注入自己的 API key 和 Web UI 登录密码,避免 不同 Sandbox 之间共享凭据。

    长期架构、认证边界和版本演进策略见模板方案

    模板内容

    组件 说明
    @deepseek-ai/dsh 固定版本 0.1.2-alpha.5 的 DeepSeek Harness CLI
    Harness Web UI 运行在 Sandbox 内 127.0.0.1:3080
    Web 网关 运行在 0.0.0.0:8080,负责登录和 HTTP / SSE / WebSocket 转发
    Supervisor 使用启动命令继承的运行时 ENV,并负责重启 dsh 和网关
    公共工具 Node.js 24.x、Python、git、ripgrep、vim、GitHub CLI、pnpm、tsx、vite

    Harness 保持 loopback 监听,公网只暴露网关端口 8080。创建 Sandbox 后使用 sandbox.getHost(8080) 获取访问地址。

    创建 Sandbox

    创建时至少提供 DEEPSEEK_API_KEYDSH_WEB_PASSWORD。密码应由调用方随机生成并 保存在自己的安全存储中,不要写入 URL、日志或前端代码。浏览器流量需要到达模板内的 网关,因此示例开启 allowPublicTraffic;envd 继续使用 secure 模式保护运行时 API。 SDK 连接七牛 Sandbox 控制面时需要 QINIU_API_KEYQINIU_SANDBOX_API_URL;兼容 E2B SDK 命名的 E2B_API_KEYE2B_API_URL 也可以使用。

    import { setTimeout as delay } from "node:timers/promises";
    import { Sandbox } from "e2b";
    
    function requiredEnv(name, ...aliases) {
      for (const key of [name, ...aliases]) {
        if (process.env[key]) return process.env[key];
      }
      throw new Error(`${[name, ...aliases].join(" or ")} is required`);
    }
    
    const apiKey = requiredEnv("QINIU_API_KEY", "E2B_API_KEY");
    const apiUrl = requiredEnv("QINIU_SANDBOX_API_URL", "E2B_API_URL");
    const deepseekApiKey = requiredEnv("DEEPSEEK_API_KEY");
    const webPassword = requiredEnv("DSH_WEB_PASSWORD");
    const sandbox = await Sandbox.create("deepseek-harness", {
      apiKey,
      apiUrl,
      timeoutMs: 60 * 60 * 1000,
      secure: true,
      network: { allowPublicTraffic: true },
      envs: {
        DEEPSEEK_API_KEY: deepseekApiKey,
        DEEPSEEK_BASE_URL: "https://api.deepseek.com",
        DSH_HOME: "/home/user/.dsh",
        DSH_WEB_USER: "sandbox",
        DSH_WEB_PASSWORD: webPassword,
      },
    });
    
    await sandbox.commands.run("/opt/deepseek-harness/start.sh");
    
    const webURL = `https://${sandbox.getHost(8080)}`;
    let ready = false;
    for (let attempt = 0; attempt < 30; attempt++) {
      try {
        const response = await fetch(`${webURL}/_health`, {
          signal: AbortSignal.timeout(3000),
        });
        if (response.ok) {
          ready = true;
          break;
        }
      } catch (error) {
        if (attempt === 29) throw error;
      }
      await delay(1000);
    }
    if (!ready) throw new Error("gateway is not ready");
    
    // webPassword 应通过调用方的安全存储或授权渠道提供,不要写入日志。
    console.log({ webURL, webUser: "sandbox" });
    

    创建完成后执行的 start.sh 通过 SDK 已认证的 envd 命令接口启动运行时进程。示例会等待 /_health 返回 200 后再提示访问。该命令继承 创建请求中的 envs,因此 API key 和登录密码不需要经过公开端口再次传递。

    getHost(8080) 返回主机名,示例为其补充 https:// 协议后得到浏览器地址。不要把平台的 e2b-traffic-access-token 当作浏览器登录凭据;浏览器入口由模板网关的登录页保护。

    浏览器登录

    打开 webURL 后输入创建 Sandbox 时使用的 DSH_WEB_USERDSH_WEB_PASSWORD

    1. 未登录访问返回登录页。
    2. 登录成功后网关设置 8 小时有效的 HttpOnly、Secure、SameSite Strict Cookie,并跳转到 Harness。
    3. UI 的普通请求、SSE 请求和 WebSocket 连接都会复用该 Cookie。
    4. 登录失败响应会延迟 500 毫秒,正确凭据不会被其他请求锁定。

    /_health 是内部就绪检查端点,不需要登录;它只有在 Harness 后端可达时返回 200。

    环境变量

    变量 必需 默认值 说明
    DEEPSEEK_API_KEY DeepSeek 模型 API 凭据
    DEEPSEEK_BASE_URL 上游默认值 模型 API 地址
    DEEPSEEK_SEARCH_BASE_URL 上游默认值 搜索服务地址
    DSH_HOME /home/user/.dsh Harness 配置、profile 和会话目录
    DSH_WEB_USER sandbox Web UI 登录用户名
    DSH_WEB_PASSWORD Web UI 登录密码,UTF-8 编码至少 16 字节,建议每个 Sandbox 随机生成

    模板构建阶段没有用户的 envs。构建快照中网关会使用一次性随机密码完成启动;创建 Sandbox 后,通过 SDK 调用 start.sh,让 supervisor、dsh 和网关继承 envd 为该命令 提供的运行时 ENV。正式 Sandbox 必须注入自己的 DSH_WEB_PASSWORD 并执行启动命令, 否则调用方没有已知的登录凭据。

    生命周期

    启动 Sandbox 时,SDK 执行 start.sh,以运行时 ENV 重新拉起 dsh web 和网关; supervisor 会在任一子进程异常退出后重启二者。Harness 配置和工作区文件保存在 Sandbox 文件系统中。暂停与恢复不会改变外部 URL 的端口格式或运行时 ENV。

    使用完成后删除 Sandbox,及时使 URL、会话 Cookie 和运行时 API key 失效:

    await sandbox.kill();
    

    故障排查

    可以通过 SDK 执行以下命令查看监听状态和日志:

    console.log((await sandbox.commands.run(
      "ss -lntp | grep -E ':3080|:8080'",
    )).stdout);
    console.log((await sandbox.commands.run(
      "tail -n 80 /tmp/deepseek-harness/dsh.log /tmp/deepseek-harness/gateway.log",
    )).stdout);
    
    • /_health 非 200:先检查 3080 是否监听,再查看 dsh 日志和 DEEPSEEK_API_KEY
    • 登录失败:确认已通过 SDK 执行 start.sh,且创建请求中的密码满足最小长度要求。
    • UI 请求断开:确认访问的是 getHost(8080),并检查平台 Proxy 是否允许长连接。

    参考

    以上内容是否对您有帮助?