DeepSeek Harness 开源后,我先看了它的运行时
原创 · 约 41 分钟阅读 · 阅读 --

DeepSeek Harness 开源后,我先看了它的运行时

作者: 字与码


DEEPSEEK · AGENT RUNTIME 源码核对:2026-08-13

DeepSeek 把 dsh(DeepSeek Harness)开源后,最容易得到的一句结论是:又多了一个 AI 编程助手。

这句不算错,但它把真正有意思的部分压扁了。看完仓库、架构文档和关键子系统后,我更愿意把它看成一个可组合的 Agent 运行时:命令行和 Web 界面只是外壳;模型、会话、工具、沙箱、审批、工作流,甚至 Agent 循环本身,都被安置在可以替换、叠加、卸载的插件树里。

这篇不做“几分钟上手”式介绍,而是沿着一次真实任务的生命线,把 Harness 拆开。结论先放在前面:它最值得注意的不是又包了一层模型,而是把状态、能力和副作用都当成一等公民来组织。这会让它更适合被二次开发,也要求使用者对运行时边界保持敬畏。

古董级程序员,经历过大厂和创业公司;持续关注 AI、工程与产品。公众号“字与码”会更新技术拆解、实践复盘和工具观察,欢迎关注。
阅读提示:本文依据 DeepSeek Harness 在 2026-08-13 公开的官方仓库与源码文档撰写。项目 README 明确标注为 Developer Preview,接口、配置和行为仍可能有破坏性变化;下文的架构判断不等于生产可用性背书。

先校正一个视角:你看到的是产品,源码里运行的是插件树

官方 README 给出的最快入口很直接:npx @deepseek-ai/dsh web,然后在本机浏览器打开 Web 端。这是一个很正常的产品入口。但从架构文档往下看,dsh 并不是把“聊天界面 + 工具循环”写死在一处的应用。

Harness 构建在 Cordis 上。Cordis 提供共享上下文、服务注册、事件和可逆副作用;Harness 则把模型适配器、工具注册、Session 日志、Agent Loop、审批策略、沙箱和前端装进一组插件。所谓 everything is a plugin,在这里不是宣传词:插件加载时注册服务和事件监听,卸载时这些注册会一起撤销。

模块化 Agent Runtime 的抽象图解:中心运行时连接模型、会话、工具、沙箱、界面和工作流

图 1:Harness 的关键不是一个固定的 Agent,而是一棵能拼装模型、工具、持久化、安全策略和界面的运行时树。

层次Harness 中的含义工程上的好处
Profile命名的运行时组合,描述要加载的 bundle、外部插件与补丁同一套核心可切成 Web、CLI、headless 等产品形态
Bundle一组可复用插件的发行单元能力按领域打包,不把业务耦进单体启动文件
Patch按基础 bundle、Profile、用户目录、命令行覆盖顺序叠加配置环境差异成为显式配置,而不是散落的条件分支
Seam接口、实现提供者、使用者之间的可替换缝隙替换文件系统或远程沙箱时,Bash、PTY、LSP 等能力随之迁移

所以,判断一个功能是不是“核心”,不要看它是不是在仓库顶层,而要看它是怎样被插件树组合出来的。官方文档提到的 dsh-base 覆盖模型适配、工具、持久化、沙箱/审批、设置、凭据和遥测;dsh-web-app 在此之上增加 Web 应用,dsh-headless 则更接近单次执行的无服务形态。dsh --profile web --dump-config 也被特意提供出来,用于把最终运行配置摊开检查。

一次任务如何跑完:Agent Loop 只是中间的一段

很多 Agent 框架的解释到“模型调用工具、工具返回结果、再调用模型”就结束了。Harness 把这段循环展开成了可观察的生命周期:先声明 turn,认领输入,构造系统提示词和工具 schema,发起流式模型请求,记录 assistant 增量,执行工具,再决定本 turn 是否继续。

turn/start
  └─ 认领用户输入或队列消息
      └─ 生成 prompt、工具 schema
          └─ agent/pre-step → agent/request → LLM 流式输出
              └─ assistant 内容与 tool call 写入会话
                  └─ tools/pre-execute → execute → post-execute
                      └─ 工具结果写入会话
                          └─ step/end → 判断是否继续下一步
turn/end

这里有三个层次的事件:Session Event 记录可恢复的会话事实;Agent Event 描述本轮的步骤和状态;Capability Event 属于工具、审批、沙箱等局部能力。这个拆分很克制:不是所有调试信息都必须进入长期会话,但凡模型可见、会影响后续推理的输入,必须留在 Session Event 中。

这也是它和“内存里攒一段 messages 数组”的实现差异最大的地方。Harness 的会话日志是追加式的 source of truth,模型历史由事件派生,而不是另存一份随时可能漂移的聊天记录。回放、分叉、恢复和审计因此有共同依据。代价也很清楚:新增一条“模型能看到的数据”不只是 append 一行文本,而要设计事件类型、序列化、持久化和重放语义。

上下文压缩:替换模型看到的表面,不抹掉原始事实

长任务迟早碰到上下文预算。常见做法是把老消息原地改成摘要,短期很省事,之后却很难回答:“这个结论从哪里来?”Harness 的 compaction 文档选择了更严谨的做法:压缩是一个可选子系统,会记录开始、摘要、结束等事件;摘要成为模型历史中的替换表面,而原始事件仍然保留。

事件溯源会话与上下文压缩图解:原始事件保留在归档层,模型可见历史被压缩摘要替换

图 2:压缩改变的是模型的可见窗口;原始事件仍是可恢复、可追溯的底账。

源码文档还写了两个很容易被忽略的边界:压缩时要锁住相应窗口,避免竞态;工具调用与工具结果必须成对保留,不能只裁掉一半对话。这些约束看似琐碎,却决定了压缩之后的 Agent 会不会突然“记得调用过工具,却忘记结果”。

持久化也没有和交互事件绑死。运行时可以异步批量写入,但会在 turn 边界执行 flush;如果一个长任务在中途崩掉,恢复逻辑会用合成的 turn/end interrupted 收尾,而不是假装那段历史从未发生。对要做长任务、断线恢复或多端查看的 Agent,这比界面上那条流式动画重要得多。

工具执行不是一个函数调用:它是一条可拒绝、可审计的流水线

真正危险的不是模型能不能调工具,而是它在什么条件下调、谁能拦住、拦住后历史长什么样。Harness 将每次工具调用先记入事件日志,再依次经过审批、可单调收紧的 guard、执行器、文件门控和后处理钩子;最终的工具结果被规范化后写回会话。

Agent 工具执行安全流水线图解:审批、策略守卫和隔离沙箱依次控制工具调用

图 3:工具调用先成为可见、可拒绝的事件,再进入策略与隔离边界;不是“执行完再补一条日志”。

一个重要的 fail-closed 细节:当工具要求审批而审批通道不可用时,Harness 的语义是拒绝,而不是默认放行。never 也不是“无人询问便自动允许”,而是确定性拒绝。对自动化系统来说,这种命名和行为的一致性非常重要。

Guard 的“只能收紧、不能放宽”也值得单独提一下。多个插件可以围绕同一个工具调用叠加限制,但后注册的插件不能把前面的拒绝改成允许。这样一来,安全策略才不会因为插件加载顺序变成一场猜谜。

沙箱层提供 read-onlyworkspace-writedanger-full-access 等模式,并按操作系统尝试使用 Linux 的 bwrap/Landlock、macOS Seatbelt、Windows 受限令牌等机制。但官方文档同样说得很明确:沙箱主要约束文件副作用,网络和进程可见性并不天然由这层解决;运行环境只达到 partial enforcement 时,不能当作完整隔离。这个边界应该被写进任何生产接入的威胁模型里。

子 Agent 与工作流:并发不是多开几个聊天框

Harness 也支持子 Agent、外部编码 Agent 适配和工作流。这里值得关注的不是“会不会多 Agent”,而是它给并发加了运行时约束:工作流脚本运行在 worker 环境中,父级保留子任务的归属、工作目录、层级深度和总数量控制;取消时要求有界地等待清理和收敛,致命错误要回传到父级。

这套设计承认了一个事实:Agent 的并发不只是多发几次模型请求。它还包含工具占用、会话归属、取消语义、成本上限和错误传播。只要其中一项没有制度化,所谓“自主协作”很容易演变成不可收拾的后台任务群。

它适合谁,以及现在不该期待什么

如果你的诉求是Harness 值得看的原因仍应谨慎的地方
把 Agent 嵌进现有工程Profile、插件和 seam 给二次组合留下了清晰位置预览期 API、配置格式与生态兼容性尚未稳定
做可审计的长任务事件溯源、turn 边界 flush、压缩和恢复语义较完整仍需自行验证存储、迁移、观测与失败恢复
让模型直接操作工作区审批、guard、文件 gate 与沙箱是明确的控制点沙箱不覆盖一切,网络、凭据与外部系统要另设边界
马上替换稳定生产工具可以做隔离试验与源码学习官方已声明 Developer Preview,不宜跳过自己的压测和安全评估

如果只是想先观察,最小动作是启动本地 Web 端、看一次最终 Profile 配置、跑一个无敏感数据的小任务。不要一上来就给它生产凭据、全盘写权限和无人值守的长工作流。Harness 已经把很多边界显式化了,但显式化不等于替你做完风险决策。

# 官方 README 给出的本地 Web 入口
npx @deepseek-ai/dsh web

# 安装/构建 CLI 后,展开当前 Profile 的最终组合结果
dsh --profile web --dump-config

最后的判断:DeepSeek 这次开源的是“可改的宿主”

从用户体验看,DeepSeek Harness 当然可以被拿来写代码、跑工具、调度子 Agent;从工程结构看,它更想解决的是另一件事:当模型、工具、界面和安全要求不断变化时,Agent 到底应该靠什么保持可演进。

它给出的答案是插件树、事件日志和受控副作用。模型换了,工具换了,沙箱换了,甚至承载方式从 Web 换成 headless,都不应该把会话真相和执行边界一起打碎。这个选择未必让上手路径最短,但让“做一个能长大、能排查、能回放的 Agent”有了比较严肃的地基。

项目刚公开,真正值得继续追的不是星标数字,而是三件事:插件与 Profile 的兼容性会怎样稳定;外部模型和工具生态会怎样接入;安全边界能否在不同操作系统与远程执行环境中保持一致。等这些问题有了真实用户和真实故障的答案,Harness 的位置才会更清楚。


一手资料

打开原图 ↗