# DeepSeek Harness 架构 [English](architecture.md) | 中文 **DeepSeek Harness SDK** 基于 Cordis 构建 agent harness(智能体框架)。设计准则很简单:**一切皆插件**。已交付的循环只是一个插件,并非拥有特权的内核。 ## 概览 一个 harness 对应一个 [Cordis](cordis-primer.md) 上下文。各包(package)会添加服务(`ctx.llm`、`ctx.tools`、`ctx.sessions`、`ctx.sessionTitle`)、类型化事件(`agent/request`、`tools/pre-execute`、`session/event`)和可释放的注册项。 `packages/core/` 汇集默认的 agent 流程;外围功能同样都是一等的 Cordis 插件。 ### 默认服务 | ctx 键 | 包 | 职责 | |---|---|---| | — | [`dsh-scope`](../packages/core/scope/README.md) | 作用域上下文注册原语(库) | | `ctx.sessions` | `dsh-session` | 内存中的事件溯源会话 | | `ctx.systemPrompt` | `dsh-system-prompt` | 有序提示词片段、工具 schema 和提示词变量 | | `ctx.tools` | `dsh-tools` | 工具注册表和[执行流水线](tool-execution-pipeline.md) | | `ctx.agents` | `dsh-agent` | 活跃 agent、委托创建、`agent/*` 事件和进程内发起方作用域 | | `ctx.agentLoop` | `dsh-agent-loop` | 实体 `Agent` 驱动器 | ### 功能服务 | ctx 键 | 包族 | 职责 | |---|---|---| | `ctx.llm` | [`llm/`](../packages/llm/README.md) | 适配器注册表和模型流式调用 | | `ctx.tokenMeter` | [`llm/token-meter`](../packages/llm/token-meter/README.md) | 感知回放的单实例请求压力和会话表面压力 | | `ctx.bash` | [`bash/`](../packages/bash/README.md) | 前台和后台命令执行 | | `ctx.sandbox` | [`sandbox/`](../packages/sandbox/README.md) | 同一执行环境内的进程限制(argv 包装、逐调用策略) | | `ctx.sandboxPolicy` | [`sandbox/`](../packages/sandbox/README.md) | 共享沙箱策略归属点 | | `ctx.codeRuntime` | [`code-runtime/`](../packages/code-runtime/README.md) | 执行模型编写的程序 | | `ctx.fs` | [`fs/`](../packages/fs/README.md) | 文件系统提供方原语和策略事件 | | `ctx.skills` | [`skill/`](../packages/skill/README.md) | skill(技能)提供方注册表和渐进式披露 | | `ctx.web` | [`web/`](../packages/web/README.md) | 搜索与抓取提供方注册表 | | `ctx.compact`,`ctx.toolResultPrune` | [`compact/`](../packages/compact/README.md)/[`compact-tool-result-prune`](../packages/compact/compact-tool-result-prune/README.md) | 摘要压缩(compaction);可选的无模型结果裁剪 | | `ctx.subagents` | [`subagent/`](../packages/subagent/README.md) | 具名委托提供方 | | `ctx.tasks` | [`tasks/`](../packages/tasks/README.md) | 后台任务注册表和通用 `task_*` 控制工具 | | `ctx.workflows` | [`workflow/`](../packages/workflow/README.md) | 脚本驱动的多 agent 编排 | | `ctx.sessionPersistence` | [`session-persistence/`](../packages/session-persistence/README.md) | 会话日志的持久存储 | | `ctx.sessionQuery` | [`session-query/`](../packages/session-query/README.md) | 实时优先的逻辑语料精确读取和关系追踪 | | `ctx.sessionTitle` | [`session-title/`](../packages/session-title/README.md) | 基于日志的回退标题和单个可选异步提供方 | ## 事件 事件构成服务的扩展 API;完整清单见[事件目录](cordis-catalog/events.md)和[生产方与消费方映射](event-producer-consumer.md)。 ### 事件域 - **会话事件**是追加到日志并通过 `session/event` 发出的持久事实。 - **Agent 事件**携带活跃 `Agent`,用于状态、提示词准入、请求塑形、验证和续跑。 - **功能事件**让所属服务边界无需导入循环即可附加策略和适配器。 ### 拦截语义 waterfall(瀑布式事件)的行为类似环绕中间件:监听器调用 `next()` 即表示委托,直接返回而不调用它则会否决或接管。完整规则见 [Cordis waterfall 语义](cordis-primer.md#cordis-waterfall-semantics)。 ## 默认循环生命周期 已交付的循环通过插件可见的服务和事件,持续处理从提示词到检查点的工作。 **会话**是仅追加日志。每个普通**轮次**领取一项已排队的 `send()` 输入;注入不领取输入。后续轮次会等待上一项已领取轮次的检查点,但可以与其共用同一个 `running` 区间([决策](../.agents/notes/implemented/simplification/2026-07-17-one-send-one-turn.md))。模型和插件停止轮次时,该轮次结束。一个**步骤**包含一次模型请求及其工具。下文([时序配套文档](agent-lifecycle.md))用引号标记持久事件。 未提供 id 时会生成 `-session-`;`sessionId` 用于恢复或创建会话,而 `resumeSessionId` 要求已有历史。恢复流程在发布前还原沿袭关系和委托深度。设置失败会发出 `agent-loop/config-start-failed`;拆卸过程保持静默。 ### 轮次流程 ```text 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` 负责身份和角色设定,循环则提供 `model` 和 `cwd`([提示词归属](../.agents/notes/implemented/architecture/2026-07-05-prompt-variables-and-tool-guidance-ownership.md))。 工具执行阶段的上下文会在结果记录后稳定。steering(中途引导)在 `agent/post-step` 前排空;余留内容会成为排队输入。终止型 `agent/turn-stop` 在续跑判断和 steering 折叠后执行,在整个刷写期间保持最终决定权,并丢弃后续 steering,同时保留排队提示词。 裁剪先于摘要;溢出重试必须取得持久进展。有界的瞬态重试在 `agent/request-error` 上组合;取消优先([压缩](../.agents/notes/implemented/architecture/2026-07-10-after-call-compaction-pressure-and-overflow-recovery.md)、[重试](../.agents/notes/implemented/architecture/2026-06-21-bounded-llm-request-recovery.md))。 ### 失败边界 轮次是故障隔离边界。适配器故障会关闭步骤,并携带准确的故障事实进入 `agent/request-error`。重试会开启一个有编号的步骤;重试耗尽后,故障存入 `turn/end`。失败分片不会提交任何消息或工具。 其他故障使用 `agent/error`。取消和 dispose(资源释放)优先于恢复;尚未分派的模型工具调用会收到合成的 `tool/call` 与 `ABORTED` 结果对,然后才出现 `turn/end`。`cancel()` 会清空队列并中止活跃工作;资源释放会等待系统停稳后再注销。 每个会话事件都包围在轮次内。重新加载会保留中断的日志尾部,并用合成的 `interrupted` 轮次结束事件将其闭合。持久轮次关闭后的故障只通过 `agent/error` 报告,因为此时已没有安全的轮次内位置。每个轮次有一个 `TurnEndReason`;各变体由 [TurnEndReasonMap](core-data-structures/session.md#why-a-turn-ended-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` 推导载体检查([语义门禁](../.agents/notes/implemented/process/2026-07-14-typescript-program-backed-semantic-gates.md))。参见 [agent 作用域](../.agents/notes/implemented/architecture/2026-07-08-agent-scope-contexts.md)和 [subagent 组合](../.agents/notes/implemented/feature/2026-07-12-subagent-persona-tool-filter-and-depth.md)。`AgentLoop` 会传播其发起方;私有编排会派生 `agent.session`,其他身份则保持显式([决策](../.agents/notes/implemented/architecture/2026-07-15-agent-initiator-scope.md))。 ## 状态 ### 会话日志 会话日志是真源。`deriveMessages()` 将会话事件投影为发送给模型的 `Message[]`;原始 `assistant/chunk` 事件留在日志中,以保证回放和 UI 保真。回放、fork、恢复、transcript(文本记录)渲染、遥测和持久化均派生自同一个事件流。 **模型可见 ⟺ 已记录**:日志可以重建每个请求,包括由请求头会话前缀置于开头的 `step/start` 时消息,以及通过折叠 `request/header` 得到的请求头;开发期不变量会断言这一点([可重建性](../.agents/notes/implemented/architecture/2026-07-05-reconstructable-requests.md))。 持久性由插件负责。后端会缓冲同步的 `session/event` 通知;循环等待轮次结束检查点。`SessionPersistence` 直接存储 `SessionEvent`,并将元数据存入 `SessionHeader`;JSONL 默认采用带校验和的 Zstandard,SQLite 则遵循同一契约。 插件所属的纯日志事件可选择使用 `ctx.sessions.appendOutOfBand()`:事件会加入开放轮次,或获得一个平衡且已刷写的零步骤轮次。`session/title` 采用该路径并以后写覆盖方式折叠,同时记录源消息 seq 和来源信息。其首消息回退标题会立即产生;至多一个可选提供方可以异步替换该标题,而不会延迟 agent 响应。fork 会原样继承已记录的标题([决策](../.agents/notes/implemented/feature/2026-07-21-log-backed-session-titles.md))。 ### 模型内容 消息包含类型化块(`text`、`reasoning`、`tool-call`、`tool-result`),这些块从可合并扩展的 `ContentBlockMap` 派生;`MessageSource`、`FinishReason`、`TurnTrigger` 和 `TurnEndReason` 也采用同一模式定义类型。新增块类型会将适配器、UI 桥接、压缩计价、token 计量和持久化协调成一项全仓库契约;回放计量类型见 [token-meter.md](core-data-structures/token-meter.md)。 流式输出使用原始分片和 `BlockAssembler`。一次 `LlmAdapter.stream()` 调用代表一次提供方尝试;适配器报告事实,恢复逻辑则位于 `agent/request-error`。循环会记录分片及成功结果的来源信息和回放状态。远程适配器使用逐次读取空闲看门狗。只有当路由共用同一个适配器实例时,回放状态才会到达目标([契约](core-data-structures/llm-streaming.md))。 ## 扩展与组合 ### 功能模式 可替换功能通常拆分为**接口/实现/消费方**:接口拥有自己的 `ctx` 键和事件,实现负责注册后端,消费方通过工具或提示词暴露模型行为。Bash 是参考实现;[功能图](capability-seams.md)展示了所有包族。 有些服务边界会调整这一模板:LLM(大语言模型)合并接口和消费方;文件系统以策略包装提供方;web、skill 和 subagent 拥有注册表。会话标题将内置回退方案与单提供方注册表和共享 LLM 辅助组件配对。subagent 可以通过 spawn 创建全新实例、fork 一个已完成轮次的前缀,或使用 ACP(Agent Client Protocol)子 agent([subagent.md](core-data-structures/subagent.md))。 `dsh-workspace-context` 在 `agent/session-prefix` 上组合基线,并在通过 `ctx.fs` 发现嵌套变更后,于 `tools/post-execute` 追加这些变更;其[决策](../.agents/notes/implemented/feature/2026-06-24-workspace-context.md)记录了隔离方式。`dsh-paths` 负责共享路径。 ### 组合包与应用 `dsh-agent-spine-demo` 组合默认主干,其中包含仅提供回退行为的会话标题;模型标题提供方保持按需启用([README](../packages/examples/agent-spine-demo/README.md))。`dsh-tui-demo` 负责终端;`dsh-cli-demo` 运行一个持久化的无界面轮次;`dsh-acp-demo` 添加保持 stdout 纯净的 ACP([ui/](../packages/ui/README.md))。`dsh-jsonrpc-agent` 启动外部 `cordis.yml`;Python SDK 仅在没有显式配置时提供默认项,并驱动按行分隔的 JSON-RPC([Python SDK](../python/README.md))。部署保持为轻量叶节点,使用可替换后端和可选工具([examples/](../examples/AGENTS.md)、[可运行接线](cookbook/extension-cookbook.md#runnable-wirings)、[图谱](graph-atlas.md))。 ### 新行为的归属位置 新行为应附加到已有文档记录的扩展点;修改已交付的循环时,必须同步更新本架构图。 | 目标 | 机制 | |---|---| | 添加模型提供方 | 在 `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)](cookbook/extension-cookbook.md)提供插件骨架和功能到服务边界的映射;分步指南涵盖[包](cookbook/adding-a-package.md)、[工具](cookbook/adding-a-tool.md)、[LLM 适配器](cookbook/adding-an-llm-adapter.md)和 [vendored 包](cookbook/adding-a-vendored-package.md)。 ## 快速参考 - [术语表](glossary.md)中的领域术语 - [core-data-structures/](core-data-structures/core.md) 中的类型定义 - [事件](cordis-catalog/events.md)中的准确事件与服务签名 - [服务](cordis-catalog/services.md)目录 - [包索引](../packages/README.md)中的包契约 - [Agent Note(agent 决策记录)](../.agents/notes/README.md)