DeepSeek Harness 开源后,我先看了它的运行时
DeepSeek 把 dsh(DeepSeek Harness)开源后,最容易得到的一句结论是:又多了一个 AI 编程助手。
这句不算错,但它把真正有意思的部分压扁了。看完仓库、架构文档和关键子系统后,我更愿意把它看成一个可组合的 Agent 运行时:命令行和 Web 界面只是外壳;模型、会话、工具、沙箱、审批、工作流,甚至 Agent 循环本身,都被安置在可以替换、叠加、卸载的插件树里。
这篇不做“几分钟上手”式介绍,而是沿着一次真实任务的生命线,把 Harness 拆开。结论先放在前面:它最值得注意的不是又包了一层模型,而是把状态、能力和副作用都当成一等公民来组织。这会让它更适合被二次开发,也要求使用者对运行时边界保持敬畏。
先校正一个视角:你看到的是产品,源码里运行的是插件树
官方 README 给出的最快入口很直接:npx @deepseek-ai/dsh web,然后在本机浏览器打开 Web 端。这是一个很正常的产品入口。但从架构文档往下看,dsh 并不是把“聊天界面 + 工具循环”写死在一处的应用。
Harness 构建在 Cordis 上。Cordis 提供共享上下文、服务注册、事件和可逆副作用;Harness 则把模型适配器、工具注册、Session 日志、Agent Loop、审批策略、沙箱和前端装进一组插件。所谓 everything is a plugin,在这里不是宣传词:插件加载时注册服务和事件监听,卸载时这些注册会一起撤销。
图 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、执行器、文件门控和后处理钩子;最终的工具结果被规范化后写回会话。
图 3:工具调用先成为可见、可拒绝的事件,再进入策略与隔离边界;不是“执行完再补一条日志”。
never 也不是“无人询问便自动允许”,而是确定性拒绝。对自动化系统来说,这种命名和行为的一致性非常重要。
Guard 的“只能收紧、不能放宽”也值得单独提一下。多个插件可以围绕同一个工具调用叠加限制,但后注册的插件不能把前面的拒绝改成允许。这样一来,安全策略才不会因为插件加载顺序变成一场猜谜。
沙箱层提供 read-only、workspace-write、danger-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 的位置才会更清楚。
一手资料
微信公众号
欢迎关注「字与码」
如果这篇文章对你有用,也欢迎在微信里继续关注后续更新。
X / Twitter
关注 @ax2_zicode
更即时的技术观察、新文章提醒和一些短想法会发在 X 上。