[DeepSeek]DeepSeek Harness 系统架构与核心概念

材料收集完毕。基于官方架构文档(DeepSeek Harness Architecture)和你机器上的实际安装(v0.1.1-rc.2),下面是完整梳理。


DeepSeek Harness 系统架构与核心概念

一、设计哲学:万物皆插件(Everything-is-a-Plugin)

DSH 最核心的一句话:产品的每一部分都是插件——模型适配器、工具注册表、会话日志、沙箱策略、甚至 agent loop(智能体循环)本身,全部可以通过配置替换。

因此它没有需要打补丁的特权内核:扩展 DSH 的方式就是把插件挂载到其他插件旁边,所有注册都是"可逆副作用",插件卸载时自动撤销。

底层框架是 Cordis(以 vendor 方式引入的插件框架),五个核心概念:

概念 含义
插件 实现服务的对象,有 inject(声明依赖)+ apply(ctx)(挂载逻辑)
上下文 服务的容器,ctx.<key> 如 ctx.tools、ctx.llm、ctx.sessions;按 key 查找而非 import 实现
依赖注入 通过 inject 声明依赖,加载顺序由依赖关系决定,非手动编排
类型化事件 4 种分发模式:emit(观察)、waterfall(环绕包装)、parallel(并行扇出)、serial(按序执行)
可逆副作用 所有注册通过 ctx.effect()/ctx.on() 安装,reload/teardown 时按序撤销

二、分层装配:Profile + Bundle

运行中的 dsh 是一棵插件树,由启动时按序叠加的各层组合而成:

空条目列表
  └─ Profile 列出的组合包(bundle)按顺序应用
       └─ Profile 自己的 cordis.patch.yml
            └─ Home 级 $DSH_HOME/cordis.patch.yml
                 └─ 命令行 --patch overlay
  • Profile(配置档):存放在 Harness home(~/.dsh/profiles/)的具名组装。web、headless 是随发行版交付的模板。每个 profile 有 dsh.profile 清单 + 自己的 cordis.patch.yml(用户覆盖层)。
  • Bundle(组合包):Cordis 配置项+挂载代码的分发格式,在 package.json 里通过 dsh.bundle 字段声明。

三层基础 bundle:

  • dsh-base:每个 profile 的第一层——模型适配器、工具、持久化、沙箱与审批策略、设置、凭据、遥测
  • dsh-web-app:在其上增加浏览器应用
  • dsh-headless:一次性运行器,完全不带服务器

查看你机器实际的配置树:dsh --profile web --dump-config —— 打印出的任何条目都可以被你的 patch 替换。

三、六大核心子系统(packages/core)

一个轮次按同一条循环流经六个包:

包 职责 ctx 键
session 仅追加的事件溯源日志 + 内存 store——唯一真源 ctx.sessions
system-prompt 提示词段落 + 工具 schema 的组装 ctx.systemPrompt
tools 作用域化工具注册表 + 受保护的执行流水线 ctx.tools
agent Agent 接口、活跃 agent 注册表、agent/* 事件 ctx.agents
agent-loop 实现该接口的默认驱动器 ctx.agentLoop
scope 按 agent 划分作用域的注册原语(纯库,无 ctx 键) —

设计要点:扩展插件依赖 agent(需要发起 Agent 时),绝不直接依赖 agent-loop,因此循环保持可替换。

四、轮次流程(Turn Flow):Step 与 Turn

  • Step(步骤) = 一次模型请求 + 它调用的工具
  • Turn(轮次) = 零个或多个步骤,领取首条输入时打开,不再欠任何工作时关闭
turn/start
  认领 next-step 输入 + 一条排队消息
  组装提示词段落 + 工具 schema
  → agent/pre-step                ← 决定模型看到什么(可改写/拒绝)
     step/start
     追加 entered 消息为 user/message
     从日志派生模型历史
     agent/request → llm/stream → assistant/chunk* → assistant/message
     tool/call* → tools/pre-execute → tools/execute → tools/post-execute → tool/result*
     step/end
     工具欠另一次请求 或 有新输入到达 → 认领 → 下一步骤
  → agent/turn-stopping
turn/end

其中 agent/pre-step、agent/request、llm/stream 和三个 tools/* 事件是 waterfall(必须调用 next() 委托下去);agent/turn-stopping 是 serial。

五、会话日志:事件溯源(Event Sourcing)

核心不变量:「模型可见即已记录」——抵达模型请求的一切都必须能从日志重建。

  • 会话日志是一份仅追加的 SessionEvent 日志,12 种核心事件变体:turn/start、turn/end、step/start、step/end、user/message、assistant/chunk、assistant/message、tool/call、tool/result、steering/message、todo/write、request/header
  • 模型历史从日志派生(deriveMessages()),不单独存储
  • 原始 assistant/chunk 保证 token 级回放保真
  • fork、恢复、transcript、遥测、持久化全部派生自该事件流
  • 扩展方式:通过 TS declaration merging 扩展 SessionEventMap(如 compaction 插件添加了 compaction/* 事件)

六、工具执行流水线

ctx.tools.execute() 的调用链:

tools/pre-execute(可重排的 allow/deny/ask waterfall)
  → 已注册的单调 ToolGuard(只能缩减权限,不能撤销)
  → tools/execute(环绕分派包装层,可替换 signal)
  → tools/post-execute(检查/替换结果)
  → finalizeContent(定义拥有的回调)
  → tools/result(不可变的权威结果)

关键语义:

  • 参数经过一次无损 JSON 物化后被深度冻结
  • ToolGuard 返回类型没有 allow 结果——undefined 保留决策,返回 reason 只能拒绝,监听器顺序无法把拒绝变回允许(单调性)
  • 执行模式分 parallel(可与兄弟并行)和 exclusive(独占形成屏障)
  • deferContext() 允许组合工具把嵌套分派的上下文转运回外层结果

七、LLM Seam(适配器缝)

ctx.llm 定义了消息/内容块/流式词汇表和适配器 seam。添加模型提供方 = 在 ctx.llm 上注册一个适配器。你机器上装的 dsh-llm-deepseek、dsh-llm-pi-ai 就是具体适配器,当前配置用的是 deepseek-official 提供方。

八、能力 Seam(Capability Seam)

一个 seam 是三项角色组成的可替换能力:

  1. Service Definition:声明接口
  2. Service Provider:实现它
  3. Consumer:使用它(通常是面向模型的工具)

"替换一个提供方就能改变整个产品"——文件系统与进程提供方共享同一个执行世界,把 fs 指向远程沙箱,Bash、PTY、LSP 就一起搬过去了,无需提供方专用 fork。子代理提供方(ctx.subagent)在同一个接口之后也千差万别:从新建子 agent,到把轮次委派给另一个产品。

九、作用域(Scope)机制

ScopeKey 是不透明对象身份(已交付的 loop 用活跃 Agent 对象当 key);Scoped<T> 是编译期品牌标记。注册表用同一个上下文同时表达"每个 agent 的可见性"和"共享生命周期所有权",agent.ctx 的注册项 agent 专属、卸载时撤销、之后拒绝再注册。这解释了为什么子代理、workflow 里的工具集合可以按 agent 隔离。

十、事件是扩展点:三个事件域

事件域 性质 用途
会话事件 追加到日志、广播 session/event 的持久事实 需要 reload 后仍存在的事实
Agent 事件(agent/*) 携带活跃 Agent:inbox、步骤、状态、请求、验证 观察/拦截进行中的工作
能力事件 无需 import 循环即可附加策略和适配器 fs/*、tools/*、telemetry/*

十一、新行为的归属位置(快速索引)

想做什么 挂哪里
添加模型提供方 ctx.llm 注册适配器
添加面向模型的能力 ctx.tools 注册,schema 自动进提示词
添加 shell 执行 ctx.shell 后端(本地后端经 ctx.subprocess spawn)
限制启动的进程 ctx.sandbox 后端,消费方启动前包装 argv
拦截请求/工具/轮次 agent/* 或 tools/* 事件
添加模型可见上下文 agent.inject(),落到下一次获准请求
添加 UI 集成 驱动 ctx.agents + 从 session/event 渲染
fork 活跃会话 ctx.sessions.fork(source, boundary?)
管理同会话目标 ctx.goals,通过 agent/* 续跑

总结一句:DSH = Cordis 插件框架(装配层)+ 事件溯源会话(状态层)+ 可替换的 LLM/FS/Shell/Sandbox/Subagent 能力缝(能力层)+ Agent 接口与默认 Loop(执行层),最上层是 web/headless 等 profile(产品形态)。和 Codex/Trae 这类单体产品不同,你在 DSH 里改任何一个环节——哪怕是循环本身——都是在"叠 patch 层",而不是"打补丁"。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

友情链接更多精彩内容