DeepSeek Harness (dsh) 系统级架构分析

本文档对 DeepSeek Harness 项目进行系统级深度架构分析,覆盖整体架构设计、54 个包的模块拆解、跨模块调用关系与数据流,以及关键运行时流程。所有架构图均使用 Mermaid 语法绘制。


目录


第一部分:整体架构与设计哲学

1.1 项目定位与核心命题

DeepSeek Harness(以下简称 dsh)是一个插件化 AI Agent 运行时,构建于 Cordis 框架之上。其核心命题是:

一切皆插件(Everything is a Plugin)——包括模型适配器、工具注册表、会话日志、甚至 Agent 循环本身,都是可从配置替换的插件。

这意味着 dsh 没有特权核心需要打补丁:扩展 dsh 的方式是在其他插件旁挂载一个新插件,而注册是可逆效应,卸载时自动回滚。

1.2 Cordis 框架基础

dsh 的底层是 Cordis——一个基于 TypeScript 的插件化框架,核心概念包括:

概念说明
Context全局共享上下文对象,插件通过 ctx 注册和消费服务
Fiber插件的生命周期单元,6 状态机:PENDING → LOADING → ACTIVE → FAILED → UNLOADING → DISPOSED
Service可调用、可隔离、可拦截、可追踪的服务单元
Registry3 种插件形式:函数式 / 构造式 / 对象式
Events5 种派发模式:emit / parallel / serial / bail / waterfall
ReflectProxy 代理服务,实现服务调用的透明拦截

Cordis 的注册是效应:卸载插件时,该插件的所有注册自动回滚,保证系统状态一致性。

1.3 插件化架构总览

dsh 的整体架构可分为四层,自底向上:

第一层:Cordis 插件运行时

第二层:Bundle 分发层

第三层:Profile 组合层

第四层:应用入口

dsh-web-app
浏览器应用 Profile

dsh-headless
一次性运行器 Profile

Profile(命名组合)
列出 Bundle 列表 + 补丁

cordis.patch.yml
用户级补丁覆盖

dsh-base
共享核心 Bundle
模型/工具/持久化/沙箱/设置/凭证/遥测

dsh-web-app Bundle
添加浏览器应用

dsh-headless Bundle
添加无服务器运行器

Context (ctx)
全局共享上下文

核心脊柱
agent / agent-loop / session /
system-prompt / scope / tools

能力接缝
llm / shell / fs / subprocess /
web / lsp / sandbox / subagent /
workflow / compaction / e2b / mcp

基础设施
storage / settings / credentials /
boot / bundle / preset / api /
sdk / client / host / extensions

1.4 Profile 与 Bundle 分层组合系统

dsh 的启动过程是一个有序分层叠加过程:

概念定义存储位置
Profile命名组合,存储在 Harness home,列出 Bundle 列表 + 持有树外插件 + 用户 cordis.patch.yml~/.dsh/profiles/
Bundle分发格式,包含 Cordis 配置行和对应代码,声明于 package.json 的 dsh.bundle 字段各 package
Patch通过 id 定位配置行,替换整行或插入新行YAML 文件

叠加顺序(从底到顶):

空 Entry 列表

Bundle 1
(Profile 列表顺序)

Bundle 2

Bundle 3

Profile 的
cordis.patch.yml

Home 级
cordis.patch.yml

--patch 命令行覆盖

最终插件树

内置 Profile 模板:

  • web:浏览器应用模式,包含 dsh-base + dsh-web-app
  • headless:无服务器模式,包含 dsh-base + dsh-headless

1.5 三类服务模型:核心服务 / 能力接缝 / 组合点

dsh 的 ctx 上注册的服务分为三类:

类型特征示例
核心服务(Core)系统运行必需的基础设施,不可替换ctx.sessions、ctx.agents、ctx.systemPrompt、ctx.tools
能力接缝(Seam)可替换的能力接口,三方角色:定义/实现/消费ctx.llm、ctx.shell、ctx.fs、ctx.subprocess、ctx.web
组合点(Bundle)具体的实现插件,注册到某个接缝ctx.agentLoop(唯一的循环驱动器)

能力接缝的三方角色模型:

能力接缝三方角色

ctx.registerService()

ctx..register()

ctx..call()

路由到注册的 Provider

返回结果

Service Definition
声明接口
定义 ctx 上的键和类型

Service Provider
实现接口
注册到 ctx 的具体后端

Consumer
使用接口
通常是模型面向的工具

Context

1.6 事件系统三域

dsh 的事件分为三个域,每个域有不同的持久性和派发语义:

事件域持久性派发模式用途示例
Session 事件持久(追加到日志)emit必须在重载后存活的事实turn/start、user/message、assistant/chunk、tool/call、tool/result
Agent 事件实时(不持久化)emit / waterfall / serial观察或拦截进行中的工作agent/pre-step、agent/request、agent/status、agent/turn-stopping
Capability 事件实时waterfall / emit附加策略和适配器到接缝fs/write-intent、tools/pre-execute、llm/stream、approval/request

Waterfall 事件的监听器必须调用 next() 来委托给下一个监听器;Serial 事件没有 next(),按顺序执行所有监听器。

1.7 Turn/Step 运行时生命周期

dsh 的核心运行时由两个概念驱动:

概念定义
Step一次模型请求 + 该请求调用的工具
Turn零或多个 Step:从第一个输入被认领开始,到不再欠任何东西时关闭

完整生命周期序列图:

Session Log ctx.tools ctx.llm ctx.systemPrompt Hook Listeners Driver User Session Log ctx.tools ctx.llm ctx.systemPrompt Hook Listeners Driver User 认领 next-step 输入 + 一个排队消息 turn 不花费 step,关闭 opt [call starts] opt [result ready] loop [barriers + rolling pool] alt [请求成功] [请求失败] opt [自然停止 + next-step 为空] 认领 → 下一个 step opt [next-step 输入待处理] alt [rejected 或 空 enter] [enter proposed step] followup(content) turn/start agent/pre-step (waterfall) reject 或 enter(messages) step/start user/message (per entered message) system-prompt/assemble (waterfall) agent/request (waterfall) → llm/stream (waterfall) StreamChunk* assistant/chunk* assistant/message classify pending calls tool/call pre → guards → execute → post tool/result agent/request-error (waterfall) retry action 或 preserve error step/end agent/turn-stopping (serial) turn/end

1.8 会话日志作为真理之源

会话日志是模型所见上下文的唯一来源:

Model-visible means logged. 任何到达模型请求的内容必须可从日志重建,运行时不变式会断言这一点。

关键设计决策:

  • deriveMessages() 从日志投影模型历史
  • 原始 assistant/chunk 事件保留回放和 UI 保真度
  • Fork、resume、transcript、telemetry、persistence 全部从事件流派生
  • 新的模型可见输入需要新的 Session 事件:扩展 SessionEventMap 并从日志渲染

1.9 工具执行管线

工具执行管线是 dsh 最精密的子系统之一,在七个阶段中运行策略、钩子、沙箱、文件系统守卫、结果重写、最终观察和 UI 渲染:

allow

deny

allow

deny

Assistant 消息包含 tool-call block

Session 事件: tool/call
执行前记录

tools/pre-execute 瀑布
钩子、权限、沙箱

注册的 monotonic guards
deny 或 abstain

ctx.approval 一次性提示
缺失或无回答: deny

tools/execute 瀑布
超时、重试、指标

工具 execute() body

fs/write-intent 或 fs/edit-intent
仅 tool-fs 变更

tools/post-execute 瀑布
accept/block/replace/add context

finalizeContent
同步内容不变式

tools/result 同步通知
冻结的权威结果

Session 事件: tool/result
单一模型面向结果

1.10 包依赖层次结构

dsh 包含 54 个包,按依赖关系可分为五层:

L4: 应用/客户端层

L3: 基础设施层

L2: 能力接缝层

L1: 核心脊柱层

L0: Cordis 框架层

@cordis/core
Context/Fiber/Registry/Events

core/agent

core/agent-loop

core/session

core/system-prompt

core/scope

core/tools

core/agent-default-model

llm/llm

shell

subprocess

fs

web

lsp

sandbox

subagent

workflow

compaction

skill

e2b

mcp

code-runtime

settings

credentials

storage

session-persistence

session-query

jobs

spill

interaction

guard

hooks

todo

plan

goal

schedule

runtime-diagnostics

attachment

context

workspace

boot

bundle

preset

api

sdk

client

host

extensions

acp

typert

feedback

identity

util


第二部分:核心脊柱模块群

以下为 dsh 核心脊柱模块群的深度分析,涵盖 agent、agent-loop、session、system-prompt、scope、agent-default-model、agent-tool-presentation 七个模块。

目录

  1. core/agent — Agent 接口与注册表
  2. core/agent-loop — 默认 Agent 驱动器
  3. core/session — 会话事件日志
  4. core/system-prompt — 系统提示词组装
  5. core/scope — 作用域注册
  6. core/agent-default-model — 默认模型
  7. core/agent-tool-presentation — 工具展示
  8. 核心脊柱整体协作

1. core/agent — Agent 接口与注册表

路径: packages/core/agent/src/
核心作用: 定义 Agent 的公共接口、运行时类型、事件词汇表,并通过 AgentRegistry 服务管理进程内所有活跃 Agent 的生命周期注册表;同时承载 Inbox(待处理消息队列投影)、模型选择(ModelSelection)、事件分发(Dispatch)与已消费工作核算(ConsumedWork)等关键子能力。

1.1 模块内部架构

core/agent 模块

AgentRegistry
Service
ctx.agents

AgentFactory 接口
create/resume

AgentHandle
agent + dispose

Initiator Scope
AsyncLocalStorage

Agent 接口
(runtime-types.ts)

Inbox
待处理消息投影

Agent 类型与事件
(types.ts)

Dispatch
agentEvents/agentCarrier

ModelSelection
installModelSelection

ConsumedWork
foldConsumedWork

1.2 关键类/函数/方法表格

名称类型职责
AgentRegistryclass (Service)进程内 Agent 注册表;管理 Agent 的创建(委托给 AgentFactory)、注册、公告(announce)、查询、销毁;通过 AsyncLocalStorage 维护 initiator 驱动链
AgentFactoryinterfaceAgent 创建工厂接口,由 agent-loop 插件实现;定义 createAgent 和 resume 两个异步创建路径
AgentHandleinterface持有者获得的 Agent 句柄,包含 Agent 引用和 dispose() 销毁能力
AgentinterfaceAgent 公共接口;包含 id、options、session、inbox、status、ctx,以及 cancel、whenIdle、runMaintenance、send、followup、steer、inject 等方法
InboxclassAgent 待处理消息的增量投影;从 session 事件日志重建,维护 next-turn 和 next-step 两个有序列表,支持 append/prepend/replace/remove/claim/clear 操作
agentEventsfunction构建融合作用域载体的事件分发器;将 Agent 主体与 scope carrier 绑定,确保事件中的 agent 字段与 scope key 不可分离
agentCarrierfunction为 Agent 构建无状态的作用域载体(Scoped<Agent>)
assembleContextForfunction构建提示词组装上下文,将 agent 和 scope 同时设置,确保 agent 作用域的提示词/工具贡献不会被遗漏
installModelSelectionfunction将可变模型选择绑定到 Agent 作用域的提示词组装和请求路由;在组装时快照当前选择,在请求时应用 provider/model/effort
ModelSelectioninterface完整的 provider、model 和可选 reasoningEffort 选择
ModelSelectionRefinterface可变选择引用,区分 current(下一步将用)和 assembled(当前步已组装)
foldConsumedWorkfunction折叠 Agent 日志,核算已消费工作;返回最近结束的核算 turn 和是否有被取消而未运行的工作
AgentRegistry.registermethod注册已构造的 Agent;发出 agent/created,在 fiber 销毁时发出 agent/disposed
AgentRegistry.entermethod插入未公告的 Agent(高级原语,供工厂使用)
AgentRegistry.announcemethod公告已插入的 Agent,发出 agent/created 事件
AgentRegistry.createmethod通过注册工厂创建并发布新 Agent
AgentRegistry.resumemethod通过注册工厂加载持久化会话并恢复 Agent
AgentRegistry.withInitiatormethod在指定 Agent 作为 initiator 的边界内执行操作
AgentRegistry.withoutInitiatormethod在清除 initiator 的边界内执行操作(用于共享定时器/队列等)
AgentRegistry.currentInitiatormethod读取继承的 initiator Agent(可选)
AgentRegistry.requireInitiatormethod读取并要求 initiator 存在,否则抛错

1.3 与其他模块的调用关系

  • → core/session:Agent 接口持有 Session 引用;Inbox 从 Session.events 重建并使用 Session.append 记录持久化 splice 事件;AgentCancelCause、SessionId 等类型从 session 模块导入
  • → core/scope:通过 scopeTarget(agent, agent) 构建 scope carrier,用于事件分发的作用域过滤;AgentRegistry 自身通过 ctx.accessor('agent', ...) 注册 DX 上下文访问器
  • → core/system-prompt:assembleContextFor 构建传递给 systemPrompt.assemble() 的上下文;AssembleContext 接口通过模块增强声明 agent 字段
  • → core/agent-loop:AgentRegistry 不直接依赖 agent-loop,而是通过 AgentFactory 接口反转依赖;agent-loop 在构造时调用 ctx.agents.setFactory(this) 注册自己
  • → core/agent-default-model:ModelSelection 类型被 agent-default-model 模块导入并使用
  • ← 被 agent-loop 调用:agent-loop 的 ReactLoopAgent 实现 Agent 接口,使用 agentEvents、Inbox、assembleContextFor 等
  • ← 被 ACP bridge 等消费者调用:通过 ctx.agents.create() / ctx.agents.resume() 创建 Agent

2. core/agent-loop — 默认 Agent 驱动器

路径: packages/core/agent-loop/src/
核心作用: 实现 AgentFactory 接口,提供 ReactLoopAgent 作为默认的 Agent 驱动器;负责 Agent 的创建/恢复事务(prepare → setup → publish → drive)、Turn/Step 两级驱动循环、工具调用调度,以及配置驱动的声明式 Agent 启动。

2.1 模块内部架构

core/agent-loop 模块

AgentLoop
Service + AgentFactory
ctx.agentLoop

FactoryOwnership
工厂级生命周期追踪

PreparedAgent
未发布的 Agent 资源

ReactLoopAgent
implements Agent

Phase 状态机
idle / maintenance / running

RuntimeContextProjection
运行时上下文投影

executeToolCalls
工具调用调度器

DEFAULT_MAX_PARALLEL_TOOL_CALLS

2.2 关键类/函数/方法表格

名称类型职责
AgentLoopclass (Service)插件主服务;实现 AgentFactory,管理配置驱动的 Agent 启动、prepare 事务、settings 集成(maxParallelToolCalls)
ReactLoopAgentclass默认 Agent 驱动器实现;实现 Agent 接口,驱动 Turn/Step 两级循环,管理 idle/maintenance/running 三相状态机
FactoryOwnershipclass工厂级生命周期追踪;追踪活跃 Agent 的 teardown、配置启动任务和公共 create/resume 延续;通过 AbortController 融合三种销毁源(调用者取消、owner fiber 卸载、工厂 teardown)
RuntimeContextProjectionclass运行时上下文投影;追踪上次保留的 runtime-context 快照,仅在值变化时生成新的 UserMessage
executeToolCallsfunction调度一个 assistant step 的工具调用;排他调用形成屏障,并行调用使用有界滚动池;结果和上下文按模型顺序提交
runGroupfunction运行一个排他屏障或并行池;在启动前重新分类后续调用;abort 时排干已启动调用并记录合成结果
PreparedAgentinterface已准备但未发布的 Agent 资源;包含 agent、signal、publish(source) 和 dispose()
AgentLoop.preparemethod构建驱动器、作用域和记忆化反向 teardown;在发布前注册到工厂和 owner fiber
AgentLoop.createAgentmethod创建 owned Agent 的公共路径;prepare → setup → publish
AgentLoop.resumemethod从持久化恢复 Agent;加载持久化 → prepare → setup → publish
AgentLoop.setupAndPublishmethod在已获取的 Session 上准备 Agent、运行 setup、发布
ReactLoopAgent.kickmethod驱动器入口;循环执行 turn() 直到无需继续
ReactLoopAgent.turnmethod开启一个 turn;循环执行 preStep → step → turn-stopping 判定
ReactLoopAgent.stepmethod执行一个 step;构建请求 → 流式调用 LLM → 组装消息 → 执行工具调用
ReactLoopAgent.buildRequestmethod组装冻结的请求配置并绑定到 adapter 注册;处理 request/header 的 initial/resume/change 三种原因
ReactLoopAgent.preStepmethod步骤前处理;claim inbox 消息、组装提示词、投影运行时上下文、触发 agent/pre-step waterfall
ReactLoopAgent.wakeDrivermethod启动驱动器或锁存 wake;idle 时开启 turn 边界,running/maintenance 时锁存
ReactLoopAgent.sendmethod路由消息到 inbox 边界并可选唤醒驱动器
ReactLoopAgent.cancelmethod清空 inbox(除非 keepInbox)并中止活跃 turn
ReactLoopAgent.runMaintenancemethod在真实 idle 阶段运行非 turn 维护任务

2.3 与其他模块的调用关系

  • → core/agent:实现 AgentFactory 并通过 ctx.agents.setFactory(this) 注册;使用 agentEvents、Inbox、assembleContextFor、emitAgentEvent;通过 ctx.agents.enter/announce/register 管理 Agent 生命周期
  • → core/session:通过 ctx.sessions.prepare/enter/announce 管理 Session 生命周期;使用 SessionPreparation 包装未发布的 Session;通过 Session.append 记录所有事件
  • → core/system-prompt:在构造时注册 provider、model、cwd 变量;在 preStep 中调用 ctx.systemPrompt.assemble() 组装提示词;使用 renderPrompt、renderContextSections、joinContextSections
  • → core/scope:通过 createScope(loopCtx, this) 创建 Agent 作用域;通过 this.ctx = this.scope.ctx.extend({ agent: this }) 构建 Agent 作用域上下文
  • → dsh-llm:通过 ctx.llm.stream(request) 发起 LLM 请求;使用 BlockAssembler 组装流式响应;通过 ctx.llm.prepareCall 解析 adapter 默认值
  • → dsh-tools:通过 ctx.tools.executionMode 判断工具并发模式;通过 ctx.tools[TOOL_RUNTIME_SCHEDULER] 的 prepare/dispatch/finalize/finish 调度工具执行
  • → dsh-session-persistence:在 resume 路径中通过 ctx.get('sessionPersistence') 获取持久化服务
  • → dsh-settings:通过 installSettingsSection 注册 agent-loop settings 命名空间(maxParallelToolCalls)

3. core/session — 会话事件日志

路径: packages/core/session/src/
核心作用: 提供 Event-Sourced 的会话事件日志——一个只追加(append-only)的 SessionEvent 序列作为 Agent 交互的持久化真相来源;包含 Session 类(事件日志 + 派生消息历史)、SessionStore 服务(内存存储 + 生命周期管理)、Surface 层(有序消息表面)、请求头折叠、分块压缩存储编码、崩溃修复等子模块。

3.1 模块内部架构

core/session 模块

Session
事件日志 + 派生历史

SessionStore
Service
ctx.sessions

SessionPreparation
未发布 Session 所有权

SurfaceManager
有序消息表面

foldRequestHeader
canonicalHeader
headerEquals

foldSurface
纯函数表面折叠

类型定义
SessionEvent/SessionEventMap
SessionHeader/TurnEndReason

interruptedTurnClosers
崩溃修复

KNOWN_SESSION_EVENT_TYPES

packChunkRuns
decodeStorageRecord

3.2 关键类/函数/方法表格

名称类型职责
SessionclassEvent-Sourced 会话;维护只追加事件日志、Surface 表面管理器、增量的请求头折叠和派生消息历史缓存;支持 create(新建)和 fromRestore(从持久化恢复)两种构造模式
SessionStoreclass (Service)内存会话存储服务;管理 Session 的创建(create)、准备(prepare)、插入(enter)、公告(announce)、查询、fork 和 flush
SessionPreparationclass (Disposable)未发布 Session 的所有权包装;确保在发布或回滚时释放提供者状态
SurfaceManagerclass增量有序表面视图;管理 surface 节点序列和替换代数(replaceGeneration);验证下一个事件而不修改已提交状态
foldSurfacefunction纯函数完整表面折叠;重放事件日志,返回当前表面序列和替换历史
deriveEventMessagefunction单节点投影规则;将一个 surface 事件投影为 LLM 消息或 null
Session.appendmethod追加一个类型化事件到日志;同步通知观察者;验证 JSON 可序列化性和 surface 元数据
Session.deriveMessagesmethod从有序表面派生 LLM 消息历史;每个 surface 节点只投影一次,surface 重写时重建
Session.requestHeadermethod增量折叠请求头事件,返回当前 EpochHeader
Session.requestContextmethod增量折叠 request/context 事件,返回当前路由元数据
SessionStore.preparemethod构建 Session 但不进入存储;验证 id/cwd,构造 Session 和 SessionHeader
SessionStore.entermethod将 prepared Session 插入存储;安装发布钩子;返回 detach disposer
SessionStore.announcemethod发出 session/created 事件;与 enter 分离以支持回滚安全
SessionStore.forkmethod从活跃源的稳定前缀创建子会话
SessionStore.flushmethod派发 session/flush 持久化检查点
foldRequestHeaderfunction纯函数请求头折叠;从事件日志重建当前 EpochHeader
canonicalHeaderfunction将 header 规范化为标准形式(空 system/tools 变为 absent)
headerEqualsfunction规范头的字段级相等比较
packChunkRunsfunction将连续的 delta chunk 事件打包为存储行;无损压缩(~56× 实测压缩比)
decodeStorageRecordfunction将存储行解码回原始事件
interruptedTurnClosersfunction为崩溃中断的会话日志生成合成关闭事件;为未匹配的工具调用生成错误结果
KNOWN_SESSION_EVENT_TYPESconst本构建已知的事件类型集合;持久化读取路径拒绝未知类型(除非标记 ignorable)

3.3 与其他模块的调用关系

  • ← core/agent:Agent 接口持有 Session 引用;Inbox 使用 Session.append 记录 inbox splice;AgentCancelCause、SessionId 等类型从此模块导出
  • ← core/agent-loop:agent-loop 通过 ctx.sessions.prepare/enter/announce 管理 Session 生命周期;ReactLoopAgent 通过 Session.append 记录所有 turn/step/chunk/message 事件
  • → core/scope:SessionStore 使用 scopeTarget(session, scopeOf(ctx)) 和 scopeOf 构建 scope carrier
  • → dsh-llm:导入 Message、UserMessage、AssistantMessage、ToolResultMessage、LlmCallConfig、StreamChunk 等类型;使用 deepFreeze 冻结事件数据
  • ← dsh-session-persistence:持久化插件订阅 session/event 和 session/flush 事件;使用 packChunkRuns/decodeStorageRecord 进行存储编解码
  • ← 其他插件:通过 SessionEventMap 的模块增强声明插件事件类型(如 agent/inbox/spliced、compaction/*、todo/write 等)

4. core/system-prompt — 系统提示词组装

路径: packages/core/system-prompt/src/
核心作用: 提供有序的系统提示词段落(Section)、动态上下文(Context)、工具 schema(Tools)和变量(Variable)的注册表服务;在每次模型调用前组装这些部分为完整的 PromptAssembly,经过 waterfall 中间件变换后输出。

4.1 模块内部架构

core/system-prompt 模块

SystemPrompt
Service
ctx.systemPrompt

ScopedLayers
全局+作用域层管理

PromptLayer
作用域注册层

PromptSection
命名段落

PromptContext
动态上下文

ToolProvider
工具 schema 提供者

VariableProvider
变量提供者

PromptAssembly
组装结果

renderPrompt
渲染+插值

renderContextSnapshot
renderContextSections

4.2 关键类/函数/方法表格

名称类型职责
SystemPromptclass (Service)注册表服务;管理全局和作用域的段落、上下文、工具提供者和变量;在 assemble() 时合并所有层、排序、运行 waterfall
PromptLayerclass (ScopeLayer)一个作用域层的全部注册;包含 sections、contexts、runtimeContextSuppressors、toolProviders、variables 五个表
PromptSectioninterface命名段落注册项;包含 name、order、text(静态或函数)、可选 complete(声明为完整提示词)
PromptContextinterface动态上下文注册项;包含 name、order、text(静态或函数)
ToolProviderResultinterface工具提供者返回值;包含 schemas 和可选 knownNames
PromptAssemblyinterface组装结果;包含 sections、contexts、tools、variables 四个部分
AssembledSectioninterface已解析的段落;name + 已解析但未插值的 text
AssembledContextinterface已解析的上下文贡献
AssembleContextinterface组装上下文;包含可选 scope、signal,通过模块增强可携带 agent
SystemPrompt.sectionmethod注册有序段落;作用域段落阴影全局同名段落
SystemPrompt.contextmethod注册有序动态上下文
SystemPrompt.toolsmethod注册工具 schema 提供者
SystemPrompt.variablemethod注册提示词变量
SystemPrompt.suppressRuntimeContextmethod抑制调用作用域的所有动态运行时上下文贡献
SystemPrompt.assemblemethod组装全局和作用域提供者的输出,应用排序和阴影规则,运行 waterfall,返回最终 PromptAssembly
renderPromptfunction插值 {{variable}} 引用,丢弃空段落,用空行连接其余段落
renderContextSnapshotfunction渲染完整动态上下文快照文本
renderContextSectionsfunction渲染为命名贡献列表,用于归属展示
joinContextSectionsfunction将已渲染的段落列表连接为快照文本
PERSONA_SECTIONconst部署 persona 段落名(deployment:persona),order=0
TOOL_ORDER_RESTconsttoolOrder 配置中的通配符标记(<unlisted-tools>)

4.3 与其他模块的调用关系

  • ← core/agent:AssembleContext 通过模块增强接受 agent 字段;dispatch.ts 的 assembleContextFor 构建传入 assemble() 的上下文
  • ← core/agent-loop:agent-loop 在构造时注册 provider、model、cwd 三个变量;在 preStep 中调用 ctx.systemPrompt.assemble();使用 renderPrompt、renderContextSections、joinContextSections 渲染组装结果
  • → core/scope:使用 ScopedLayers 管理全局和作用域层;使用 scopeTarget(this, scope) 构建 waterfall 的 scope carrier;通过 scopeOf(ctx) 确定注册的作用域
  • ← core/agent/model-selection:installModelSelection 在 system-prompt/assemble waterfall 中注入模型选择变量
  • ← 其他插件:工具插件通过 ctx.systemPrompt.tools() 注册工具 schema;提示词插件通过 ctx.systemPrompt.section() / .context() / .variable() 注册贡献

5. core/scope — 作用域注册

路径: packages/core/scope/src/
核心作用: 提供作用域原语——通过 createScope 铸造一个标记了不透明身份的 Cordis 上下文,通过 scopeTarget 构建路由-only 事件载体;支持作用域父子链(parent binding)和作用域层叠继承(ScopedLayers),使 Agent 作用域的注册和事件分发能够精确过滤。

5.1 模块内部架构

core/scope 模块

createScope
铸造作用域上下文

Scope 接口
ctx + dispose

scopeOf
读取上下文 scope tag

scopeTarget
构建事件载体

scopeChainOf
读取作用域链

bindScopeParent
绑定父作用域

ScopedLayers
层叠注册管理

NamedEntries
命名条目表

AnonymousEntries
匿名条目表

5.2 关键类/函数/方法表格

名称类型职责
createScopefunction在 ctx 下铸造一个作用域;通过 ctx.plugin(scope) 创建 backing fiber,通过 ctx.extend({ [kScope]: key }) 标记上下文;返回 Scope(ctx + rawDispose + dispose)
scopeTargetfunction构建路由-only 事件载体;保留 base 的 Cordis filter,接纳未标记监听器和匹配 key 及其祖先的标记监听器;事件沿作用域链向上流动
scopeOffunction读取上下文继承的最近 scope tag
bindScopeParentfunction绑定子作用域的父作用域;返回 ScopeParentBinding(唯一可重链接的句柄);环检测
scopeParentOffunction读取一个 key 的父作用域
scopeChainOffunction返回从 key 到根祖先的链(nearest-first)
Scopeinterface铸造的作用域;包含 ctx(注册上下文)、rawDispose(精确 Cordis disposer)、dispose()(共享销毁)
ScopeKeytype不透明的、身份比较的作用域 key(object)
Scoped<T>type路由-only 事件接收器;类型参数记录主体类型
ScopedLayers<L>class管理全局和作用域层;提供 peek(精确层)、chainLayers(链层)、merge(合并命名条目)、effect(注册+效果所有权)
NamedEntries<V>class插入有序的命名条目表;重复名抛错;返回幂等 undo
AnonymousEntries<V>class插入有序的匿名条目表;独立注册身份;返回幂等 undo
isScopeCarrierfunction测试值是否为 scope 载体
carrierKeyOffunction读取载体的路由 key

5.3 与其他模块的调用关系

  • ← core/agent:AgentRegistry 使用 scopeTarget(agent, agent) 构建 agent 事件分发的 carrier;agentCarrier 直接使用此函数
  • ← core/agent-loop:ReactLoopAgent 构造时调用 createScope(loopCtx, this) 创建 Agent 作用域;通过 this.scope.ctx.extend({ agent: this }) 构建 Agent 上下文
  • ← core/session:SessionStore 使用 scopeTarget(session, scopeOf(ctx)) 和 scopeOf(ctx) 构建 session 事件的 scope carrier
  • ← core/system-prompt:SystemPrompt 使用 ScopedLayers 管理段落/上下文/工具/变量的全局和作用域层;使用 scopeTarget(this, scope) 构建 waterfall carrier;使用 scopeOf(ctx) 确定注册作用域
  • → Cordis:基于 ctx.plugin() 创建 backing fiber;使用 ctx.extend() 标记上下文;carrier 通过 Context.filter 实现事件过滤

6. core/agent-default-model — 默认模型

路径: packages/core/agent-default-model/src/
核心作用: 独立于 Host 或传输层管理 Agent 的默认模型选择(provider + model + 可选 reasoningEffort);通过 settings 服务支持运行时修改,为没有显式模型选择的 Agent 提供回退。

6.1 模块内部架构

core/agent-default-model 模块

AgentDefaultModelConfig
Service
ctx.agentDefaultModel

Settings 集成
installSettingsSection

ModelSelection
provider + model + effort

6.2 关键类/函数/方法表格

名称类型职责
AgentDefaultModelConfigclass (Service)默认模型选择服务;持有可变 source 函数,通过 settings 实时读取;提供 currentSelection() 和 saveSelection()
AgentDefaultModelSettingsinterface存储和组合的默认模型设置;provider、model、可选 reasoningEffort
Configinterface组合入口配置;provider、model(无 effort — 由 settings 提供)
currentSelectionmethod读取当前默认模型选择;返回 ModelSelection
saveSelectionmethod保存完整默认模型选择到 settings
AGENT_DEFAULT_MODEL_SETTINGS_NAMESPACEconstsettings 命名空间(agent-default-model)
AGENT_DEFAULT_MODEL_SETTINGS_SCHEMAconstsettings schema

6.3 与其他模块的调用关系

  • → core/agent:导入 ModelSelection 类型;将选择投影为此类型
  • → dsh-llm:使用 ReasoningEffortId 品牌类型
  • → dsh-settings:通过 installSettingsSection 注册 settings 命名空间;通过 ctx.get('settings')?.replace() 保存选择
  • ← 消费者:Agent 创建入口在没有显式 AgentOptions.provider/model 时可读取 ctx.agentDefaultModel.currentSelection() 作为回退

7. core/agent-tool-presentation — 工具展示

路径: packages/core/agent-tool-presentation/src/
核心作用: Agent 预设层面的工具展示选择器;声明 Agent 的模型看到哪种形式的工具——native(原始 schema)、code(仅 run_code + 生成 SDK)或 both(两者皆有);一个组合一行声明,覆盖该预设下的所有 Agent。

7.1 模块内部架构

core/agent-tool-presentation 模块

apply
Cordis 插件入口

Config
mode: native|code|both

inject
['tools']

codeRuntime 等待
(code/both 模式)

7.2 关键类/函数/方法表格

名称类型职责
applyfunction (Cordis plugin)插件入口;根据 config.mode 调用 ctx.tools.presentAs();native 直接调用,code/both 等待 codeRuntime 服务后调用
Configinterface插件配置;mode: ToolPresentationMode(native | code | both),必填
nameconstCordis 插件名(tool-presentation)
injectconst依赖注入声明(['tools']);codeRuntime 不在列表中,按需等待

7.3 与其他模块的调用关系

  • → dsh-tools:通过 ctx.tools.presentAs(mode) 声明工具展示模式;导入 ToolPresentationMode 类型
  • → dsh-code-runtime:在 code/both 模式下通过 ctx.inject(['codeRuntime'], ...) 等待代码运行时服务
  • ← dsh-agent-presets:由 Agent 预设组合加载;预设声明其工具展示模式
  • ← core/agent-loop:间接通过 ctx.tools 读取展示模式,影响工具 schema 的组装

8. 核心脊柱整体协作

8.1 协作链路总览

DeepSeek Harness 的核心脊柱由七个模块构成一个完整的 Agent 运行时骨架。从 Agent 创建到模型调用的完整链路如下:

  1. Agent 创建:AgentLoop(agent-loop)作为 AgentFactory 通过 ctx.agents.create() 或配置驱动启动创建事务
  2. Session 准备:SessionStore(session)通过 prepare → enter → announce 三步将 Session 插入存储
  3. 作用域铸造:ReactLoopAgent 通过 createScope(scope)铸造 Agent 作用域上下文
  4. Setup 组合:在未发布状态下运行 setup 回调,通过 Agent 作用域上下文注册工具、提示词段落、变量等
  5. 发布:先公告 Session(session/created),再公告 Agent(agent/created),最后发出 agent/session-start
  6. 驱动循环:ReactLoopAgent.kick() 启动 Turn/Step 两级循环
  7. 步骤执行:每个 Step 中:
    • Inbox Claim:从 Inbox 认领消息
    • 提示词组装:调用 SystemPrompt.assemble() 组装系统提示词(段落 + 上下文 + 工具 + 变量)
    • 运行时上下文投影:RuntimeContextProjection 判断是否需要更新动态上下文快照
    • 请求构建:通过 agent/request waterfall 确定请求配置,记录 request/header
    • LLM 调用:流式调用 LLM,逐 chunk 记录 assistant/chunk,完成后记录 assistant/message
    • 工具调用:executeToolCalls 调度工具执行,记录 tool/call + tool/result
    • Turn 停止判定:无工具调用且无 next-step 消息时触发 agent/turn-stopping
  8. 销毁:AgentHandle.dispose() 或 owner fiber 卸载触发反向 teardown——停止驱动器 → 注销 Agent → 注销 Session → 解开作用域

8.2 完整协作序列图

Tool Registry LLM Adapter ReactLoopAgent Scope (core/scope) SystemPrompt (core/system-prompt) SessionStore (core/session) AgentLoop (core/agent-loop) AgentRegistry (core/agent) 消费者 (ACP Bridge / Config) Tool Registry LLM Adapter ReactLoopAgent Scope (core/scope) SystemPrompt (core/system-prompt) SessionStore (core/session) AgentLoop (core/agent-loop) AgentRegistry (core/agent) 消费者 (ACP Bridge / Config) 1. Agent 创建请求 2. Session 准备 3. 作用域铸造 4. Setup 组合 (未发布) setup 回调注册 agent 作用域的 工具、提示词、变量 5. 发布 (有序公告) 6. 驱动循环启动 7. Turn/Step 循环 loop [流式响应] opt [工具调用] opt [Turn 停止判定] loop [每个 Step] loop [每个 Turn] 8. 销毁 ctx.agents.create(options) factory.createAgent(ownerCtx, options) sessions.prepare(sessionId, {meta, seed}) Session (未发布) createScope(loopCtx, agent) Scope { ctx, dispose } scope.ctx.extend({ agent: this }) agentCtx.systemPrompt.section(...) agentCtx.systemPrompt.tools(...) agentCtx.systemPrompt.variable(...) sessions.enter(session) sessions.announce(session) emit session/created agents.enter(agent, ownerCtx.agent) agents.announce(agent) emit agent/created emitAgentEvent(agent, agent/session-start) wakeDriver() setPhase(running) emit agent/status { running } kick() session.append(turn/start) inbox.claim(target, turn) assemble({ agent, scope, signal }) PromptAssembly runtimeContext.project() session.append(user/message) session.append(step/start) waterfall agent/request LlmCallConfig session.append(request/header) llm.stream(request) chunk session.append(assistant/chunk) session.append(assistant/message) executeToolCalls(toolCalls) results session.append(tool/call) session.append(tool/result) session.append(step/end) serial agent/turn-stopping settled session.append(turn/end) handle.dispose() cancel({ kind: 'disposed' }) whenIdle() scope.dispose() detachAgent (emit agent/disposed) detachSession (emit session/disposed)

8.3 关键设计模式总结

反转依赖与工厂委托

core/agent 定义 AgentFactory 接口但不实现它;core/agent-loop 实现该接口并通过 ctx.agents.setFactory(this) 注册。这使得消费者可以仅依赖 ctx.agents 而不需要直接依赖 dsh-agent-loop 包。

三阶段发布事务

Session 和 Agent 的发布都遵循 prepare → enter → announce 三阶段模式:

  • prepare:构建对象但不插入存储
  • enter:插入存储、安装钩子,但不公告
  • announce:发出创建事件

这种分离确保了 setup 回调中的同步失败可以回滚(已 yield 的 disposer 在 throw 时被 Cordis 的 generator effect 自动销毁),而不会泄露部分配置的 Agent。

作用域继承与事件过滤

core/scope 实现了两个方向的继承:

  • 向下继承(注册可见性):子作用域能看到祖先的注册(ScopedLayers.chainLayers),SystemPrompt 利用此机制让 Agent 作用域阴影全局段落
  • 向上继承(事件分发):祖先的监听器能收到后代作用域的事件(scopeTarget 的 filter 逻辑),使得一个上层组合能观察其下所有 Agent 的事件
Event-Sourcing 与派生历史

core/session 的核心设计是 Event-Sourcing:所有交互以 SessionEvent 形式追加到不可变日志。LLM 消息历史不是存储的,而是通过 Surface 层从事件日志派生的。Surface 层维护一个有序的"消息产生事件"序列,支持 append(正常追加)和 replace(压缩替换)两种操作。这使得:

  • 日志是完整的(包括 chunk、turn 边界等非消息事件)
  • 消息历史是派生的(通过 Surface 投影)
  • 压缩可以替换历史范围而不丢失原始日志
两级循环与三相状态机

ReactLoopAgent 使用 Turn/Step 两级循环和 idle/maintenance/running 三相状态机:

  • Turn:一次完整的用户交互(从认领消息到 turn 结束)
  • Step:一次模型调用 + 工具执行
  • idle:无活跃驱动器
  • maintenance:运行非 turn 维护任务
  • running:活跃的 Turn/Step 驱动

wakeDriver 的锁存机制确保在 maintenance 或 aborted 活动期间的唤醒不会丢失,而是在收敛到 idle 时重放。

工具调用的有序调度

executeToolCalls 实现了精细的工具调用调度:

  • 排他模式:形成屏障,必须单独执行
  • 并行模式:有界滚动池,受 maxParallelToolCalls 限制
  • 模型顺序提交:无论执行顺序如何,结果按模型给出的顺序提交到会话日志
  • abort 处理:中止时排干已启动调用,为未启动调用记录合成错误结果,保持重放有效性
崩溃恢复

interruptedTurnClosers 为崩溃中断的会话日志生成确定性合成事件:为未完成的工具调用生成错误结果,关闭打开的 step 和 turn。这使得恢复后的会话日志对 LLM 来说是有效的(没有悬挂的工具调用),同时保留了崩溃前的完整记录。

存储压缩

packChunkRuns 将连续的 delta chunk 事件打包为单个存储行,实测压缩比约 56×。编解码是确定性的——解码后的事件与原始事件完全一致。未知的事件形状原样存储,不丢失数据。


以上分析基于 DeepSeek Harness 项目源码,涵盖 core/agent、core/agent-loop、core/session、core/system-prompt、core/scope、core/agent-default-model、core/agent-tool-presentation 七个核心脊柱模块的完整架构。


Logo

欢迎加入DeepSeek 技术社区。在这里,你可以找到志同道合的朋友,共同探索AI技术的奥秘。

更多推荐