Skip to content

DeepSeek Harness 引擎 ​

引擎镜像:veyra/veyra-os/engine-deepseek:0.2.1-rc.2-veyra.1(tag 唯一真相为 engines/deepseek-harness/VERSION)。

DeepSeek Harness 引擎把 dsh CLI(npm 包 @deepseek-ai/dsh,Cordis 插件架构) 包装为 OpenAI 兼容的 HTTP/SSE 服务:容器内 server.py 接收请求,spawn dsh --profile veyraos-sdk 子进程(SDK profile 暴露 newline-delimited JSON-RPC stdio 通道),把 dsh 的 session.event 流式事件翻译成 OpenAI SSE 流给 gateway。 模型统一经平台 LiteLLM 代理(Messages API endpoint + per-instance key)。

容器构建 ​

  • 基础镜像: python:3.11-slim(终段)
  • 构建段: node:22-bookworm-slim — 安装 @deepseek-ai/dsh(锁版本 0.2.1-rc.2)
    • 沙箱插件 @veyraos/opensandbox-shell
  • 依赖锁定: engines/deepseek-harness/runtime/package-lock.json,构建使用 npm ci --install-links
  • 运行时: FastAPI + uvicorn + pyyaml,内置 server.py / entrypoint.sh / profile 模板 / engines/_shared/profile_isolation.py
  • 入口: entrypoint.sh — 校验 dsh CLI、检测沙箱开关、启动 API server(端口 8649)

API 面 ​

端点说明
GET /health健康检查
POST /v1/chat/completionsOpenAI 兼容响应:默认/显式 stream:true 为 SSE 流(delta + 工具进度帧 + usage);显式 stream:false 聚合为 chat.completion JSON
POST/GET /v1/sessions创建 / 列举 session
GET /v1/sessions/{sid}/messages读 session 历史
DELETE/PATCH /v1/sessions/{sid}删 / 改名 session
POST /v1/sessions/{sid}/stop停止该 session 正在运行的推理(幂等)
GET /v1/models当前注入的模型列表
GET /v1/files列举 profile 默认工作区目录
GET /v1/files/content读取工作区文件内容(≤1MB 文本)

SSE 输出契约:delta 帧(content / reasoning_content)、p 工具进度帧 (running→success/error)、末帧 usage、[DONE]、30s keepalive。 正文与思考内容分别输出;多步骤回复逐段展示,不重复输出已收到的内容。

连续对话与升级 ​

每轮请求启动独立 dsh 进程;已有会话通过原生 session/resume 恢复后再发送本轮消息。 历史上下文包括用户和助手消息、工具调用与结果,以及原生压缩状态。最终结束信号在 子进程完成日志持久化并退出后发送,保证下一轮可读取完整上下文。

从旧版升级后,已有会话首次续接会从平台保存的文本历史恢复用户与助手消息,平台 会话 ID 保持不变。旧原生日志保留;其中未保存的工具过程无法由文本历史还原。 后续轮次直接续接新原生日志,历史不会重复导入。读取失败时返回错误,避免空上下文继续对话。

0.2.1-rc.2 为官方候选发布版,新引擎镜像版本为 0.2.1-rc.2-veyra.1。 此打包修订修复升级后的流式正文缺失,并保持多轮上下文恢复能力。 该版本使用平台 LiteLLM 的 /v1/messages 接口;部署前需确认该接口支持模型路由。

多用户隔离 ​

使用 engines/_shared/profile_isolation.py 提供 per-profile UID 隔离:

per-profile UID(20000-29999)  ← useradd -r -M -u {uid} -d {profile_dir} deepseek-{name[:25]}
+ chown -R {uid}:{uid} profile 目录
+ chmod 0700 profile 目录
+ spawn dsh 时 preexec_fn 降权
+ cwd = HOME = /opt/data/profiles/{name}
+ DSH_HOME = {profile_dir}/.dsh  ← dsh session 日志/settings 按 profile 隔离

技能与 MCP / 知识库 ​

引擎支持平台的三类资产,消费方式与 Hermes 系不同(引擎侧自持渲染逻辑):

  • 技能:平台按定义维护共享目录(/opt/data/skills/{定义标识})为「启用集」 磁盘视图——启用的技能在位、停用的移除。引擎插件(skill 三件套)把该目录作为 自定义技能目录加载(不加载内置根目录),技能增删/停用下一轮请求即生效 (wrapper 每请求重渲染插件配置)。spawn dsh 时附带技能目录组权限,保证降权 后的进程仍可读。
  • MCP / 知识库:平台下发一张引擎中立的数据契约(UA_MCP_SERVERS_JSON: 绑定条目 + 地址 + 绑定上下文头),wrapper 每请求解析它并渲染成 MCP 客户端 插件条目。Authorization 由引擎从自身 Pod env 的模型 Key 取(凭据不进契约); X-Profile-Name 取本次请求的真实 profile。知识库经平台内置检索 MCP 门面 下发,绑定任一知识库即挂载、全解绑即摘除。
  • 生效语义:绑定/解绑经平台自动下发并滚动重启(约 30–60 秒);技能类变更走 磁盘视图,无需重启。

沙箱(可选) ​

  • 开启条件:Pod env 同时存在 OPENSANDBOX_SERVER_URL 与 OPENSANDBOX_API_KEY
  • 开启后 dsh 的 shell 工具执行经插件 @veyraos/opensandbox-shell 转发到 OpenSandbox server(建 ephemeral 沙箱 → 执行命令 → 命令结束删除沙箱)
  • 未开启则 dsh 使用本地 provider(降权 uid 执行),沙箱插件不加载

环境变量 ​

变量用途来源
API_SERVER_KEY引擎 API KeyK8s secret
API_SERVER_PORT监听端口(默认 8649)固定
OPENAI_BASE_URL平台 LiteLLM 代理地址平台注入
OPENAI_API_KEYper-instance 模型 Key平台注入
DSH_MODEL默认模型名(deepseek-v4-flash)平台注入
UA_MCP_SERVERS_JSONMCP / 知识库绑定契约(渲染插件条目用)平台注入
UA_DEFINITION_ID定义标识(定位共享技能目录)平台注入
OPENSANDBOX_SERVER_URL沙箱服务地址平台注入(可选)
OPENSANDBOX_API_KEY沙箱服务 Key平台注入(可选)
OPENSANDBOX_IMAGE沙箱镜像(默认 ubuntu:22.04)平台注入(可选)

请求头 X-Ua-Profile 指定 profile(sk- API Key 无登录态调用时 gateway 自动按实例 派生 {agent_short}-default 默认 profile);X-Ua-Model-Config 可每请求注入 base_url / api_key / default_model,优先于 Pod env。

人设注入:请求体 messages 里的 system 消息经 DSH_SYSTEM_PROMPT env 进入 dsh 原生 system prompt(sdk-minimal bundle 的 system-prompt 插件通过 personaPrefix 读取该 env)。

基于内网部署的企业级 AI 智能体平台