Files
deepseek-harness/docs/architecture.zh.md

16 KiB
Raw Blame History

DeepSeek Harness 架构

English | 中文

DeepSeek Harness SDK 基于 Cordis 构建 agent harness智能体框架。设计准则很简单一切皆插件。已交付的循环只是一个插件,并非拥有特权的内核。

概览

一个 harness 对应一个 Cordis 上下文。各包package会添加服务ctx.llmctx.toolsctx.sessionsctx.sessionTitle)、类型化事件(agent/requesttools/pre-executesession/event)和可释放的注册项。

packages/core/ 汇集默认的 agent 流程;外围功能同样都是一等的 Cordis 插件。

默认服务

ctx 键 职责
dsh-scope 作用域上下文注册原语(库)
ctx.sessions dsh-session 内存中的事件溯源会话
ctx.systemPrompt dsh-system-prompt 有序提示词片段、工具 schema 和提示词变量
ctx.tools dsh-tools 工具注册表和执行流水线
ctx.agents dsh-agent 活跃 agent、委托创建、agent/* 事件和进程内发起方作用域
ctx.agentLoop dsh-agent-loop 实体 Agent 驱动器

功能服务

ctx 键 包族 职责
ctx.llm llm/ 适配器注册表和模型流式调用
ctx.tokenMeter llm/token-meter 感知回放的单实例请求压力和会话表面压力
ctx.bash bash/ 前台和后台命令执行
ctx.sandbox sandbox/ 同一执行环境内的进程限制argv 包装、逐调用策略)
ctx.sandboxPolicy sandbox/ 共享沙箱策略归属点
ctx.codeRuntime code-runtime/ 执行模型编写的程序
ctx.fs fs/ 文件系统提供方原语和策略事件
ctx.skills skill/ skill技能提供方注册表和渐进式披露
ctx.web web/ 搜索与抓取提供方注册表
ctx.compactctx.toolResultPrune compact//compact-tool-result-prune 摘要压缩compaction可选的无模型结果裁剪
ctx.subagents subagent/ 具名委托提供方
ctx.tasks tasks/ 后台任务注册表和通用 task_* 控制工具
ctx.workflows workflow/ 脚本驱动的多 agent 编排
ctx.sessionPersistence session-persistence/ 会话日志的持久存储
ctx.sessionQuery session-query/ 实时优先的逻辑语料精确读取和关系追踪
ctx.sessionTitle session-title/ 基于日志的回退标题和单个可选异步提供方

事件

事件构成服务的扩展 API完整清单见事件目录生产方与消费方映射

事件域

  • 会话事件是追加到日志并通过 session/event 发出的持久事实。
  • Agent 事件携带活跃 Agent,用于状态、提示词准入、请求塑形、验证和续跑。
  • 功能事件让所属服务边界无需导入循环即可附加策略和适配器。

拦截语义

waterfall瀑布式事件的行为类似环绕中间件监听器调用 next() 即表示委托,直接返回而不调用它则会否决或接管。完整规则见 Cordis waterfall 语义

默认循环生命周期

已交付的循环通过插件可见的服务和事件,持续处理从提示词到检查点的工作。

会话是仅追加日志。每个普通轮次领取一项已排队的 send() 输入;注入不领取输入。后续轮次会等待上一项已领取轮次的检查点,但可以与其共用同一个 running 区间(决策)。模型和插件停止轮次时,该轮次结束。一个步骤包含一次模型请求及其工具。下文(时序配套文档)用引号标记持久事件。

未提供 id 时会生成 <config-id>-session-<uuid>sessionId 用于恢复或创建会话,而 resumeSessionId 要求已有历史。恢复流程在发布前还原沿袭关系和委托深度。设置失败会发出 agent-loop/config-start-failed;拆卸过程保持静默。

轮次流程

choose declarative identity and fresh/resume path
  -> prepare private session + agent.ctx -> await unpublished setup
  -> enter session + agent -> session/created -> agent/created
  -> enable driving -> agent/session-start(source) -> start driver
forever:
  wait for a queued message
  emit agent/status(running)
  TURN:
    'turn/start'
    claimed message -> agent/prompt-submit
      allowed prompt -> 'user/message' plus injected context
      blocked prompt -> 'prompt/blocked' -> 'turn/end'(rejected)
    STEP loop:
      drain steering
      assemble system prompt and tool schemas
      agent/session-prefix (first step)
      agent/pre-step
      snapshot the derived messages (the reconstruction boundary)
      'step/start'
      agent/request (config only) -> log request/header -> llm/stream (frozen)
      on final adapter-path or terminal in-band failure:
        'step/end'
        agent/request-error(original error, failure facts, immutable prior failures, signal)
        retry in the next numbered step or preserve the original error
      otherwise:
        'assistant/chunk'
        agent/step-result
        'assistant/message' (transformed content or empty success anchor after step-result rejection)
        schedule tool calls by ctx.tools.executionMode:
          exclusive -> one-call barrier
          parallel -> rolling pool, <= maxParallelToolCalls in flight; reclassify before start
          each start -> 'tool/call' -> ordered tools/pre-execute -> concurrent tools/execute
          each model-order result -> ordered tools/post-execute -> 'tool/result'
        append accepted tool-batch context after all recorded results, then steering
        agent/post-step
        'step/end'
        agent/turn-continuation
        agent/turn-stop (terminal policy)
        stop unless tools or continuation policy ask for another step
    'turn/end'
    checkpoint persistence and notify idle/running status

每个步骤都会组装有序提示词片段、工具 schema 和变量;未知引用会使该轮次失败。dsh-system-prompt 负责身份和角色设定,循环则提供 modelcwd提示词归属)。

工具执行阶段的上下文会在结果记录后稳定。steering中途引导agent/post-step 前排空;余留内容会成为排队输入。终止型 agent/turn-stop 在续跑判断和 steering 折叠后执行,在整个刷写期间保持最终决定权,并丢弃后续 steering同时保留排队提示词。

裁剪先于摘要;溢出重试必须取得持久进展。有界的瞬态重试在 agent/request-error 上组合;取消优先(压缩重试)。

失败边界

轮次是故障隔离边界。适配器故障会关闭步骤,并携带准确的故障事实进入 agent/request-error。重试会开启一个有编号的步骤;重试耗尽后,故障存入 turn/end。失败分片不会提交任何消息或工具。

其他故障使用 agent/error。取消和 dispose资源释放优先于恢复尚未分派的模型工具调用会收到合成的 tool/callABORTED 结果对,然后才出现 turn/endcancel() 会清空队列并中止活跃工作;资源释放会等待系统停稳后再注销。

每个会话事件都包围在轮次内。重新加载会保留中断的日志尾部,并用合成的 interrupted 轮次结束事件将其闭合。持久轮次关闭后的故障只通过 agent/error 报告,因为此时已没有安全的轮次内位置。每个轮次有一个 TurnEndReason;各变体由 TurnEndReasonMap 统一定义。

Agent 句柄

ctx.agents 拥有活跃 agent并返回 AgentHandle { agent, dispose() }。插件使用 send()steer()inject()cancel()whenIdle()。调用方 fiber、工厂提供方和消费方句柄通过同一个需等待完成的 disposer 共同拥有拆卸过程。

Agent 作用域

每个活跃 agent 都拥有一个作用域化的 agent.ctx。注册项会遮蔽全局项,只接收发往该 agent 的分派,并随 agent 一同撤销;系统会等待异步清理。CreateAgentOptions.setup(agentCtx) 在发布前完成组合。类型化解析器从合并后的 Events 签名和 scopeTarget 推导载体检查(语义门禁)。参见 agent 作用域subagent 组合AgentLoop 会传播其发起方;私有编排会派生 agent.session,其他身份则保持显式(决策)。

状态

会话日志

会话日志是真源。deriveMessages() 将会话事件投影为发送给模型的 Message[];原始 assistant/chunk 事件留在日志中,以保证回放和 UI 保真。回放、fork、恢复、transcript文本记录渲染、遥测和持久化均派生自同一个事件流。

模型可见 ⟺ 已记录:日志可以重建每个请求,包括由请求头会话前缀置于开头的 step/start 时消息,以及通过折叠 request/header 得到的请求头;开发期不变量会断言这一点(可重建性)。

持久性由插件负责。后端会缓冲同步的 session/event 通知;循环等待轮次结束检查点。SessionPersistence 直接存储 SessionEvent,并将元数据存入 SessionHeaderJSONL 默认采用带校验和的 ZstandardSQLite 则遵循同一契约。

插件所属的纯日志事件可选择使用 ctx.sessions.appendOutOfBand():事件会加入开放轮次,或获得一个平衡且已刷写的零步骤轮次。session/title 采用该路径并以后写覆盖方式折叠,同时记录源消息 seq 和来源信息。其首消息回退标题会立即产生;至多一个可选提供方可以异步替换该标题,而不会延迟 agent 响应。fork 会原样继承已记录的标题(决策)。

模型内容

消息包含类型化块(textreasoningtool-calltool-result),这些块从可合并扩展的 ContentBlockMap 派生;MessageSourceFinishReasonTurnTriggerTurnEndReason 也采用同一模式定义类型。新增块类型会将适配器、UI 桥接、压缩计价、token 计量和持久化协调成一项全仓库契约;回放计量类型见 token-meter.md

流式输出使用原始分片和 BlockAssembler。一次 LlmAdapter.stream() 调用代表一次提供方尝试;适配器报告事实,恢复逻辑则位于 agent/request-error。循环会记录分片及成功结果的来源信息和回放状态。远程适配器使用逐次读取空闲看门狗。只有当路由共用同一个适配器实例时,回放状态才会到达目标(契约)。

扩展与组合

功能模式

可替换功能通常拆分为接口/实现/消费方:接口拥有自己的 ctx 键和事件实现负责注册后端消费方通过工具或提示词暴露模型行为。Bash 是参考实现;功能图展示了所有包族。

有些服务边界会调整这一模板LLM大语言模型合并接口和消费方文件系统以策略包装提供方web、skill 和 subagent 拥有注册表。会话标题将内置回退方案与单提供方注册表和共享 LLM 辅助组件配对。subagent 可以通过 spawn 创建全新实例、fork 一个已完成轮次的前缀,或使用 ACPAgent Client Protocol子 agentsubagent.md)。

dsh-workspace-contextagent/session-prefix 上组合基线,并在通过 ctx.fs 发现嵌套变更后,于 tools/post-execute 追加这些变更;其决策记录了隔离方式。dsh-paths 负责共享路径。

组合包与应用

dsh-agent-spine-demo 组合默认主干,其中包含仅提供回退行为的会话标题;模型标题提供方保持按需启用(README)。dsh-tui-demo 负责终端;dsh-cli-demo 运行一个持久化的无界面轮次;dsh-acp-demo 添加保持 stdout 纯净的 ACPui/)。dsh-jsonrpc-agent 启动外部 cordis.ymlPython SDK 仅在没有显式配置时提供默认项,并驱动按行分隔的 JSON-RPCPython SDK)。部署保持为轻量叶节点,使用可替换后端和可选工具(examples/可运行接线图谱)。

新行为的归属位置

新行为应附加到已有文档记录的扩展点;修改已交付的循环时,必须同步更新本架构图。

目标 机制
添加模型提供方 ctx.llm 上注册适配器
添加面向模型的功能 ctx.tools 上注册工具schema 会进入提示词组装流程
添加命令执行 实现并注册 ctx.bash 后端
添加长时间运行或后台功能 ctx.tasks 上注册工作;通用 task_* 工具负责收集或停止
添加文件系统访问或策略 实现 ctx.fs 提供方,或监听 fs/* 策略事件
限制生成的进程 使用 ctx.sandbox 后端;消费方在生成进程前包装 argv
拦截提示词、请求、模型完成或失败、工具使用或续跑 监听相应的 agent/*tools/* 事件;使用串行 agent/turn-stop 实现单调终止
添加历史记录之外的会话稳定请求前缀 agent/session-prefix 上组合,每个循环实例一次;记录在请求头中
添加 UI 或编辑器集成 驱动 ctx.agents 并从 session/event 渲染
添加持久会话状态 添加一个 SessionEventMap 成员,并从日志渲染和回放
添加异步会话标题生成 ctx.sessionTitle 上注册唯一提供方
fork 活跃会话 使用 ctx.sessions.fork(source, boundary?, childSessionId?)
将工具、提示词片段或监听器限定到单个 agent 通过该 agent 的 agent.ctx 注册(参见 Agent 作用域)

扩展实操手册cookbook提供插件骨架和功能到服务边界的映射;分步指南涵盖工具LLM 适配器vendored 包

快速参考