☰
0基础深入理解DeepSeek Harness 架构【12】扩展点速查、ctx 键、十二个坑与资料出处
2026/10/8 2:08:07 网站建设 项目流程

《DeepSeek Harness 架构详解手册》全书面向零基础读者,从 Cordis 插件地基讲到轮次流程、会话日志、工具流水线,最后落到动手开发 Agent。本文把全书四个附录合在一起,是一份可以随时回查的速查表。

四个部分互不依赖,按需翻阅即可:

  • 附录 A|扩展点速查表:知道要做什么,反查该挂在哪。
  • 附录 B|核心 ctx 键速查表:写服务名时对照,避免拼错或搞混层级。
  • 附录 C|新手最常见的十二个坑:写完代码后自查一遍。
  • 附录 D|资料来源与核对说明:想知道某个说法的依据,或跟同事口径不一致时查。

其中附录 D 还专门记录了整理过程中发现的四处口径差异(事件数量、默认端口、两种「上下文」、以及事件记录与进入派生历史的区别)——这几处最容易在团队讨论时产生分歧。

附录 A 扩展点速查表

这张表回答一个问题:「我想加 X,应该挂在哪?」它是按官方架构文档的「新行为的归属位置」表与实操手册的「功能→机制」映射表合并整理而成。

A.1 按目标查机制

我想做的事挂在哪
添加模型提供方在ctx.llm上注册它的适配器
添加面向模型的能力在ctx.tools上注册;它的 schema 会自动加入提示词组装
让某个会话拥有不同的能力集合组装一个 agent preset;其中的服务行需要isolaterealm
添加 shell 执行注册ctx.shell后端;本地后端通过ctx.subprocessspawn 进程
添加持久化终端执行注册ctx.terminals后端和dsh-tool-terminal
添加用户命令在ctx.commands上注册;它无需模型轮次即可分派
管理后台任务在ctx.jobs上注册;job_*工具读取或停止任务
从外部 webhook 启动 Session在ctx.webhookRuntime上注册可信规则,并挂载提供方适配器
添加文件系统访问或策略注册ctx.fs提供方,或监听fs/*事件
限制所启动的进程使用ctx.sandbox后端;消费方在启动进程前包装 argv
拦截请求、工具或轮次使用相应的agent/*或tools/*事件;agent/turn-stopping会停止轮次
添加模型可见的上下文调用agent.inject();它会落到下一次获准的请求中
添加 UI 或编辑器集成驱动ctx.agents并从session/event渲染
添加 Web Client Chat 节点注册ConversationNodeDefinition+ keyed renderer
添加持久会话状态扩展SessionEventMap;从日志渲染和回放
生成会话标题注册唯一的ctx.sessionTitle提供方
管理同会话目标使用ctx.goals;通过agent/*续跑
在轮次边界 fork 会话ctx.agents.create({ sessionId, seed, meta: { parentSession, seedLength } })——只有经 agent-loop 发布的会话才会持久化
在新后端存储会话基于共享的句柄脚手架实现SessionPersistence(create/open/stat/list/export)
将注册项限定到单个 agent使用该 agent 的agent.ctx

A.2 按产品功能查插件机制

产品功能插件机制
钩子系统(用户级 + 项目级)agent/created、agent/pre-step、agent/request、tools/pre-execute、tools/post-execute、agent/turn-stopping上的监听器。dsh-hooks-claude-code/dsh-hooks-codex把钩子配置文件映射到这些扩展点
/goalctx.goals管理持久状态,dsh-goal-round-driver通过公共Agent调度同会话 Round
/loop在turn/end会话事件上followup()下一次迭代;或强制继续
动态工作流ctx.workflowEngine+ PTC 工作流引擎 +workflow工具
排队消息 + steering核心Agent.followup()/Agent.steer()
上下文压缩(自动 + 手动)ctx.compactionseam +dsh-compaction-basic。自动压力检查跑在串行agent/pre-step,溢出恢复跑在agent/request-error,手动调用方用同一个压缩服务
系统提示词可配置性ctx.systemPrompt.section(),支持排序与作用域局部覆盖
AGENTS.md(根目录)一个读取该文件的 section 提供方
AGENTS.md(子目录,按需触发)+ 文件变更通知从 watcher 或工具结果监听器调用agent.inject()
内置工具ctx.tools.register();schema 自动流入装配。dsh-tool-*系列(bash、fs、web、subagent、todo)是已交付的示例
ToolSearch / 渐进式披露当可见集变化时替换一个作用域化的ctx.tools.restrict()注册
工具截止时间 / 重试 / 指标用tools/execute包裹核心分发
最终工具结果指标 / 审计 / 捕获用tools/result观察不可变的权威结果
单调终端轮次策略从成功的终端工具调用ToolExecution.concludeTurn()
子进程沙箱(landlock / sandbox-exec)通过dsh-bash-sandbox使用ctx.sandbox后端;能力级别的拒绝用tools/pre-execute
权限系统 / AskUserQuestion从tools/pre-execute返回ask并通过ctx.approval应答;为普通用户提问注册一个独立的面向模型的 ask 工具
Plan mode@deepseek-ai/dsh-plan-mode:落日志的plan/mode状态、plan:policy引导段、/plan入口、经用户评审的exit_plan_mode出口。强制约束留在独立的沙箱/审批轴上
subagent 委派ctx.subagents提供方注册表(六个提供方)+dsh-tool-subagent向模型暴露一个已配置的提供方
MCP每个服务器一个插件:发现工具 →ctx.tools.register()
skill(技能)section + 工具注册;调用时通过inject()注入 skill 内容
记忆section 提供方 + 工具
定时任务(cron)插件注册面向模型的调度工具;定时器触发 → 空闲时followup(...),忙碌时inject()通知
UI(GUI;CLI 输出 JSONL)监听agent/assistant-stream的实时 chunk,并监听session/event的持久结算、边界与工具活动;输入 →followup()
遥测 / 可回放 tracesession/event→ JSONL;回放 =sessions.create(id, { seed })
模型适配器通过registerAdapter注册LlmAdapter子类
插件热重载每个注册都是一个ctx.effect,所以随仓库提供的 HMR 直接生效

A.3 所有事件一览(按分发模式分组)

模式事件用途
waterfallagent/pre-step拒绝或改写要进入步骤的消息。请求发出前的唯一拦截点
waterfallagent/request替换冻结的调用配置(换提供方/模型/推理强度/采样参数)
waterfallagent/request-error处理一次失败的模型请求尝试。返回{kind:'retry'}触发重试
waterfallllm/stream环绕每一次流式模型调用(重试、回放、路由)
waterfalltools/pre-execute允许/拒绝/取消/询问
waterfalltools/execute环绕分派:超时、重试、指标
waterfalltools/post-execute接受/替换/阻止 / 附加下文
waterfalltools/ptc-dispatch-log允许替换run_code子分派结果的日志副本内容
waterfallsystem-prompt/assemble专家级整体装配变换。返回值具有权威性
waterfallapproval/request一次性权限决策的分派
serialagent/createdagent 已就绪,可做每个 agent 的初始化。全部 await 完成前创建不算成功
serialagent/turn-stopping轮次即将关闭的终局检查点
parallelsession/flush等待的并行持久化检查点:每个监听器都跑,调用方 await 全部
emitagent/status状态在idle⇄running之间切换
emitagent/assistant-stream实时的助手流发布:start、chunk、end
emitagent/inbox/inserted·claimed·discarded跟踪单条消息的入队、领取、丢弃
emitagent/disposed·agent/erroragent 离开注册表 / 步骤或轮次出错
emitsession/created·session/disposed会话发布与离开
emitsession/event提交后的追加通知源。可回放数据都从这里读
emittools/change·tools/result工具集变化 / 观察冻结的最终结果
emitsystem-prompt/change·llm/adapters-updated提示词提供方变化 / 提供方拓扑变化
emitapi-session/*会话列表的活动、加入、移除、状态、错误
emitagent-preset/selected某个会话向它的持久日志提交了不同的 agent preset

附录 B 核心 ctx 键速查表

写插件时你最常做的事,就是在某个ctx键上注册东西。这张表按「你关心的领域」分组,列出最常用的键。完整清单见官方的能力图。

ctx 键角色你会用它做什么
核心四件套
ctx.agentscore创建/恢复/查找 agent;传播发起方(currentInitiator/withInitiator)
ctx.agentLoopbundle唯一的具体循环实现。扩展包不要依赖它,依赖ctx.agents
ctx.sessionscore创建会话、注册消息投影、fork、flush 检查点
ctx.toolscore注册工具、设置守卫、限制工具、按作用域查询 schema
ctx.systemPromptcore注册提示词段落、动态上下文、工具 schema 提供方、变量
ctx.llmseam注册模型适配器;直接发起一次模型调用;查询模型能力
执行环境
ctx.fsseam文件系统读写(本地/沙箱/远程)
ctx.subprocessseam启动进程(Bash、PTY、LSP、外部 subagent 都靠它)
ctx.shellseam面向模型的 shell 执行后端
ctx.terminalsseam持久化的交互式终端
ctx.sandboxseam进程沙箱:包装即将执行的 argv
ctx.sandboxPolicycore部署默认沙箱模式与工作区根目录
ctx.lspseam语言服务导航(只有四种标准化操作)
ctx.sshcore一条经过认证的 OpenSSH 连接及其远端提供方
安全与审批
ctx.approvalseam一次性权限决策的分派与应答
ctx.permissionPresetscore用户可见的权限预设切换
ctx.credentialsseam机密信息的引用。配置只携带引用,实际值归提供方所有;消费方按操作解析,所以轮换的凭据会在下一次请求就生效
ctx.authorizationseam授权流程注册(怎么拿到某份凭据)
ctx.deepseekAccountseamDeepSeek 账号。UI 使用方只接收不含 token 的状态
会话数据
ctx.sessionPersistenceseam把会话事件持久化到磁盘
ctx.sessionProjectionscore注册状态折叠单元;读单个类型化状态
ctx.sessionProjectionCachecore按会话持久保存投影检查点,加速恢复
ctx.sessionQueryseam会话的读取、过滤、追踪、搜索
ctx.sessionTitleseam会话标题生成
ctx.storage/ctx.storageDomainseam / core非会话存储的中枢/类型化持久状态
ctx.attachmentsseam持久的二进制附件存储(图片、文件)
ctx.spillStoreseam过大的工具文本的暂存与定位
协作与外部世界
ctx.subagentsseam子 agent 的提供方注册与延续编排
ctx.agentTeamscore实验性多 agent 协作(roster、mailbox、任务 DAG)
ctx.jobsseam后台任务的注册与控制
ctx.webseamweb 搜索与抓取的提供方注册
ctx.skillsseam技能目录
ctx.mcpResourcesseamMCP 资源访问
ctx.browserUse/ctx.computerUseseam浏览器操作/桌面自动化
ctx.webhookRuntimecore外部 webhook 触发会话创建
ctx.schedulecore定时消息
ctx.commandscore面向人的命令(无需模型轮次)
ctx.userQuestionsseam工具向人提问的通道
ctx.planModecore计划模式的协作状态
ctx.goalscore同会话目标
应用与界面
ctx.agentPresetscore按会话的 agent 组合(YAML preset)
ctx.webServercore注册 HTTP 路由
ctx.clientModulescore客户端插件图
ctx.connectioncore浏览器认证与共享 HTTP 请求分发
ctx.settingscore插件配置表单
ctx.configEditorcore在应用文件锁与 HMR 队列下持久化 profile 配置 patch
ctx.pluginManagercore当前 profile 的插件与组合包管理
ctx.otel/ctx.sessionTelemetryservice / seam共享的遥测上报通道

附录 C 新手最常见的十二个坑

这一章是按「错误认知 → 正确认知」的方式整理的。这些坑大多来自「用别的框架的经验硬套过来」,而不是来自不会写代码。

#常见错误认知正确认知
1「我应该去找核心抽象层/基类」这里没有特权内核。你要找的是挂载点——某个ctx键或某个事件。见第 1、10 章
2「patch 是深度合并,我只写要改的字段」patch 按 id 定位后整体替换config。你必须把想保留的字段全部重述。见第 2 章
3「我把系统提示词清空了,但模型还记得旧指令」空渲染文本会清除所有生效的系统节点。如果旧指令还在起作用,它大概不在系统提示词里——检查 user 消息和 skill 注入。见第 5 章
4「往内存里的 messages 数组塞东西,模型就能看到」模型历史是从日志派生的。要写事件,或者调用agent.inject()。见第 4 章
5「状态是 running 说明它正在处理我这条消息」running跨越整个驱动器排空区间,可能包含多个轮次。要知道单条消息的进度,看 inbox 通知和轮次事件。见第 3 章
6「我想阻止轮次结束,就返回一个 veto 值」agent/turn-stopping是 serial,没有next()。想阻止就 steer 一条消息,让机器重新读 inbox。见第 3 章
7「并发安全默认应该是开的吧」默认是exclusive(独占),而且 fail-closed。想并行要主动返回严格true。见第 6 章
8「我把结果内容替换掉了,就算保密了」内容替换是展示策略。程序仍然能拿到value。要保密就用block或替换value。见第 6 章
9「命令返回非零,所以工具该抛异常」非零退出是正常的领域结果,应该作为值返回,由渲染器解释。**只有基础设施故障才抛异常。**见第 6 章
10「重试应该在适配器里做」一次适配器调用 = 一次提供方尝试。适配器禁用库重试,重试是 agent 层的职责。见第 7 章
11「currentInitiator()有值,所以这次调用是被授权的」归因不等于授权。发起方方法只提供同进程内的因果归因。授权走审批 seam。见第 9 章
12「我加了一个新事件类型,读取时应该跳过不认识的事件」默认是必需:遇到不认识的、又没有ignorable标记的事件,必须拒绝重建。**宁可多报一次错,也不要静默恢复出一个被掏空的会话。**见第 4 章

附录 D 资料来源与核对说明

这份手册的内容全部来自官方仓库的文档。这一章说明资料来源、范围边界,以及我在整理过程中发现并处理的几处需要留意的地方。

D.1 主要资料来源

文档本手册用它来支撑
docs/architecture.zh.md整本书的骨架:Cordis 定位、profile 与组合包、核心包表、事件三域、轮次流程伪代码、会话日志、能力 seam、归属位置表
docs/cordis-primer.zh.md第 1 章:五个核心概念、五种分发模式、waterfall 语义、实践规则
docs/cordis-tutorial/index.zh.md第 10 章:七章动手教程的路径与准备工作
docs/agent-lifecycle.zh.md第 3 章:轮次与步骤的时序细节、失败与重试的处理位置
docs/tool-execution-pipeline.zh.md第 6 章:工具流水线的完整关卡顺序、PTC 与上下文附加
docs/capability-seams.zh.md第 8 章与附录 B:seam 列表、角色分类、各键的职责与消费方
docs/subsystems/core.zh.md第 3、4 章:Agent 句柄与全部方法、inbox、取消语义、两个类型模式、会话事件清单
docs/subsystems/session.zh.md第 4 章:事件表全字段、surface 与 surfaceOp、派生规则、持久化约定、fork
docs/subsystems/tools.zh.md第 6 章:ToolDefinition 全字段、schema DSL、执行类型、决策类型、UI 卡片词汇
docs/subsystems/system-prompt.zh.md第 5 章:PromptSection 全字段、三种更新方式、工具提供方结果
docs/subsystems/llm-streaming.zh.md第 7 章:内容块、StreamChunk、BlockAssembler、适配器约定、重试策略、TokenUsage
docs/subsystems/scope.zh.md第 9 章:ScopeKey、Scoped、Scope、ScopedLayers 与容器原语
docs/cookbook/extension-cookbook.zh.md第 1 章的门禁示例、第 10 章的实操模式、附录 A 的功能映射表
docs/cookbook/adding-a-tool.zh.md第 6、10 章:工具约定、PTC 设计建议、后台任务、UI 展示规则
docs/user/develop/basic/tool.zh.md第 10 章:最小可运行的工具示例与--patch开发方式
packages/boot/app-boot/README.zh.md第 2 章:启动五步、失败模式表、profile 与 runtime resolution
README.zh.md封面信息、运行方式、项目状态与许可

D.2 核对中发现并处理的四处地方

为了让这份手册不把读者带进沟里,以下几处我在整理时专门做了处理,并把结论写在这里。

#发现的问题处理方式
1**会话事件的数量存在两种口径。**核心包文档写「十三种核心事件变体」并列出十三项;而会话子系统的事件表里还登记了developer/message,以及由插件合并扩展的compaction/*、hook/*等第 4 章明确采用「核心十三种」的口径,并单独用提示框解释了两种数字的关系(一个说「核心」,一个说「当前全部」),避免读者以为文档自相矛盾
2**两个默认端口容易混。**README 里的 Web 默认地址是127.0.0.1:3080,而桌面应用文档里的默认端口是19387第 2 章专门加了一个提示框把两个数字并列说明,并指出 19387 是桌面端且可被 profile 覆盖,避免读者看到 19387 时误判为配置错误
3「上下文」一词在此框架中有两个完全不同的含义。ctx(Context)指插件共用的服务容器;而contextWindow指模型能处理的 token 上限术语表(第 11 章)为这两个词分别立条,并在 Context 条目下明确写出「不是『语言模型的上下文窗口』」。第 7 章也再做了一次区分
4**assistant/message与assistant/attempt的「是否进入模型历史」表述容易误读。**文档说法是后者「不添加模型历史」,前者「内容为空的也会跳过」第 3 章用一张两列表把两者并排对比,并特别标注「记录事件」与「进入派生历史」是两件独立的事——空内容的 assistant 消息仍然会记录,只是不进派生历史

D.3 范围边界

说明一下这份手册没有做什么,以免读者产生错误的期待:

  • **没有逐字段抄录所有生成型文档。**官方仓库里有一批由脚本生成的参考页(config-catalog、persistence-catalog、各子系统的cordis-surface代码块)。一个包里面就可能有几十页 JSDoc 原文。这些属于「查」而不是「读」,本手册只在需要说明机制时引用其结论,没有整体搬运。
  • **没有覆盖每一个实验性包。**实验性的浏览器操作、计算机操作、语音识别、Python 版 PTC 运行时等只在 seam 列表里点到,没有展开。
  • **没有给出可复制的完整插件工程。**本手册的代码片段用于说明「为什么这么写」,很多省略了 import 与辅助实现——官方也明确说了这一点。要跑起来,请走第 10 章的路径并参考官方教程。
  • **没有承诺长期有效。**项目处于开发者预览阶段,官方明确写着「未来将出现破坏兼容性的变更」。本手册描述的是这组文档所记录的架构契约与设计取舍——这部分相对稳定;具体字段名、命令参数请以你手上的代码为准。

D.4 一份实用的一句话总结

这套架构只讲了一件事:把「行为」和「策略」都变成可以挂载、可以替换、可以撤销的插件,然后用一条仅追加的日志保证「发生过什么」永远可查、可重建、可回放。

学它的顺序,也应该是这个顺序:先接受「日志是唯一真源」,再接受「一切皆插件」,最后学会问「这件事该挂在哪个扩展点上」。这三步走完,剩下的都是查表。


使用建议

如果你只想把一张纸贴在显示器边上,我建议是附录 C 的十二个坑,因为它覆盖面最广:
几乎每一条都对应着手册某一章里反复强调过、但在动手时又特别容易忘的点。

四份表都只是速查,想看某个为什么这么设计,回到正文对应的章节即可,那里有完整解释与配图。

内容整理自 DeepSeek Harness 官方仓库docs/architecture.zh.md及其引用的全部子系统、教程、
实操手册与核心包文档。官方项目处于开发者预览阶段,具体字段与命令请以你手上的代码为准。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询