DeepSeek Harness
一、架构图
1.1 分层总览
+==========================================================================+
| DeepSeek Harness (dsh) |
| "everything is a plugin" -- 没有可打补丁的特权内核 |
+==========================================================================+
+----------------------------------------------------------------------+
| 接入层 INTERFACE |
| [14] 模型接入 [15] 人机协作 [16] 技能系统 |
| [17] 自指扩展 [18] 对外接口 SDK / ACP / MCP / Web / CLI / headless |
+----------------------------------------------------------------------+
|
+----------------------------------------------------------------------+
| 编排层 ORCHESTRATION |
| [10] 子代理 [11] 上下文管理 |
| [12] 目标/计划/待办/工作流 [13] 后台作业与定时 |
+----------------------------------------------------------------------+
|
+----------------------------------------------------------------------+
| 执行层 EXECUTION |
| [5] Agent 循环 [6] 工具执行管线 [7] 内置工具集 24 个包 |
| [8] fs / shell / PTY / code-runtime [9] 沙箱隔离 四后端 |
+----------------------------------------------------------------------+
|
+----------------------------------------------------------------------+
| 地基层 FOUNDATION |
| [1] 插件化内核 Cordis [2] Profile / Bundle / Patch 三层 |
| [3] 能力接缝 Capability Seam [4] 事件溯源会话日志 |
+----------------------------------------------------------------------+
<details>
<summary>展开:每个模块一句话</summary>
DeepSeek Harness (dsh)
"everything is a plugin" —— 没有可打补丁的特权内核
│
├── 地基层 FOUNDATION
│ ├── [1] 插件化内核 Cordis — 模型适配器 / 工具表 / 会话日志 / agent 循环全是插件
│ ├── [2] Profile / Bundle / Patch — 启动时叠出的插件树,--dump-config 可打印,任意行可 patch
│ ├── [3] 能力接缝 Capability Seam — Definition / Provider / Consumer 三角色,缺一不算 seam
│ └── [4] 事件溯源会话日志 — "模型可见 = 必须落日志",运行时 invariant 强制
│
├── 执行层 EXECUTION
│ ├── [5] Agent 循环 turn / step — pre-step 可改写或拒绝送进模型的消息
│ ├── [6] 工具执行管线 — pre-execute -> execute -> post-execute 三段 waterfall
│ ├── [7] 内置工具集 — 24 个工具插件包
│ ├── [8] fs / shell / PTY / 代码 — 四套独立 seam ,fs 带"读后才能写"门禁
│ └── [9] 沙箱隔离 — bwrap / Landlock / Seatbelt / Windows ACL ,deny-only
│
├── 编排层 ORCHESTRATION
│ ├── [10] 子代理 Subagent — 进程内 / 跨进程 / 外部 Codex 与 Claude Code
│ ├── [11] 上下文管理 — compaction 压缩 + spill 溢写 + context 注入
│ ├── [12] 目标 / 计划 / 待办 / 工作流 — goal / plan / todo_write / workflow + ralph
│ └── [13] 后台作业与定时 — ctx.jobs + job_* 工具 + schedule_*
│
└── 接入层 INTERFACE
├── [14] 模型接入 — 双适配器:deepseek 原生 + pi-ai 目录厂商
├── [15] 人机协作 — 审批席位 / 权限预设 / commands / ask_user_question
├── [16] 技能系统 Skill — provider 注册表 + 本地 provider + 目录加载工具
├── [17] 自指扩展 — cordis_* 工具:模型在运行时挂载卸载插件
└── [18] 对外接口与交付 — TS/Python SDK · ACP · MCP(仅客户端) · Web/CLI/headless
</details>
1.2 能力接缝:三角色
+---------------------------+
| Service Definition | 只声明接口
| ctx.fs / ctx.subprocess | 不含任何实现
+-------------+-------------+
|
+--------------------+--------------------+
| | |
+--------v--------+ +--------v--------+ +--------v--------+
| Service Provider| | Service Provider| | Service Provider|
| fs-local | | fs-e2b | | fs-sandbox |
+--------+--------+ +--------+--------+ +--------+--------+
| | |
+--------------------+--------------------+
|
+-------------v-------------+
| Consumer | 模型面工具
| tool-bash / tool-terminal| 只认 Definition
| tool-lsp / tool-fs | 不认 Provider
+---------------------------+
文档原话:一个角色单独存在不算 seam ,加能力必须三个一起设计。
1.3 接缝的回报:接远程沙箱只动两行
本地执行世界 远程执行世界 (E2B)
--------------------------- ---------------------------
ctx.fs -> fs-local ctx.fs -> fs-e2b <== 只换这个
ctx.subprocess -> subprocess-local ctx.subprocess -> subprocess-e2b <== 和这个
| |
+-- tool-bash 不变 +-- tool-bash 一行没改
+-- tool-terminal 不变 +-- tool-terminal 一行没改
+-- tool-lsp 不变 +-- tool-lsp 一行没改
+-- tool-fs 不变 +-- tool-fs 一行没改
没有 provider 分叉,没有 if (remote) else (local)。
1.4 一个 turn 的生命周期
turn/start
|
+-- 认领下一步输入 + 一条排队消息
+-- 组装 prompt sections + tool schemas
|
+--> agent/pre-step ............ 可 reject ,也可改写 messages
| +-- 被 reject 或首次改写成空 --> 不产生 step ,直接收 turn
|
+--> step/start
| +-- 把认领的消息追加为 user/message
| +-- 从日志派生模型历史 deriveMessages()
| +--> agent/request --> llm/stream --> assistant/chunk* --> assistant/message
| +--> tool/call*
| +-> tools/pre-execute 权限 / 审批 / 沙箱包裹
| +-> tools/execute 真正跑
| +-> tools/post-execute 结果落盘 / 溢写
| +-> tool/result*
| +-- step/end
| +-- 还欠一次请求,或来了新输入 --> 认领 --> 下一个 step
|
+--> agent/turn-stopping
turn/end
durable (写进日志): turn/* step/* user/message assistant/* tool/*
waterfall (须调 next() 才往下传): agent/pre-step agent/request llm/stream tools/*
1.5 启动时的插件树
空的 entry list
|
[1] bundle dsh-base 模型适配器 / 工具 / 持久化 / 沙箱 / 审批 / 设置 / 凭据 / 遥测
[2] bundle dsh-web-app 浏览器应用( headless profile 换成 dsh-headless )
[3] profile 的 cordis.patch.yml
[4] home 级 patch
[5] --patch 覆盖层 argv 顺序
|
v
实际启动的插件树 <-- dsh --profile web --dump-config 打印出来
打印出的任意一行,都能被你自己的 patch 换掉
1.6 三种交付形态,同一个插件核
+---------------------------+
| 同一棵 Cordis 插件树 |
+-------------+-------------+
|
+-------------------------+-------------------------+
| | |
+-----v-----+ +-----v-----+ +-----v-----+
| Web UI | | CLI | | headless |
| 127.0.0.1 | | dsh | | 一次性运行 |
| :3080 | | | | 无服务端 |
+-----------+ +-----------+ +-----------+
dsh-web-app app-boot/cmdline dsh-headless
换的是 bundle ,不是代码。
二、18 个大模块
按四层分。有的模块我翻得比较细,有的只看了 README 和 index.ts ,后面会标出来。
地基层
1. 插件化内核 Cordis
模型适配器、工具注册表、会话日志、agent 主循环,全都是插件。
packages/core 文档里有句说得更直白:你扩展 dsh 的方式是在其他插件旁边再挂一个,注册进去的东西是可逆的 effect ,插件卸载时自动回收。
入门看 cordis-primer.md。
2. Profile / Bundle / Patch
启动时叠出来的插件树。顺序是 bundle 按 profile 列的次序叠,然后 profile 自己的 cordis.patch.yml,然后 home 级那份,最后 --patch 按 argv 顺序。
想知道自己机器上到底跑了什么,直接打印:
dsh --profile web --dump-config
打出来的任意一行都能被你的 patch 按 id 换掉整段 config ,或者插新行进去。比大多数 agent 框架那种"改配置文件"实在不少。
代码在 packages/bundle 和 packages/boot。
3. 能力接缝
每个能力拆三个角色:Service Definition 声明接口,Service Provider 给实现,Consumer 用它,通常是模型面的工具。文档写得很硬:一个角色单独存在不算 seam ,加能力就得三个一起设计。
这条约束的回报看上面 1.3 那张图。接 E2B 远程沙箱只换了 ctx.fs 和 ctx.subprocess 两个 provider ,bash 、PTY 、LSP 全部原样搬过去,没有 provider 分叉,也没有 if (remote)。
见过太多项目本地一套远程一套,最后两边行为对不上,这里算给了个解法。
4. 事件溯源会话日志
append-only 的 SessionEvent,模型历史用 deriveMessages() 从日志投影出来。
有条运行时 invariant 断言兜着:模型可见就必须落日志。想加一种模型能看到的新输入,得先扩 SessionEventMap 加事件,没有后门可走。
fork 、resume 、转写、遥测、UI 回放全是从这一条流派生的。代价是事件类型会长得比较快。代码在 packages/session,检索那部分在 packages/session-query,带 SQLite 全文搜索。
执行层
5. Agent 循环
一个 step 是一次模型请求加它调的工具,一个 turn 是零或多个 step ,turn 在第一次认领输入前开,欠的事做完才关。
要插手不用改循环源码,挂事件就行:
agent/pre-step能改写要送进模型的消息,也能直接 rejectagent/request、llm/stream、三个tools/*是 waterfall ,监听器不调next()就截断了agent/turn-stopping是 serial ,没有next()
被 reject 或者首次改写成空的情况,仍然会往日志里记一个没花 step 的 turn 。这个细节挺讲究,等于把"试过但没跑"也留了痕。
完整时序在 agent-lifecycle.md。
6. 工具执行管线
tool/call 进来,过 tools/pre-execute、tools/execute、tools/post-execute,出 tool/result。
权限、审批、沙箱包裹、结果落盘和溢写全挂这条线上,位置固定,不散在各个工具里。另外 packages/guard 里有个 deadline enforcer 和重复调用提醒,算 loop hygiene 。
7. 内置工具
24 个工具插件包。常规的 read / write / edit / glob / grep / bash / pwsh 之外,值得单独提几个:
terminal_open/_read/_write/_close/_list,一整套持久 PTYrun_code,走 worker threadworkflow和ralphsession_event_read/_search/_trace,模型能自己查历史job_list/job_output/job_kill
工具目录是生成的,还有完备性守卫,不会出现文档里写了代码里没有的情况。清单见 tool-catalog.md。
8. 文件系统 / Shell / PTY / 代码执行
四套独立 seam 。有个细节我觉得挺聪明:fs-observation-policy 做了读后才能写的门禁,没读过的文件不让改。
shell 那边 bash 和 pwsh 各有 local 和 sandbox 两个实现,另外单独有个 shell-env 管 DSH_* 环境变量注册表。
9. 沙箱
四个后端:bwrap 、Landlock 、Seatbelt 、Windows 受限令牌 ACL 。deny-only 策略,消费者在 spawn 前包裹 argv ,对工具本身透明。
Windows 那条是认真做了的,不是占位。不过我没在 Windows 上实际跑过,只看了代码。
编排层
10. 子代理
同一个接口后面挂着差别极大的实现:进程内 spawn 和 fork 、跨进程走 ACP 或 DSH-SDK 、以及外部的 Codex 和 Claude Code 。
最后这条是我翻源码时最意外的地方,你可以把 Claude Code 当成 dsh 的子代理来调。配套还有 subagent-control (interrupt_agent / list_agents / send_message)和 report 。
11. 上下文管理
三个包各管一段:compaction 压缩,spill 把超限的工具结果溢写到外部存储,context 负责往请求里注工作区指令和时间上下文。
溢写有策略层,不是拿到就硬截断。
12. 目标 / 计划 / 待办 / 工作流
goal 管同会话目标的持久化和生命周期,plan 是协作式计划、进出都有明确入口(进有命令,出要评审),todo_write 就是个待办工具,workflow 提供引擎加 workflow / ralph 两个工具。
四个包是分开的,没糊成一个大而全的任务系统,这点我挺认同。
13. 后台作业与定时
ctx.jobs 是通用后台作业运行时,模型自己起活、自己用 job_* 收。schedule 管会话内的定时跟进。
不用外挂调度器这点对本地跑的工具挺重要。
接入层
14. 模型接入
两个适配器,分工清楚。
dsh-llm-deepseek 自己拿 fetch 加 eventsource-parser 解 SSE ,独占 deepseek-official 这条路由,模型 id 直通不做白名单,换模型不用重新注册。dsh-llm-pi-ai 走 pi-ai 覆盖目录厂商,OpenAI 、Anthropic 、Bedrock 、Vertex 、Azure 这些。
要手工声明网关的话,可用协议只有三个:openai-completions、openai-responses、anthropic-messages。想接别的自定义协议,目前得自己写适配器。
另外 token-meter 是 replay 感知的,重放的时候不会重复计。
15. 人机协作
审批和交互都是 seam ,加上权限预设、命令注册(ctx.commands,不走模型轮次直接派发)、ask_user_question 工具。
审批做成一次性席位而不是全局开关,同一时刻只有一个审批位,避免多个请求互相打架。
16. 技能系统
provider 注册表加本地文件系统 provider ,再加模型面的目录和加载工具。skill 是个能力家族,后端可换,不是硬编码扫目录。
这块我只看了 README 和 index.ts ,没深读。
17. 自指扩展
cordis_define、cordis_inspect_list / _query / _get 这一族工具,让模型在运行时检视整棵插件树,并且挂载、卸载插件。
也就是 agent 改自己的运行时。配合前面说的可逆 effect ,插件卸载时它注册过的东西自动回收。这是 everything-is-a-plugin 推到极致的产物,我个人觉得是整个项目最有意思的一块。
风险也明显:模型自己动运行时,出了问题不好查。代码在 packages/extensions。
18. 对外接口和交付形态
TS SDK 和 Python SDK 共用一套 stdio JSON-RPC 线协议。ACP 有个服务端,但标注是仅自动化用。hooks 那边桥了 Claude Code 和 Codex 的 hook 线协议。
MCP 这里要留意:只有客户端桥,工具名格式 mcp__<server>__<tool>,Resources 和 Prompts 都没接。想拿 dsh 当 MCP server 用的先别抱期望。
交付形态三种,Web UI 默认 127.0.0.1:3080、CLI 、headless 一次性运行不起服务。
三、开源项目列表
全部来自 awesome-dsh-plugins 自动索引,收录 288 个仓库。
列表 A · 九大分类总览
Agent 能力 ############################# 58
Web UI 增强 ###################### 44
基建部署 ###################### 44
编码开发 ################## 36
文件数据 ################# 34
消息通讯 ######### 18
娱乐生活 ######### 18
学习研究 ######## 16
其他 #### 7
|----|----|----|----|----|----|
0 10 20 30 40 50 60
列表 B · 41 个的项目
IM 渠道接入
dsh-feishu-bot · dsh-wecom-bot · dsh-weixin-bot · qqbot
开发与协作工具
dsh-gh-bridge · dsh-issue-filer · dsh-prompt-studio · review-panel · dsh-diff-viewer · dsh-opencode-server
协议与适配
dsh-acp · dsh-pi-adapter · dsh-harness-ops
记忆与持久化
dsh-memory-evolve · Recall · session-persistence-rdb · dsh-track
列表 C · 按「你想干什么」精选
想要个桌面 App ,不想开终端
- deepseek-harness-desktop — DSH 桌面应用
- dsh-desktop-electron — Electron 桌面端
- deepseek-harness-distro — 自定义发行版
想在手机 / 浏览器里用
- dsh-android — 在安卓设备上跑 dsh
- dsh-browser — Chrome 侧边栏扩展,零视觉能力依赖操作浏览器
- dsh-browser-panel — Web UI 内嵌完整有头浏览器视图
想接进团队 IM
- dsh-feishu-bot — 飞书远程渠道
- dsh-feishu-notify — 会话结束 / 需要输入时飞书通知
- dsh-wecom-bot — 企业微信
- dsh-weixin-bot — 微信
- qqbot — QQ
- telegram — Telegram
- tg-bot — Telegram 另一实现
想学怎么写 Cordis 插件
- dsh-cordis-examples — 最小可运行的原生扩展示例
- dsh-cordis-rocks — 16 章可逆 Cordis 配套教程
- plugin-template — 插件模板
- dsh-edu — 教育版,7 个教学 bundle
- dsh-101 — DSH 文档阅读模式
想让 agent 更聪明 / 更省钱
- dsh-agent-budget — agent 树 token 预算
- distill — 后台子代理自动把对话蒸馏成技能
- dsh-memory-evolve — 记忆演化
- context-doctor — 审计 AGENTS.md 指令链 / 技能目录 / 工具 schema 的上下文占用
- dsh-advisor — 配一个被动 review 的第二模型
- deep-standard-skill — 把工程规范从没人读的文档变成会拒绝违规的程序
想做深度研究 / 自动化
- dsh-deep-research — 自适应深研编排
- dsh_workflow — 动态工作流
- dsh-a2a — Agent2Agent mesh
- browser4-dsh — AI 原生浏览器引擎
- dsh-cyber-sec — 授权渗透测试 profile bundle ,容器化 bash
跨 harness 迁移
- cross-harness-cite — 跨 harness 引用 Codex / Claude Code 历史对话
- dsh-cc-tui — Claude Code 风格全屏终端前端
- dsh-sidechain — /side 持续侧会话( Codex 风格)与 /btw 一次性侧问( Claude 风格)
生态漏斗
自动收录 288 个仓库
################################################################ 288
+-- 兼容 ########## 41
+-- 关注 ####### 31
+-- 需适配 ## 9
+-- 证据不足 ########################################## 188 <-- 占 65%
+-- 其他 ##### 19
运行级实测(同一版快照)
测试样本 5
可用 0 |
失败 5 |#####
收录 != 兼容 静态检查 != 运行可用 运行可用 != 安全审计