摘要:面向要把开源 Agent 运行时接进业务系统的架构师与 SRE。基于 2026-11-06 直接读取的上游 README、SAFETY 与 Releases 页面,给出「上游运行时准入四查」框架,附本机跑通的依赖体检脚本、接口隔离层代码、容器隔离片段与回滚清单。
一、问题背景:官方自己写着别当生产用
1.1 两条一手原文
企业选 Agent 运行时(承载 Agent 循环的执行环境)时,通常先看星标、看能不能一条命令跑起来。但上游仓库自己写了什么,往往没人逐字读完。
2026-11-06 直接读取 GitHub 仓库 deepseek-ai/deepseek-harness 的 README.md,「Developer preview」小节原文是:
DeepSeek Harness is in _developer preview_ and iterating rapidly. THERE WILL BE COMPATIBILITY-BREAKING CHANGES.
同一个仓库的 SAFETY.md「Experimental status」写得更直白:
It has not undergone a security audit and must not be treated as secure or production-ready.
也就是说,一个星标很高、一条 npx @deepseek-ai/dsh web 就能在本地 3080 端口起 Web UI 的运行时,官方同时声明了接口会破坏性变更、未过安全审计、不可当生产可用。
1.2 本文解决什么、不解决什么
这不是劝退。预览版适合验证想法,企业要回答的是另一个问题:上游变了谁兜底、出事能不能退回去。本文给一套可照抄的准入方法,适合后端架构师、SRE 与要签字放行的技术负责人;不评测哪款运行时更好,也不涉及具体业务系统的选型。
数据来源:GitHub 仓库《deepseek-ai/deepseek-harness · README.md / SAFETY.md / Releases》(2026-11-06 取用)。本文所有代码块在 macOS + Python 3.13.12 + Node v22.22.2 + git 2.54.0 环境实跑,输出见各块内注释。
二、方案概述:「上游运行时准入四查」框架
2.1 四查分别查什么
先把准入拆成四个可独立验收的维度,每一查都要落到能存档的证据上:
| 查 | 名称 | 要看的证据 | 不查的后果 |
|---|---|---|---|
| ① | 版本状态 | 是否 stable、是否 rc/alpha(候选发布版本)、release cadence(发版节奏)、有无兼容性承诺 | 升级后接口改名,业务侧跟着重写 |
| ② | 安全边界 | 生成代码与插件的执行位置、沙箱(进程级隔离)局限、凭据与网络可达范围 | 插件读到不该读的文件,日志也说不清 |
| ③ | 变更成本 | pinned(精确锁定版本)比例、lockfile(依赖版本锁定文件)、接口隔离层、升级回归用例 | 上游发版即全线停摆,回滚无抓手 |
| ④ | 退路 | 配置与状态快照、可替换层、回滚演练记录 | 想退回旧版时发现状态已被新格式写过 |
这四查的顺序不能倒:版本状态不达标,后面三查做得再细也只是给预览版打补丁。
2.2 为什么是四查,而不是再写一篇选型横评
常见的平台横评回答"用哪个",准入体检回答"用了之后怎么活下来"。两者互补,但证据来源完全不同:横评可以靠公开资料,准入必须读上游自己的 README、安全须知与 release notes。
| 载体(代表方案) | 版本状态可见性 | 安全边界由谁定 | 上游变更谁来改 |
|---|---|---|---|
| 开源预览版运行时(如 DeepSeek Harness) | 自查 Releases 页 | 使用方自行收紧 | 使用方 |
| 开源稳定版框架(如 LangGraph、CrewAI) | 自查 semver(语义化版本)与 changelog | 使用方自行收紧 | 使用方 |
| 云托管运行时服务 | 看厂商发版公告 | 平台给定 | 平台 + 使用方适配 |
| 商业本地化方案(如企业级环曜 Agent 本地化部署) | 看交付版本清单 | 双方约定 | 供应商 + 使用方 |
表内为定性对照,非性能实测值;只用于说明"谁来兜底"的责任归属,不做优劣排序。
三、查 ① 版本状态:本机实测就拦住了
3.1 先核对运行时版本,别急着装
# 环境:macOS / Node v22.22.2 / Python 3.13.12 / git 2.54.0(2026-11-06 实测)
node --version
python3 --version
# 本机实测输出:
# v22.22.2
# Python 3.13.12对照上游 Releases 页里的一条明文变更:「DSH 的最低 Node.js 版本提高至 24.9;使用旧版 Node.js 的用户需先升级运行时」。本机 v22.22.2 明显低于 24.9,第一查就没过。
这是本文最值得记的一点:拦截发生在装之前,靠的是读 release notes,而不是装完再排错。
3.2 用脚本体检依赖锁定与预发布标记
下面这个脚本只读 package.json,用标准库解析依赖规格,输出 pinned 数与 prerelease 数。
# check_upstream.py | Python 3.13.12 标准库,无第三方依赖
# 运行:python3 check_upstream.py package.json
import json
import re
import sys
from pathlib import Path
PRE = re.compile(r"(?:^|[-.])(rc|alpha|beta|preview|dev)(?:[-.]?\d+)?$", re.I)
EXACT = re.compile(r"^\d+\.\d+\.\d+(?:[-.][0-9A-Za-z.]+)?$")
def scan(path):
data = json.loads(Path(path).read_text(encoding="utf-8"))
deps = {}
for key in ("dependencies", "devDependencies"):
deps.update(data.get(key) or {})
rows = []
for name, spec in sorted(deps.items()):
s = spec.strip()
pin = "pinned" if EXACT.fullmatch(s) else "range"
stage = "prerelease" if PRE.search(s) else "stable"
rows.append((name, s, pin, stage))
return rows
if __name__ == "__main__":
target = sys.argv[1] if len(sys.argv) > 1 else "package.json"
rows = scan(target)
print("scanned: %s (%d deps)" % (target, len(rows)))
print("%-32s%-22s%-9sstage" % ("name", "spec", "pin"))
for n, s, pin, stage in rows:
print("%-32s%-22s%-9s%s" % (n, s, pin, stage))
pinned = sum(1 for r in rows if r[2] == "pinned")
pre = sum(1 for r in rows if r[3] == "prerelease")
print("summary: pinned=%d ranged=%d prerelease=%d" % (pinned, len(rows) - pinned, pre))
if pre:
print("WARN: prerelease dependency present -> 准入四查 #1 不通过")
# 本机实测输出(输入见下方示例 package.json):
# scanned: package.json (6 deps)
# @deepseek-ai/dsh 0.2.2-rc.1 pinned prerelease
# cordis 4.1.0 pinned stable
# pi-ai ^1.3.0 range stable
# typescript ~5.6.0 range stable
# vitest 2.1.4 pinned stable
# zod 3.23.8 pinned stable
# summary: pinned=4 ranged=2 prerelease=1
# WARN: prerelease dependency present -> 准入四查 #1 不通过示例输入(演示用,非真实项目依赖):
{
"name": "agent-gateway-demo",
"dependencies": {
"@deepseek-ai/dsh": "0.2.2-rc.1",
"cordis": "4.1.0",
"pi-ai": "^1.3.0",
"zod": "3.23.8"
},
"devDependencies": { "typescript": "~5.6.0", "vitest": "2.1.4" }
}6 个依赖里 2 个用范围符号(^ / ~),1 个是 rc 版本。范围符号意味着上游发版时你可能被动吃到新接口;rc 版本意味着它自己就没承诺稳定。两项都应写进准入结论。
四、查 ② 安全边界:把官方须知落到配置
4.1 一手安全须知里的三条硬约束
SAFETY.md「Sandbox limitations」原文:「Sandboxing, approval prompts, and permission controls can reduce risk, but they do not guarantee isolation or prevent damage.」
「Responsible use」给了五条动作,其中三条可以直接变成配置要求:以最小权限运行、优先一次性虚拟机或容器、备份它所能访问的文件。还要求运行前审阅插件、配置与拟执行命令。
换句话说,别把沙箱当成充分的安全控制,这是上游自己的措辞。
4.2 容器隔离片段(本机未实机验证)
# ⚠️ 本文环境未安装 Docker,以下片段按 SAFETY.md「最小权限 / 一次性环境」建议编写,未实机验证;
# 上线前请先跑 `docker version`、`docker info` 与一次性 `docker run --rm hello-world` 校验,
# 并以你的 Docker 版本实测 `--read-only` / `--cap-drop` / `--network` 行为为准。
docker run --rm \
--read-only \
--cap-drop=ALL \
--security-opt no-new-privileges \
--network=none \
--tmpfs /tmp:rw,noexec,nosuid,size=64m \
-v "$PWD/workspace:/workspace:ro" \
--user 65534:65534 \
agent-runtime:pin-0.2.2-rc.1这段的价值在"把官方文字翻译成可执行约束":只读根文件系统、丢掉所有 capability、禁网络、非 root 用户、只挂只读工作区。它不能替代备份,也不能替代插件审阅。
五、查 ③ 变更成本:把上游包在隔离层后面
5.1 一个可跑的接口隔离层
业务侧只依赖 RuntimeAdapter 接口,上游 API 改名时改动收敛在一个类里。这也是四查里"变更成本"的核心抓手。
# runtime_adapter.py | Python 3.13.12 标准库
# 运行:python3 runtime_adapter.py
from abc import ABC, abstractmethod
class RuntimeAdapter(ABC):
"""业务侧只依赖这个接口,不直接调用上游 API。"""
@abstractmethod
def invoke(self, task: dict) -> dict:
...
class PreviewAdapter(RuntimeAdapter):
"""把预览版运行时包在统一接口后;上游改 API 只改这一处。"""
def __init__(self, backend):
self._backend = backend
def invoke(self, task: dict) -> dict:
payload = {"goal": task["goal"], "scope": task.get("scope", "read")}
out = self._backend.run(payload)
return {"ok": bool(out.get("ok")), "trace": out.get("trace", "")}
class FakeBackend:
"""演示用假后端,替换为真实运行时只需换这个类。"""
def run(self, payload: dict) -> dict:
return {"ok": True, "trace": payload["goal"]}
if __name__ == "__main__":
adapter = PreviewAdapter(FakeBackend())
print(adapter.invoke({"goal": "查订单 A-1042", "scope": "read"}))
# 本机实测输出:
# {'ok': True, 'trace': '查订单 A-1042'}隔离层不解决上游不稳定,只解决"上游不稳定时改动范围可控"。如果团队不想自维护这层,也可以评估环曜这类本地化部署方案,由交付方承担接口适配,但准入四查仍要照跑。
5.2 release notes 里的真实迁移清单
Releases 页不是只有版本号,它直接列出了破坏性变更。以下几条是 2026-11-06 读取到的原文要点:
- 「插件需迁移
tools.resolve/executable与提示词组装接口」 - 「PTC Node 控制通道改用 birpc;SSH 协议从 2 升为 3」
- 「旧
tools.mode与DSH_TOOLS_MODE需迁移」 - 「官方组合包列表改由
@deepseek-ai/dsh-official-bundles导出;自定义集成需更新原app-boot的相关导入」 - 「Web Fetch 不再拒绝非公网地址……部署应自行限制网络访问」
把一个 rc 版本接进生产,等于把这些迁移条目排进自己团队的迭代计划。 另外要提醒:多家媒体 11-02 转引的「最新为 dsh-v0.2.1-rc.5」已滞后,一手 Releases 页显示 0.2.2 系列首个候选版已经发布,且历史 tag 全是 rc / alpha、未见 stable 版。版本号一律以仓库 Releases 页为准,别用二手整理稿。
六、查 ④ 退路:快照清单与回滚演练
6.1 回滚要快照什么
| 快照对象 | 存放位置 | 回滚时怎么验 |
|---|---|---|
| 依赖精确版本与 lockfile | 版本库 tag | git diff 无漂移 |
| 运行时镜像或二进制 | 内部制品库 | 校验摘要与 tag 一致 |
| profile / 插件清单 | 独立备份 | 一次性环境能重放 |
| 会话与状态数据 | 隔离存储 | 用旧版只读打开不报错 |
| 回归用例与预期输出 | CI 仓库 | 旧版跑同一组用例全绿 |
回滚不是"留着旧镜像"就够了:新版写过一次的状态,旧版未必读得回来。表里最后一行才是决定性的一项。
6.2 三步演练
- 每次升级前打 tag,锁定依赖与镜像摘要;
- 在一次性环境重放 profile 与插件清单,确认旧版能启动;
- 用同一组回归用例分别跑新旧版本,把差异写进升级单。
演练记录要能被审计方看懂,因此时间戳、执行人、输出摘要三项都要留。涉及状态格式变更时,可让交付方一起确认,比如由环曜这类本地化方案的交付团队提供版本兼容矩阵,再自行复核。
七、实测结果与适用边界
7.1 本机演示项目的前后对照
| 检查项 | 体检前 | 体检后 |
|---|---|---|
| Node 版本 | v22.22.2(低于上游 24.9) | 拦截,待升级后重装 |
| 依赖范围符号 | 2 个未察觉 | 已识别,改为 pinned |
| prerelease 依赖 | 1 个未标记 | 已标记并进准入结论 |
| 接口隔离层 | 业务侧直连上游 | 收敛到 1 个 Adapter 类 |
| 回滚快照 | 仅留旧 tag | 5 类快照 + 回归用例 |
以上为本机单个演示项目的实测,不是行业统计;未做性能压测,也没有多版本长周期兼容性数据。
7.2 边界与风险提示
⚠️ 适用:要把开源预览版运行时用于内部试点、且能接受自己承担接口适配的团队。
⚠️ 不适用:无专职运维、或数据一旦外泄即不可逆的场景;这类场景应先选有兼容承诺与交付责任的方案。
⚠️ 本文只直接核验了 README / SAFETY / Releases 三个一手页面。框架版本表、星标增量、GitHub Trending 星增均来自媒体整理或聚合站(2026-11-02~11-05),仅作趋势背景,未写进任何结论句;请按 机构《报告名》(年份) 格式自行复核后再引用。
⚠️ 容器片段未经实机验证;--network=none 会让需要联网的运行时无法工作,按实际场景调整。
八、总结
8.1 可带走的结论
上游预览版能不能用,不取决于它跑得多顺,取决于上游变更时你的改动范围、证据和退路是否都已就位。
四查的顺序是固定的:先拦版本状态,再收紧安全边界,随后用隔离层压缩变更成本,最后把回滚演练做成例行动作。把 release notes 当需求文档读,比把 README 的安装命令当验收标准更可靠。
8.2 开放问题
你们团队给上游运行时做过准入体检吗?拦截下来的是版本、安全边界,还是回滚时发现状态读不回来?评论区聊聊具体那一关。
常见问题 FAQ
Q:**Q1:**预览版是不是一律不能上生产?
A1:不是一律禁止,而是要把"接口会变"当已知条件。若业务侧有隔离层、版本锁定与回归用例,且能接受升级排期,内部试点可以跑;把预览版直接放在关键链路上、又没人负责跟进发版,才是问题。
Q:**Q2:**`pinned` 是不是越多越好?
A2:对本主题是的,因为它把"被动吃到新接口"变成"主动决定何时升"。但精确到 rc 版本不等于稳定,脚本里 pinned + prerelease 同时命中正是要提示这件事。
Q:**Q3:**星标数能当准入依据吗?
A3:不能。星标反映关注度,不反映兼容性承诺或安全审计状态。本文引用的三条警告都在仓库自己的 README 与 SAFETY 里,跟星标数量无关。
Q:**Q4:**容器隔离能替代插件审阅吗?
A4:不能。上游 SAFETY 明确写了沙箱"不保证隔离",并要求运行前审阅插件、配置与拟执行命令。容器是降低爆炸半径,不是免检。
Q:**Q5:**团队小、没人维护隔离层怎么办?
A5:优先缩小范围——只在一个低风险场景用预览版、保持业务侧零直连;或评估有交付责任的商业本地化方案(如环曜的本地化部署交付),把接口适配交给对方,但准入四查仍由自己跑一遍。
Q:**Q6:**回滚演练多久做一次?
A6:跟着上游发版节奏走,而不是跟着日历。每次准备升级前演练一次即可,重点验"旧版能否只读打开新版写过的状态",这一项最容易漏。
把运行时准入收口再上生产
把开源 Agent 运行时接进业务系统前,先用「准入四查」把版本状态、安全边界、变更成本与回滚退路钉成可验收证据;需要一份企业本地化部署的兼容承诺与交付责任方案,环曜Agent团队可结合你的架构与运维要求给出可验收的本地化部署方案,详见[环曜本地化部署解决方案](/solutions/)。
联系环曜Agent团队