DeepSeek Harness SDK 集成架构方案

DeepSeek Harness SDK 集成架构方案(Python · 单机多用户 · 技能隔离与共享)

版本:v0.1 草案 | 日期:2026-10-19 | 适用范围:Python 服务端集成 DeepSeek Harness SDK,同一台机器服务数百用户,每用户 1~2 个并发会话。

0. 摘要

本方案把 DeepSeek Harness 的 SDK 形态(dsh --profile sdk 的 stdio JSON-RPC 运行时)嵌入一个 Python 单机服务端:Python 后端作为控制面与 API 面,为每个用户拉起独立的 DSH 运行时子进程,通过按行分帧的 JSON-RPC 2.0 协议驱动 agent。隔离与共享按三个正交维度展开:

维度 手段 粒度
用户隔离 每用户独立 $DSH_HOME + 独立 workspace 根 + 独立子进程 + bash 沙箱 + 资源配额(cgroup/rlimit/token) 用户
会话隔离 sessionId 以用户为命名空间;会话 JSONL 落在用户自己的 DSH_HOME 下;编排层只把会话路由给所属用户的运行时 会话
技能隔离/共享 三来源:用户私有 <DSH_HOME>/skills + 组织共享只读目录(Git/HTTP 同步)+ 远程技能注册中心;dsh-skill 注册表合并多提供方 技能/用户/角色

核心设计决策:

  1. 进程模型:一用户一运行时(长期驻留)+ 空闲回收。DSH SDK 服务器为每个 sessionId 在同一个进程内创建 agent,因此一个运行时子进程可承载该用户全部并发会话;按需拉起、空闲超时优雅关闭,把"数百用户 × 1~2 会话"映射为"数百个可控的 Node 子进程"。
  2. 隔离原语复用官方机制:$DSH_HOME 环境变量(每用户一份配置文件/凭据/会话/技能)、InitializeParams.cwd 指定用户 workspace、dsh-bash-sandbox 的 workspace-write/read-only 模式限制文件影响、InitializeParams.maxTokens 做 token 配额。
  3. 技能三来源合并,注册表裁决:共享技能只读挂载进每个用户的运行时(customSkillDirs/patch 配置),用户私有技能在各自 DSH_HOME;需要远程注册中心时,用一个轻量 Cordis 插件或目录同步把"服务端技能目录"变成每个运行时可发现的只读提供方。服务端技能 API 做 RBAC 过滤(按角色/用户返回可见技能)。
  4. 会话生命周期归 Python 编排器所有:SDK 协议没有逐会话关闭/提示词取消方法,agent 活到进程关闭——因此"结束会话/取消任务"由编排器对进程做优雅关闭(shutdown 请求 → SIGTERM → SIGKILL 逐级升级)实现。
  5. 交付形态:Python 包(库 + CLI 双形态):服务端以 pip 包发布,既可 dsh-server 命令独立部署,也可 from dsh_server.embed import create_app 嵌入其他 Python 项目(库模式挂载 FastAPI 路由/编程式 API),满足"方便其他项目引用"的最终目标。

1. 背景与目标

1.1 业务目标

1.2 非目标(v0.1 明确不做)


2. 事实基础:DSH SDK 关键能力(已核实,版本 0.2.0-rc.2)

以下事实来自本机安装的 @deepseek-ai/dsh@0.2.0-rc.2 及其插件包 README/代码。

2.1 SDK 运行时形态

2.2 协议面(dsh-sdk-protocol)

方向 方法 语义
client→server initialize 握手:provider/model、可选 reasoningEffort、可选 maxTokens、cwd;返回 serverInfo.name = "deepseek-harness-sdk-runtime"
client→server session/prompt 按 sessionId 排队一条用户消息,立即返回 { messageId }(仅表示已入队,不是结果)
client→server shutdown dispose 根运行时并退出(退出码 0)
server→client session.event 每个持久化事实(会话日志事件流)
server→client session.status agent 整机 running/idle 状态转换
server→client subagent.started / subagent.finished 子 agent 边界事件

关键限制(决定架构的事实):

2.3 会话与持久化

2.4 技能子系统(dsh-skill + dsh-skill-filesystem)

rank 来源 路径
100 project-dsh <projectRoot>/.dsh/skills(cwd 最近 .git 祖先)
200 project-agents <projectRoot>/.agents/skills
300 custom Config.customSkillDirs
400 user-dsh <dshHome>/skills
500 user-agents <agentsHome>/skills
600 bundled $DSH_BUNDLED_SKILL_DIR / bundledSkillDir

2.5 文件沙箱(dsh-bash-sandbox)

2.6 主目录与数据布局(dsh-home-paths)


3. 总体架构

总体架构图

打开可交互总览图

┌───────────────────────────── 用户前端 / 技能管理控制台 ─────────────────────────────┐
│  HTTPS · JWT                                                                       │
└─────────────────────────────────────────┬──────────────────────────────────────────┘
                                          ▼
┌────────────────────────────── Python 服务端(单机) ────────────────────────────────┐
│  ┌──────────────┐  RBAC   ┌─────────────────────┐  发布/审批/授权   ┌──────────────┐ │
│  │ API 网关/认证 │ ───────▶│   Python 应用层      │ ────────────────▶│ 技能服务中心  │ │
│  │ (FastAPI)    │         │ 会话/技能/配额 API   │                  │ 目录·审批·版本│ │
│  └──────────────┘         └───────┬─────────────┘                  └──────┬───────┘ │
│                                   │ 用户/授权/配额                        │ 校验后发布
│                                   ▼                                       ▼         │
│                          ┌──────────────────┐                   ┌──────────────────┐│
│                          │ 运行时编排器       │ ◀──订阅同步──      │ 共享技能目录(只读) ││
│                          │ spawn/回收/健康/配额│                   │ Git/HTTP 同步     ││
│                          └───────┬──────────┘                   └────────┬─────────┘│
│                        spawn/stdio│监控                    只读挂载(customSkillDirs) │
│        ┌─────────────────────────┼───────────────────────────┐              │       │
│        ▼                         ▼                           ▼              ▼       │
│  ┌─────────────┐          ┌─────────────┐            ┌─────────────┐  ┌───────────┐ │
│  │ dsh 运行时A  │          │ dsh 运行时B  │            │  dsh 运行时… │  │ 私有技能   │ │
│  │ DSH_HOME[A] │          │ DSH_HOME[B] │            │             │  │ <DSH_HOME>│ │
│  │ workspace[A]│          │ workspace[B]│            │             │  │ /skills    │ │
│  └──────┬──────┘          └──────┬──────┘            └─────────────┘  └───────────┘ │
└─────────┼─────────────────────────┼───────────────────────────────────────────────┘
          ▼                         ▼
   ┌─────────────────────────────────────────────┐
   │            DeepSeek 模型 API(各自凭据)        │
   └─────────────────────────────────────────────┘

3.1 分层职责

层 组件 职责
接入层 API 网关/认证(FastAPI 中间件) 认证(JWT/OIDC 对接企业账号)、RBAC、限流、审计入口
应用层 Python 应用服务 会话管理 API、技能管理 API、配额/计费 API、业务编排;把用户请求翻译成对运行时编排器的调用
编排层 运行时编排器(RuntimeManager) 用户运行时生命周期(spawn/健康/回收/崩溃重启)、协议客户端之上的会话-进程路由、事件分发、配额执行(token/并发/存储)
集成层 JSON-RPC over stdio 客户端 initialize / session/prompt / shutdown + 4 类通知;asyncio 行分帧;事件规范化
运行时层 dsh --profile sdk 子进程(每用户一个) agent 执行、持久会话、工具、技能发现/加载、bash 沙箱
技能层 技能服务中心 + 共享技能目录 + 私有技能区 + 远程注册中心 技能全生命周期(编写→评审→版本→分发→回收);权限过滤
数据层 元数据库(用户/授权/配额)、会话持久化(JSONL in DSH_HOME)、技能版本库、审计日志 状态与证据

4. 多用户隔离设计

4.1 隔离模型总览

用户 = 一个运行时子进程 + 一份 $DSH_HOME + 一个/多个 workspace 根 + 一组资源配额 + 一组授权(Grant)

主机
├── /data/harness/
│   ├── users/<uid>/
│   │   ├── dsh-home/            # $DSH_HOME——配置/凭据/会话JSONL/私有技能
│   │   ├── workspaces/
│   │   │   └── <project>/       # 传给 InitializeParams.cwd 的 workspace 根
│   │   └── logs/                # stderr 诊断(stdout 是协议通道,不许混日志)
│   ├── shared-skills/           # 组织共享技能(只读,Git/HTTP 同步,版本化)
│   ├── metaservice.db           # 用户/授权/配额/技能元数据(SQLite/Postgres)
│   └── audit/                   # 审计

4.2 六道隔离边界(自外向内)

# 隔离维度 机制 破坏后果
1 认证/授权 网关 JWT;编排器只接受"已认证用户"的会话指令;会话 ID 带用户命名空间(u:<uid>:<uuid>) 跨用户会话/进程注入
2 进程 每用户独立 Node 子进程;崩溃互不影响;OOM 由 cgroup 收割该进程 单用户拖垮全部
3 数据 每用户 $DSH_HOME + workspace 根;OS 用户/组权限(或目录 ACL);会话 JSONL 归属清晰 会话历史/凭据/私有技能泄露
4 文件执行 dsh-bash-sandbox:默认 workspace-write(只能写用户自己的 workspace + /tmp);高危模式 danger-full-access 必须逐次审批 agent 越权读写其他用户文件
5 资源 每用户:并发会话数上限、InitializeParams.maxTokens token 上限、cgroup 内存/CPU、进程数 rlimit;编排器级限流 资源耗尽型 DoS 与费用失控
6 网络 说明:bash 沙箱不约束网络。模型 API 出口走每用户自己的凭据(credentials seam 内代理);严格的出网白名单(若业务需要)留作 Linux netns/代理演进项 数据外发、凭据滥用

4.3 会话隔离与路由

4.4 凭据/密钥矩阵

凭据 存放 说明
用户身份 服务端会话(JWT) 网关签发,编排器不透传
模型 API Key 每用户 $DSH_HOME 的 credentials seam 一个用户一个 Key(或多 Key 按 profile 切换);绝不共享文件
技能仓库写权限 服务端(技能服务中心) 用户端只读

5. 技能隔离与共享设计

5.1 三来源技能拓扑

来源 物理位置 可见性 读写方 优先级(rank)
① 用户私有技能 <uid>/dsh-home/skills(即 <dshHome>/skills,rank 400) 仅该用户 用户本人(经技能 API 写入) 400
② 组织共享技能 主机 /data/harness/shared-skills,注入各运行时的 customSkillDirs(rank 300) 全体/角色子集 服务端 CI 只读同步;用户只读 300
③ 远程技能注册中心 服务端技能服务中心(HTTP API + 版本库) 按角色过滤 运营/管理员 经②物化或插件直连

优先级语义:rank 越小,注册表裁决重名时越优先。因此 ②组织共享技能 > ①用户私有技能——组织希望"运营强制技能覆盖个人同名技能"时成立;若希望"个人可覆盖组织默认",调整挂载 rank 即可(如把共享技能挂到 rank 较低的用户域之外的位置,或用 web 注入覆盖;见 §5.4 配置点)。

5.2 共享技能注入机制(②的落地)

方案 B1(推荐起步)——目录同步物化:远程注册中心/技能 Git 仓库 → CI 或后台任务 pull + 校验 + 物化 到 /data/harness/shared-skills/<version>/skills/,用原子符号链接 shared-skills/current -> <version> 做版本切换与秒级回滚。每个用户运行时通过 profile/home 级 patch 把 customSkillDirs: ["/data/harness/shared-skills/current/skills"] 注入。技能文件系统提供方监视目录,改文件即对存活会话生效(无需重启)。

方案 B2(进阶)——注册中心直连提供方:为 dsh profile 写一个 ~100 行的 Cordis 插件,ctx.skills.registerProvider 回调服务端 /api/skills?token=<user-scope-token>,目录远取、正文远取。优点:权限实时、无需常驻同步;缺点:依赖服务可用性、开发维护成本。作为 v0.2 演进。

两者可共存:dsh-skill 注册表本来就合并多提供方,多来源的"可见技能并集"是设计内的行为。

5.3 技能与用户/角色的可见性(RBAC)

5.4 按用户差异化注入的配置点(profile 层)

  1. $DSH_HOME/profiles/<name>/cordis.patch.yml:技能目录、工具集、MCP、沙箱默认模式的 profile 级定制;
  2. $DSH_HOME/cordis.patch.yml:home 级覆盖(按用户);
  3. dsh --profile <name> --patch <file>:逐次调用覆盖。 → 编排器在 spawn 用户运行时前按用户档案渲染一份 patch 集,实现"同一套服务端代码、不同用户的技能/策略不同"。

5.5 技能生命周期与治理

编写(SKILL.md) → 提交到技能仓库 → CI 校验(frontmatter/schema/lint)
  → 评审(人工/双人) → 打版本(语义化) → 发布(物化到共享目录 + 角色授权)
  → 运行时热发现生效 → 指标埋点(调用次数/效果) → 回收(下线版本 → 原子切 link)

6. 会话全生命周期(时序)

会话生命周期时序图

打开可交互时序图

用户前端        Python 编排器           dsh 运行时(用户U)        DeepSeek API
  │                  │                       │                       │
  │ POST /sessions   │                       │                       │
  ├─────────────────▶│ 校验 JWT/RBAC/配额    │                       │
  │                  │ 若运行时不存在:       │                       │
  │                  │  spawn dsh --profile sdk├───进程启动──────────▶│
  │                  │  DS H_HOME=<uid>/dsh-home│                       │
  │                  │  cwd=<uid>/workspaces/x │                       │
  │                  ├────── initialize(model, cwd, maxTokens) ──────▶│
  │                  │◀────── serverInfo/ok ────────────────────────  │
  │                  │                       │                       │
  │ POST /prompt     │                       │                       │
  ├─────────────────▶│ session/prompt        │                       │
  │                  │  (sessionId, content) ├──────────────────────▶│
  │                  │◀────── {messageId}    │                       │
  │                  │◀──────── session.event / session.status (流)  │
  │ WS 推送事件 ◀──────┤                      ├──── 模型调用 ─────────▶│
  │                  │                       │◀──── 事件(消息/工具/…)─┤
  │                  │◀────── session.status(idle) ───────────────── │
  │ 结果(最终文本/idle)│                       │                       │
  │                  │  (空闲超时/显式关闭)     │                       │
  │ DELETE /sessions ├── shutdown ──────────▶│                       │
  │◀─────────────────┤◀────── {} + exit 0    │                       │
  │                  │ 回收进程/账目/配额      │                       │

事件→结果的桥接规则(协议只给事件不给"该条 prompt 的结果"):


7. 关键接口与数据模型

7.1 服务端 API(Python)

端点 说明
POST /api/v1/sessions 建会话(内部:确保用户运行时在跑;返回 sessionId = u:<uid>:<uuid>)
POST /api/v1/sessions/{sid}/prompt 发提示词(校验归属 → session/prompt → 返回 messageId)
WS /api/v1/sessions/{sid}/events 事件流(session.event/status/subagent.* 规范化后推送)
GET /api/v1/sessions/{sid}/result 轮询最终结果(编排器维护的区间汇总)
DELETE /api/v1/sessions/{sid} 结束会话(可配:仅下线该会话 / 关闭该用户运行时)
GET/POST /api/v1/skills 技能目录/发布/授权(RBAC)
GET /api/v1/quota 用户配额视图

7.2 运行时编排器状态机(每用户)

absent → provisioning(拉起+initialize) → ready(可接会话)
                      │                       │
                      │ 崩溃                空闲超时 / 显式关闭 / 配额
                      ▼                       ▼
               restarting(退避)         shutting_down(shutdown→SIGTERM→SIGKILL)
                      │                       │
                      └───────── back to ready / removed

7.3 事件规范化(JSON-RPC 通知 → 内部消息)

// 内部统一事件
{ "event": "session.event" | "session.status" | "subagent.started" | "subagent.finished",
  "sessionId": "u:42:…", "messageId": "…",  // 有则带
  "payload": { …原协议载荷… },
  "ts": 1760850000000 }

7.4 技能 manifest(写入 SKILL.md frontmatter)

name: code-review-python        # kebab-case,必填
description: 对 Python 变更做评审并输出清单。  # 必填
whenToUse: 用户要求评审代码变更时
metadata:
  version: 1.4.0                # 服务端版本管理使用
  author: platform-team
  requires_roles: [engineer]    # 服务端 RBAC 过滤使用(不在 frontmatter 强制)
disable-model-invocation: false
user-invocable: true

8. 容量估算与部署建议(数百用户档)

项 估算 说明
用户数 ~300 活跃 每用户 1~2 并发会话
运行时进程 ≤ 300(一用户一进程) 仅活跃用户拉起;Node 常驻基线 ≈150–300MB/进程(以实测为准)
内存预算 300 × 250MB ≈ 75GB 叠加上限按 cgroup 收紧到每进程 ~512MB,超限 OOM 只伤该用户
CPU 8–16 核 agent 多为 I/O 与等待模型;峰值看并发 turn 数
磁盘 每用户会话 JSONL+workspace+技能;审计 建议挂 SSD;给配额(如单用户 10GB)
网络 模型 API 出口为唯一依赖 出网白名单(可选)
部署 systemd 服务 1 个 Python 进程组(uvicorn workers)+ 子进程树 cgroup v2 下按用户切片;OS 账号可每用户或共享运行账号+目录 ACL(推荐每用户 OS 账号以获得硬边界,成本自负)

起步规模(<50 用户)可直接复用同一架构,仅调低 cgroup/配额;进程模型不变。


9. 演进路线

阶段 内容 验收
P0(MVP) 单用户→首个用户运行时打通:spawn sdk profile、initialize、prompt、事件流、shutdown;元数据库落地 端到端一个会话闭环
P1(多用户隔离) 每用户 DSH_HOME/workspace/配额/沙箱;会话命名空间与路由;崩溃恢复、空闲回收;审计 双用户互不可见/互不影响;故障注入通过
P2(技能三来源) 技能服务中心(版本/审批/授权);共享技能目录物化+原子切换;私有技能区;RBAC 过滤 角色 A 看不到角色 B 的共享技能;共享技能热更新;回滚 <1s
P3(规模与进阶) 会话级运行时档位(高隔离)、注册中心直连插件(B2)、OTel 埋点、出网白名单、多机(shared storage + 编排层水平拆分) 压测 300 用户达标

10. 风险与开放问题

# 风险/开放问题 影响 缓解/答案
1 协议无逐会话关闭/取消 "结束单会话"只能关整进程 默认一用户一进程;需要时升级会话级进程档位
2 官方 Python SDK 发布形态未在本环境核实 可能需自实现 JSON-RPC 客户端 协议面已文档化且仅 3+4 个方法;自实现 ~300 行 python 可控。落地时先查官方仓库 python/ 目录的 wheel 发布
3 Node 进程内存占用 数百进程资源成本 cgroup 限额 + 空闲回收 + 监控阈值告警
4 共享技能热更生效粒度 正文变更对"进行中的轮次"可能不一致 目录/正文分离是官方设计(正文每次加载重读);进行中轮次的快照语义可接受
5 技能代码性内容(脚本) 沙箱之外仍需治理 v0.1 依赖文件沙箱 + 审批;容器级技能执行沙箱列入 P3
6 stdout 纯净性 任何 stdout logger 会破坏协议 profile 组装时禁用 stdout logger(官方明确要求),stderr 归日志文件
7 版本兼容 SDK 0.2.0-rc.2 为预发布,无版本协商 锁定 dsh 版本;升级走灰度;协议面增加回归测试

附:证据与参考

DeepSeek Harness SDK 集成 · 发布于 Cloudflare Pages · 由设计文档自动生成