DEEPSEEK HARNESS · 深度技术分析

DeepSeek Harness 深度分析报告

一个完全插件化的开源 Agent Harness —— 基于自带的 Cordis 框架,把"模型、工具、会话、循环、UI、沙箱"全部下沉为可热替换的插件。本文从基本盘、实现方案、模块架构、能力接缝、组合模型、自修改能力、对比测试等八个角度展开。

版本 0.1.0-rc.5 代码 ~238 个 workspace 包 核心 Cordis vendored 语言 TypeScript · Python · C++ License MIT 状态 Developer Preview

01项目基本盘分析

DeepSeek Harness(命令行入口 dsh)是 DeepSeek AI 于 2026 年开源的 agent harness(智能体运行环境),定位与 Claude Code、Codex CLI 类似 —— 一个由 LLM 驱动、可执行工具、面向终端或 Web 的对话式编程助手。但它在底层架构上做出了根本不同的选择。

REPOSITORY
github.com/deepseek-ai/deepseek-harness

MIT 许可,完全开源,可作为 npm 包 @deepseek-ai/dsh-* 直接发布使用。

SCALE
238 个 workspace 包

覆盖 50+ 个能力组,核心 ~50 包,演示与测试 ~30 包,vendored Cordis 等 ~10 包,apps/website 等若干。

STATE
0.1.0-rc.5 · Developer Preview

官方明确表示将会有 breaking changes;采用 pre-release stance: 宁选正确基础,不选兼容垫片。

与同类项目的根本差异

维度Claude Code / CodexDeepSeek Harness
架构哲学整体式 (monolithic) 主体 + 工具扩展Everything is a plugin(包括循环本身)
替换模型需 fork 或外部 adapter挂一个 ctx.llm provider 即可
替换沙箱替换有限/不开放三个 ctx.sandbox 后端:bwrap / Landlock / Seatbelt
替换 UI仅 TUI / VS CodeWeb / TUI / CLI / ACP / JSON-RPC 五种 host
会话回放私有格式公开 SessionEvent 协议 + JSONL/SQLite 后端
智能体自修改extensions/ 让模型读写自己的 Cordis 运行时

用一句话概括区别:Claude Code 给你一个产品;DeepSeek Harness 给你一个平台

02核心理念与设计哲学

Model-visible ⟺ Logged — 任何到达模型请求的内容,必须可从会话日志完整重构。这是 dsh 的运行时不变式。

整个仓库的 AGENTS.mdarchitecture.mdglossary.md 围绕几条不可妥协的原则组织:

2.1 五条核心原则

原则 01
Everything is a plugin

包括模型适配器、工具注册表、会话日志、智能体循环本身。没有 privileged core。

原则 02
Registrations are effects

每个贡献都通过 ctx.effect() / ctx.on();卸载时 disposer 自动回收,reload 可预测。

原则 03
Model-visible ⟺ Logged

新增模型可见输入 = 新增 session 事件 + 渲染逻辑。日志是真相之源,UI、回放、分叉全部派生。

原则 04
Capability seams, never half-seams

能力 = Service Definition + Service Provider + Consumer 三角色,缺一个就不是 seam。

原则 05
Pre-release stance: 基础 > 兼容

无外部消费者时,自由重命名/重打包;旧 on-disk 格式直接拒绝;SQLite 用单调 SCHEMA_VERSION。

原则 06 (隐含)
Plugins, not loop changes

新行为走文档化扩展点。改 agent-loop 必须同步更新 docs/architecture.md

2.2 工程语言层面的硬约束

  • ESM 唯一 —— "type": "module";Node 原生 TS 模式不可用(因 engines 跨 22.19/24)。
  • 严格类型 —— strict: true + noImplicitAny;剩余 any 必须解释为何无法收窄。
  • 同进程信任 —— TS 已验证的内部接口不做运行期校验,只在 parser/config、queued、模型/工具 JSON、持久化、worker、process、wire 边界做。
  • 品牌类型 —— 跨边界 id 全部 Branded<B>,绝不裸 string
  • 对称优先 —— 平行值用对称命名,不对称的形状通常是漏掉抽象。

03基础框架:Cordis 五大概念

dsh 整个运行时建立在 自带的 Cordis(vendor/cordis/)之上,Cordis 源自 Koishi/cosmonium 生态,被 dsh vendoring 进来并 rescope 为 @deepseek-ai/cordis。还附带 cosmokitincludeloaderlogger-consoleschemasterytimer 等子模块。

3.1 Cordis In Five Ideas

Plugin is a Service

函数(apply(ctx) + 可选 inject) Service 子类;生命周期由 Cordis 挂载到当前 context。

Context = Service Repository

服务认领 ctx.<key>(如 ctx.toolsctx.llmctx.sessions),其他插件按 key 查找而非 import。

Inject 声明依赖

命名所需服务,Cordis 等它们就绪后才挂载;加载顺序表达为服务依赖而非手动 boot。

Typed Events

通过 TS declaration merging 声明事件名,按 emit/waterfall/parallel/serial 派发。

Registrations are Effects

贡献通过 ctx.effect() / ctx.on(),reload/teardown 自动 unwind。

3.2 四种派发模式

模式await顺序有返回值典型用途
emit注册顺序观察型 listener、telemetry、policy 旁路
waterfall注册顺序中间件风格,必须 next() 委托
parallel并发独立观察者 fan-out
serial注册顺序有序副作用,需累计结果

3.3 Waterfall 中间件语义

// 监听器签名: (...args, next) => result
ctx.waterfall('agent/pre-step', async (messages, turn, next) => {
  // 1) 改写请求
  const filtered = messages.filter(m => !m.internal)
  // 2) 委托给下一个 listener
  return next(filtered, turn)
  // 不调 next() = 短路,后续 listener 看不到
})

04整体架构:三层关注点分离

dsh 把"扩展点"按域划分,新增功能第一件事就是选域:

域 1
Session Events(持久事实)

append-only 日志,session/event 广播。事实必须能跨 reload 存活。新增模型可见输入 = 新增 session 事件。

turn/* · step/* · user/message · assistant/* · tool/*

域 2
Agent Events(活的协调)

携带 live Agent,可观察或拦截在飞工作。Waterfall 中间件用得最多。

agent/pre-step · agent/request · agent/turn-stopping · agent/status

域 3
Capability Events(策略注入)

附策略与适配器到 seam,不导入循环也不依赖 loop。

fs/* · tools/* · telemetry/*

4.1 单轮生命周期(Turn Flow)

一个 step = 一次模型请求 + 它引发的工具调用。一个 turn = 零或多个 step。Turn 在第一个 input 被 claim 时打开,在"什么都没欠"时关闭。

turn/start ├─ claim next-step input + one queued message ├─ 装配 prompt sections + tool schemas └─► agent/pre-step (waterfall,可改写/拒绝) ├─ reject → turn 关,无 step └─ enter(messages) ├─ step/start ├─ append entered messages as user/message ├─ derive model history from log ├─► agent/request (waterfall) │ └─► llm/stream (waterfall) │ └─► assistant/chunk* (emit) │ └─► assistant/message (anchor) ├─► tool/call* → tools/pre-execute → tools/execute │ → tools/post-execute → tool/result* ├─ step/end └─ 循环直到 turn 收尾 └─► agent/turn-stopping (serial,无 next) turn/end

4.2 关键概念:Scope 与 Agent Context

每个 Agent 有自己的 agent.ctx(作用域上下文)。注册通过它贡献 = 作用域可见 AND 作用域生命周期。工具/提示段/变量在 agent 维度有"全局"和"作用域"两层。最具体者获胜(shadowing)。

DIAGRAM · 4-A 三层关注点分离 + AgentLoop 中心驱动 animated
LAYER 1 · PLUGINS Everything is a plugin shell · fs · llm · tools · session · skill · sandbox · subagent · ... THE ONLY CONCRETE LOOP AgentLoop · packages/core/agent-loop ctx.agents.withInitiator(agent, ...) DOMAIN · SESSION Session Events durable facts · append-only turn/* · step/* · tool/* DOMAIN · AGENT Agent Events live coordination · waterfalls agent/pre-step · agent/request DOMAIN · CAPABILITY Capability Events policy + adapter injection fs/* · tools/* · telemetry/* SOURCE OF TRUTH SessionEvent Log · append-only Model-visible ⟺ Logged · fork · replay · telemetry · persistence

05核心包与循环驱动

整个 dsh 只有一个包包含具体循环逻辑:packages/core/agent-loop/。其他全是抽象服务或扩展点插件。

5.1 包族谱

职责ctx 键
core/sessionappend-only SessionEvent 日志 + 内存存储ctx.sessions
core/system-prompt提示段 + 工具 schema 装配ctx.systemPrompt
core/tools作用域工具注册表 + 守卫执行管线ctx.tools
core/agentAgent 接口、live 注册表、agent/* 事件ctx.agents
core/agent-loop默认 driver,实现 Agent 接口ctx.agentLoop
core/scopeper-agent scoped-registration 原语库,无 key
llm/llm消息/流词汇 + adapter seamctx.llm

5.2 AgentLoop 是唯一的具体循环

// ctx.agentLoop.create() —— 同步无 setup 的创建
const agent = ctx.agentLoop.create(id, { cwd }, meta)
// driver 跑在 ctx.agents.withInitiator(agent, ...) 里
// Agent 拥有自己的会话;构造/恢复是一回滚事务
// —— 私有 session + concrete agent + scoped ctx,await setup,
// 同时 enter 两个 registry,宣布 session/created → agent/created
// → agent/session-start,然后才启动 driver

5.3 统一 send 原语

Loop 提供统一的 send() 原语,通过 (target × wakeup) 路由内容与唤醒:

  • followup() → append next-turn FIFO + 唤醒 driver
  • steer() → append next-step inbox + 唤醒 driver
  • inject() → append next-step inbox + 唤醒

5.4 Inbox 操作发布规范事件

每个 inbox 变化都先发归一化事件再改投影:

  • agent/inbox/spliced —— 标准 splice 坐标
  • agent/inbox/inserted · agent/inbox/discarded · agent/inbox/claimed
  • MessageId 在两个 pending 列表间唯一;同步持久事件观察者能从 pre-splice 投影重构移除值

5.5 取消与唤醒闭锁(Wake Latch)

abort 之后但 activity 收敛到 idle 之前到达的唤醒输入会被 latch(wakeRequested),在 driver 的收敛边界 replay,无需再 send。

关键状态:idle → running → idle 过渡对,即便 message 已被 clear 也保留;disposed 取消永不 latch;持久 turn/enduser/parent 记录 aborted,对 disposal 记录 disposed

5.6 内置请求重建不变量

每个 agent-loop/invariant companion 把请求注册到 ctx.invariants。loop 在 dsh-llm 拥有的进程内 identity 集合里记录每个精确的 frozen request,然后独立从日志重建消息边界 + folded request header。

06能力接缝(Capability Seams)

每个能力是一个 seam,由三角色组成:

SD
Service Definition

Cordis Service 子类,拥有 ctx.<key> 和词汇类型。抽象类(ShellExecutor)或具体注册表(WebRuntime),绝 不是 TS interface

SP
Service Provider(s)

实现定义的具体后端。例:dsh-bash-local / dsh-bash-sandbox

C
Consumer(s)

注入服务并使用,通常是面向模型的工具。例:dsh-tool-bash

6.1 重要接缝一览

能力族SDSP 示例Consumer
Shelldsh-shelldsh-bash-local, dsh-bash-sandbox, dsh-pwsh-localdsh-tool-bash
Subprocess通用local process-tree被 shell/sandbox 消费
Sandbox通用 seambwrap / Landlock / Seatbelt / Windows-ACLbash / fs 包装 argv
FS通用 seamdsh-fs-local, 远程file tools + bash 资源
Terminal通用 seamlocal PTYdsh-tool-terminal
LSP通用 seamgeneric stdiolsp 工具
Web通用 seamsearch / fetch providersmodel-facing web tools
Subagentctx.subagentsspawn-in-process / remotedsh-tool-subagent
Workflow通用 seamworker-threadworkflow / ralph
Compaction通用 seambasic providercommand consumer
LLMdsh-llmDeepSeek / OpenAI / Claude / Codexagent-loop
Seam 的力量 —— 换一次 provider 就能切换整产品。FS+Subprocess 共用同一执行世界,指向远程沙箱即迁移 Bash/PTY/LSP,无需 fork。

6.2 单一接缝的角色分离原则

glossary.md:

  • 角色通常按独立演化的需要分到不同包;一个包可以承担多个角色,如果是一回事(dsh-llm 同时拥有 SD 和 Consumer)。
  • seam 完整能力,绝不是单一角色;术语 seam 保留为这层意思。
  • 反 smell:一个 Service 公开方法只有一个内部 caller —— 用私有 capability closure 替代。
DIAGRAM · 6-A Capability Seam 三角色:SD → SP → Consumer animated swap
SERVICE DEFINITION · SD abstract class ShellExecutor ctx.shell · @deepseek-ai/dsh-shell SERVICE PROVIDER · SP ① dsh-bash-local unconfined · local process subprocess → ctx.subprocess SERVICE PROVIDER · SP ② dsh-bash-sandbox bwrap / Landlock / Seatbelt ctx.sandbox wraps ⟲ hot-swap · single config key CONSUMER · C dsh-tool-bash injects ctx.shell · registers on ctx.tools → 模型可见的 bash 工具 schema ⤵ 换 provider = 改 profile 无需 fork · 无需改 loop 无需改 consumer

07会话日志即真相(Model-visible ⟺ Logged)

这是整个 dsh 最深的不变式 —— 它解释了为什么 dsh 与 Claude Code 在工程上完全分道扬镳。

7.1 为什么日志是"唯一真相"

派生能力
一份数据,多种产品

fork、resume、transcript、telemetry、persistence 全部从同一 SessionEvent 流派生。换前端、换数据库、换分析管道,不必重写产品。

回放保真
原始 chunk 留存

assistant/chunk 原始流事件保留,replay 时 token 流式输出与原 UI 完全一致 —— 不只是文字,也包括流式 UI。

重投影
不同视角可派生

同一会话可同时投影成:模型视角(deriveMessages())、UI 视角、telemetry 视角,数据源是同一条 stream。

新输入门槛
新增可见 = 新增事件

任何模型可见新输入:扩展 SessionEventMap,从日志渲染。门槛很高,杜绝"内存里随便塞"的快路径。

7.2 SessionEvent 类型与版本化

// dsh-session 保持 SESSION_FORMAT_VERSION = 0,无兼容承诺
interface SessionEventMap {
  'session/created': { sessionId: SessionId, ... }
  'turn/start':      { turnId: TurnId, ... }
  'step/start':      { stepId: StepId, turnId: TurnId, ... }
  'user/message':    { messageId, role, content }
  'assistant/chunk': { seq, delta, ... }
  'assistant/message': { messageId, content, sourceEventSeqs, usage }
  'tool/call':       { callId, name, args }
  'tool/result':     { callId, content, error? }
  'turn/end':        { reason: 'completed' | 'aborted' | 'disposed' }
  ...
}

事件 member 默认 require-on-read:build 不知其类型时拒绝 log,除非事件携带信封的 ignorable: true;只有结构性格式变更才升 SESSION_FORMAT_VERSION

7.3 KV-Cache 友好的 Append-only

agent-loop/README.md 的 Model Experience 节:

  • 系统文本/工具 schema: 每步重发;若装配字节相同则 KV cache 复用。
  • 历史增长: append-only 直至 compaction shadow;普通增长不破坏复用。
  • 取消后重放: 每个未派发的 tool call 收到 ABORTED_BEFORE_DISPATCH 合成结果,append-only 跟随复用前缀。

08插件组合模型:Profile + Bundle + Patch

一个运行的 dsh 是一棵按有序层组合的插件树。

8.1 三个术语

PROFILE
命名组合

存于 Harness home($DSH_HOME/profiles)。列出要堆叠的 bundles + 用户 patch。模板:webheadless

BUNDLE
分发格式

Cordis 配置行 + 挂载代码的发布单元。无论它插入什么,都可被上层 patch。

PATCH LAYER
行覆盖

按 id 替换某行整块 config 或插入新行。深度合并不存在 —— "要么全替,要么原样"。

8.2 加载顺序(从空 entry list 开始)

  1. profile 列出的每个 bundle(按 dsh.profile.bundles 顺序)
  2. profile 的 cordis.patch.yml
  3. home 级别的 cordis.patch.yml
  4. 任何 --patch <path> overlay(可重复)

8.3 dsh-base 是所有 profile 的第一层

它通过 cordis.patch.yml 插入所有基础插件:模型适配器、共享 agent-default-model 选择、工具、持久化、策略、settings/credentials、telemetry、host-level subagent providers。Codex/Claude provider 装载但休眠

它通过平台 gate 实现 POSIX/Windows 单 shell stack:

# 同一 patch 文件,一个平台一份 shell stack
bash-sandbox:  disabled: !!js process.platform === 'win32'
tool-bash:     disabled: !!js process.platform === 'win32'
pwsh-sandbox:  disabled: !!js process.platform !== 'win32'
tool-pwsh:     disabled: !!js process.platform !== 'win32'

8.4 用户诊断命令

$ dsh --profile web --dump-config        # 看实际启动的树
$ dsh --profile web --dump-default-config # 不含用户层和 --patch overlay
$ dsh web --help                          # web app 自己的 flag
$ dsh plugin --profile tui add <pkg>      # 给 profile 装插件

8.5 Loader 配置的细节

@deepseek-ai/cordis-plugin-include 解析 !!js 为表达式节点。Loader 在该插件上下文(已声明 injection 激活后,作用于 ctx.serviceName)插值 entry 的 config;disabled 在每次装载决策时对 loader 上下文求值。其他 entry 元数据保留字面值。

DIAGRAM · 8-A 插件树的层叠装配(applied bottom-up · patches replace rows by id) stacked assembly
↑ applied later · overrides by id ↓ applied earlier · provides base LAYER · 5 — CLI --patch <path> overlay (repeatable) LAYER · 4 — HOME $DSH_HOME/cordis.patch.yml LAYER · 3 — PROFILE profiles/<name>/cordis.patch.yml LAYER · 2 — BUNDLE dsh-web-app · cordis.patch.yml (browser UI) LAYER · 1 — BASE dsh-base · first layer · model + tools + persistence + sandbox ↓ empty entry list starts here Loader: include → !!js evaluated per mount decision most user-controlled always shipped

09事件系统与三种派发模式

9.1 关键 domain 事件清单

Session Events(durable)

事件何时模式
session/created新会话被 enter()emit
turn/start, turn/end一轮边界emit
step/start, step/end单步边界emit
user/message用户输入落地emit
assistant/chunk, assistant/message流式 token / 完成锚emit
tool/call, tool/result工具调用与结果emit

Agent Events(live coordination)

事件模式用途
agent/pre-stepwaterfall改写/拒绝 claimed 输入;决定模型看什么
agent/requestwaterfall改写请求或路由;执行前最后一次拦截
llm/streamwaterfall拦截/替换流式结果
tools/pre-executewaterfall策略/审批/沙箱包装
tools/executewaterfall替换实际执行
tools/post-executewaterfall结果策略(回滚/截断)
agent/turn-stoppingserial停止一轮;无 next()
agent/status, agent/created, agent/disposedemit状态广播
Waterfall 监听器必须 next() 委托 —— 返回而不调 next() 会短路链路。

9.2 事件命名 / 文档约束

  • 事件 JSDoc 必须标 @mode 和 payload 的 @param
  • scoped key 在 payload 缺失时标 @dshScopeScan unsupported
  • 生成器(gen-cordis-catalog)从源头生成 fresh 列表;手编辑被门禁拒绝

10自我修改(Self-Modification)能力

这是 dsh 区别于 Claude Code 最戏剧化的能力 —— 模型可以读写自己运行的 Cordis 运行时packages/extensions/ 提供此功能,Agent Note 2026-07-08-self-referential-cordis-toolset 详述设计。

HOST HALF
tool-cordis

面向模型的运行时检视 + 动态包工具;在 ctx.tools 注册。

SANDBOXED EXEC
cordis-host-runner

定义注册表、node:vm 沙箱宿主半、request-run 往返。提供 ctx.dynamicCordisRunner

CLIENT HALF
cordis-client-runner

双半包浏览器半:把定义求值为活浏览器插件,响应 run 请求。提供浏览器 ctx.dynamicCordisRunner

UI
ui-cordis

浏览器面板:操作每个定义的 frame-wide 面板 + 只读 define 卡。

10.1 实际能力

  • Inspect: 列已装载插件、服务 API、活动事件
  • Define: 模型可写一个 cordis 配置,在 node:vm 沙箱中编译为插件
  • Mount/Unmount: 装载插件 + 卸载时自动 dispose 所有贡献
  • Retract: 撤回自己写过的定义,清理由其产生的副作用

10.2 安全护栏

虽然模型可以改自己的运行时,但仍受沙箱约束:

  • 动态代码在 node:vm 隔离上下文求值,无法直接访问 Node 全局
  • 所有插件依然要经过 Service Definition 的服务契约校验
  • 外部模型注入依然走 agent/pre-step 中间件,可被策略层拦截
  • 权限预设(permission-preset)约束工具调用

10.3 与 Claude Code 对比

Claude Code / Codex 都没有自我修改能力。dsh 把"agent 修改自己的运行时"作为头等公民 —— 与 preset/(per-session 预设)、guard/(循环卫生)、extensions/(自修改)三者并列,构成 dsh 的"agent 元能力栈"。

11多语言、多面、多 UI 矩阵

11.1 三种语言

TYPESCRIPT
主产品

ESM,strict: true,noImplicitAny。Node ≥ 22.19 或 ≥ 24。pnpm 11.7。

PYTHON
Python SDK + 运行时

python/ 子树捆绑 SDK 与运行时,提供 Python 生态的 dsh 集成。

C++
Linux Landlock 原生

native/landlock-run/ 是 Landlock 沙箱 Node addon 的源,Linux 平台进程级封装。

11.2 两面构建(host + client)

构建面目标关键包
hostNode 服务端进程dsh-agent-loop, dsh-llm, dsh-shell, dsh-fs-local, sandbox providers
client浏览器前端dsh-client-runtime, dsh-client-connection, dsh-client-ui-*, dsh-cordis-client-runner

构建矩阵确保编译 face 显式:每个包用一个聚合(tsconfig.base.jsontsconfig.base.client.json),只有 api/remotes 拆为两个 face(因为它有生成的对外合约)。

11.3 五种部署形态

PROFILE: web
Web 应用

浏览器 SPA + Node host,默认端口 3080。当前启动形态。

PROFILE: headless
一次性 runner

dsh --profile headless "task":一次性完成,无 server。

acp/
Agent Client Protocol 服务端

自动化场景的 ACP 协议服务端,与其他 agent 客户端互通。

sdk/
进程外 JSON-RPC

JSON-RPC 协议 + TS 客户端,任何语言都能嵌入 dsh。

hooks/
Claude Code/Codex hook 桥

共享线协议库,让 dsh 兼容现有的 hook 生态。

examples/
可运行示例

cordis.yml 叶子 + agent-spine + CLI/ACP/JSON-RPC bins。

12测试与质量门禁体系

dsh 把"质量"做成可执行门禁而非文档。仓库根 scripts/run-gates.ts 编排大量 verify-* 脚本,CI 拥有完整信号。

12.1 测试体系

命令作用备注
pnpm testvitest unit 测试本地快路径
pnpm test:coverage每个文件 100% 覆盖 gateCI 覆盖门禁
pnpm test:e2e真实 API 测试DEEPSEEK_API_KEY 自动跳过
pnpm test:snapshotkeyless ACP/headless 回放用于快照关键产出
pnpm test:snapshot:record录制 expected outputs需 key
pnpm test:web浏览器端到端需要先 build

12.2 静态生成 & Freshness 门禁

以下目录/文件由源生成,且由 --check 模式 freshness-gated:

  • docs/subsystems/cordis-surface 区域(每页)
  • docs/cordis-api/(Cordis 核心 API + 继承 tier)
  • docs/tool-catalog.md · docs/config-catalog.md · docs/persistence-catalog.md · docs/module-graph.md

12.3 Hygiene 全套

$ pnpm run hygiene
   ↳ rescope-vendor:check    # Cordis 是否仍 rescope 正确
   ↳ knip                    # 未用导出 / 死代码
   ↳ publint                 # package.json 导出契约正确
   ↳ constraints             # workspace 约束
   ↳ verify-dsh-package-licenses
   ↳ verify-package-invariants
   ↳ verify-built-package-invariants
   ↳ verify-cordis-config    # raw/plugins 必须在 resolver manifest 的 dependencies
   ↳ verify-node-next-types
   ↳ verify-runtime-closure
   ↳ verify-vendored-links

12.4 文档门禁

  • verify-doc-budgets —— 每个 doc 有字数上限,超限拒绝(根 AGENTS.md ≤1600,architecture.md ≤1800 等)
  • verify-md-wrap —— 一段一行,软换行
  • verify-md-links —— 链接存活 + 锚点正确
  • verify-export-jsdoc —— 每个 export 有 JSDoc 覆盖
  • verify-type-equiv —— doc 里贴的 TS 类型不能漂移
  • verify-package-readme-model-experience —— 强制 Model Experience 节存在
  • verify-package-readme-limitations —— 限制要么写,要么进 allowlist

12.5 测试理念(摘自 testing.md 链)

每个非平凡、面向模型或产品用户可见的行为变更,必须在同一 PR 内新增或更新一个 keyless 快照 —— 走真实可运行示例。包测试、e2e-only 断言、mock-only fixtures 都不能替代组装后应用 transcript。

13与 Claude Code / Codex 详细对比

为避免与公开产品做无证据比较,下表只对比公开架构属性

维度Claude CodeCodex CLIDeepSeek Harness
架构基座整体式主体 + MCP 工具扩展Rust 内核 + TS 包装Cordis 全插件化,循环本身也是插件
模型接入仅 Anthropic(原生)OpenAI(原生)多个 Provider:DeepSeek/OpenAI/Claude/Codex 装载但休眠
沙箱受限(macOS Seatbelt 等)AppArmor/seatbelt/landlockbwrap / Landlock / Seatbelt / Windows-ACL 四选
UI 形态TUI + IDE 插件CLI + TUIWeb / TUI / CLI / ACP / JSON-RPC 五种 host
会话回放私有会话存档(不可外部派生)会话存档(内部用)公开 SessionEvent 协议,JSONL/SQLite 后端
智能体自修改extensions/ 是头等公民
工具管线批准 + 执行(细节不公开)执行 + 批准公开瀑布:tools/pre-execute → execute → post-execute → result
会话分叉无原生支持无原生支持ctx.sessions.fork(source, boundary?, childSessionId?)
Per-session preset不支持不支持preset/ 从 cordis.yml 组合
Goal/Same-session 目标goal/ 带 active/paused/blocked/complete 阶段
Ralph 循环(全新子 agent)workflow/ralph 工具
类型/事件契约内部约定内部约定TS declaration merging + JSDoc + 生成 catalog
测试覆盖未公开未公开每个文件 100% coverage 门禁
文档 gate无公开无公开字数预算 + 类型贴片验证
开源协议不开源部分开源MIT,238 包全开源
Vendoring不适用不适用自带 Cordis 等基础库,可控升级

13.1 架构差异带来的影响

DSH 更适合
平台化、定制化

需要换模型、换沙箱、换 UI、换持久化后端的团队;做 agent 元能力(自修改、preset、goal)的项目。

Claude Code 更适合
开箱即用 + IDE 集成

想立即获得"够好"体验的个人开发者,深度集成在 Anthropic 生态中。

Codex 更适合
OpenAI 偏好 + Rust 性能

已经订阅 OpenAI、做性能敏感场景、希望 CLI 而非 UI 的开发者。

DSH 学习曲线
陡峭但透明

Cordis 概念 + capability seam 三角色 + session event 协议,需要一周入门。

14优势、局限与适用场景

14.1 工程优势

+
真正可组合的插件

不是"开放 API",而是"循环本身由插件装配" —— 改动空间大一个数量级。

+
数据是真相之源

SessionEvent 日志 + 派生投影让 fork / replay / UI / telemetry 解耦。

+
能力接缝设计

SD/SP/Consumer 三角色分离,单点替换全局生效,无 fork。

+
企业级门禁

100% 覆盖、文档预算、catalog freshness、Agent Note 强制,质量信号机器可读。

+
KV-Cache 友好

显式 Model Experience 节记录 token / KV 缓存影响,提示装配变更要谨慎。

+
多语言运行时

TS / Python / C++ native addon,Web 前端 + Node host + JSON-RPC。

14.2 局限与代价

!
陡峭学习曲线

Cordis 五概念、capability seam 三角色、SessionEvent 协议,需要一周入门,一个月才能写合格插件。

!
发布前迭代快

官方明确表示会有 breaking changes;生产环境使用需自承担稳定性风险。

!
概念密度高

Agent Note、Postmortem、Subsystem pages、Glossary 四层文档结构,初学者容易迷路。

!
构建重

238 个 workspace 包,初次 build 数分钟,测试链路长。CI 资源消耗高。

!
零 IDE 插件

不像 Claude Code 有原生 IDE 集成,要靠 hook 桥(hooks/)对接。

!
当前 UI 体验

Web UI 中文界面但功能还在补全,缺 polish,benchmark 工作未到位(BENCHMARK.md 存在但内容待写)。

14.3 适用场景

场景推荐度理由
构建"agent-as-platform"产品⭐⭐⭐⭐⭐插件化是核心价值
多模型 / 多沙箱后端的研究项目⭐⭐⭐⭐⭐seam 设计契合
需要 fork / replay / 时间旅行调试⭐⭐⭐⭐⭐SessionEvent 流是天然数据源
需要在 agent 内建元能力(自修改、goal、preset)⭐⭐⭐⭐⭐扩展点齐全
企业级可审计 + 可回放⭐⭐⭐⭐100% 覆盖 + log-everything
个人开发者开箱即用⭐⭐Claude Code 更顺手
VS Code / JetBrains IDE 深度集成⭐⭐需自己写 hook 桥
已有大量现有 agent 代码迁入pre-release stance 不友好

15结论与未来展望

DeepSeek Harness 不是另一个 Claude Code 克隆 —— 它是 agent harness 的"平台化宣言"。

15.1 一句话总结

把 agent harness 当作可组合平台来设计,而非可调用产品来提供 —— 这是 dsh 与现有竞品最根本的分野。它付出了陡峭学习曲线和文档密度的代价,但换来了"任何层都可被替换"的根本自由度。

15.2 设计哲学的五个"先于"

  • 正确性先于兼容性(pre-release stance)
  • 插件先于核心(everything is a plugin)
  • 数据先于产品(Model-visible ⟺ Logged)
  • 契约先于实现(capability seam 三角色)
  • 门禁先于流程(每个机制都有机器可执行信号)

15.3 关键里程碑(自观察到的 Agent Notes)

日期主题
2026-06-13Capability seams 架构 rationale
2026-06-14Session persistence seam
2026-06-18Markdown 跨链接 lint
2026-07-04Doc tiers & budgets
2026-07-08Self-referential Cordis toolset
2026-07-10Parallel tool call execution
2026-07-15Agent initiator scope
2026-07-16Explicit turn cancellation
2026-07-19Package invariant runtime contracts
2026-07-26Dependencies over hand-rolling
2026-07-29dsh source launch tsx/esm contract
2026-08-02Native GitHub stacks & optional rebases
2026-08-03Package-anchored subsystem pages
2026-08-07Cancel-convergence wake latch(bug-fix)
2026-08-08Unified GitHub label taxonomy
2026-08-09Concrete prose names actors & recorded facts
2026-08-10Session log version mechanism

15.4 未来值得关注的演进方向

  • 正式 1.0 发布(pre-release stance 移除,意味着兼容性承诺)
  • SCHEMA_VERSION / SESSION_FORMAT_VERSION 跃迁与兼容性策略
  • BENCHMARK.md 内容沉淀(目前是骨架)
  • Python SDK 与进程外 JSON-RPC 的扩展
  • E2B(已在 packages/e2b/)走向产品级
  • 更多 IDE 集成(目前只有 hook 桥)

15.5 给不同身份读者的"读这份仓库"建议

FOR USERS
用户:如何用它

README.mddocs/architecture.mddocs/user/;装好后改 $DSH_HOME/profiles 即可定制。

FOR PLUGIN AUTHORS
插件作者:写什么

docs/cordis-primer.mddocs/architecture.mddocs/glossary.md;遵循 capability seam 三角色;参考 packages/examples/

FOR CONTRIBUTORS
贡献者:怎么改

AGENTS.md + packages/CLAUDE.md;改任何 packages/ 必读 docs/architecture.md;提交时跑 dsh-pre-push-checks

FOR ARCHITECTS
架构师:为什么

.agents/notes/implemented/docs/postmortem/ —— Agent Notes 解释 why,postmortem 解释 what-was-given-up。

报告基于 v0.1.0-rc.5 源码 + Agent Notes + 文档快照;所有特性与数据来自仓库 /Users/wangzhikui/github/deepseek-harness,日期 2026-08-15
随着 dsh 持续迭代,文档层级与 seam 设计可能演进,请以最新版的 architecture.md + glossary.md 为权威。

16模块依赖图与门禁链(可视化)

最后用两张动态图把前面 15 章的工程结构再"看一眼":包拓扑与构建/测试门禁链。

DIAGRAM · 16-A 核心包拓扑 · AgentLoop 为枢纽,六向辐射 radial animated
shell · bash · pwsh subagent workflow · ralph web · skill compaction · todo fs · sandbox extension · self-mod plan · goal · preset session core/session tools core/tools llm llm/llm system-prompt core/system-prompt agent core/agent scope core/scope AgentLoop the only loop core/agent-loop → animated lines = dependency injection through Cordis ctx.<key> outer ring = capability seams; inner ring = core services; hub = the only concrete loop
DIAGRAM · 16-B 构建 → 测试 → 门禁 → 启动流水线 pipeline
① INSTALL pnpm install 923 packages ~ 1m15s ② BUILD pnpm run build tsc + tsdown host + client ③ HYGIENE pnpm run hygiene knip + publint + 8 more gates ④ TEST test:coverage 100% / file snapshot · e2e ⑤ SERVE pnpm dsh web :3080 web UI live 本报告实测(本机 macOS): install → 1m15s · build → 2m22s · dsh web → ~ 6s 启动 → :3080 监听 ⚠ 踩坑:corepack 拦截 + git 2.10 太老 → 改用真 pnpm 路径 + .npmrc 关掉 verify-deps ✅ 服务已在 :3080 提供 12 KB 主页 + 30+ 客户端插件 manifest