DeepSeek Harness 拦截扩展点深度解析:基于类型化 Decision 的 Agent Hook 事件面设计
DeepSeek Harness 拦截扩展点深度解析基于类型化 Decision 的 Agent Hook 事件面设计【免费下载链接】deepseek-harnessDeepSeek Harness: Everything is a Plugin.项目地址: https://gitcode.com/gh_mirrors/de/deepseek-harness本文是 DeepSeek Harness 的 Agent Note 解读系列之一源自 .agents/notes/implemented/feature/2026-06-30-interception-extension-points.md。DeepSeek Harness 以「Everything is a Plugin」为核心理念通过 Cordis 事件体系把 Agent 生命周期全面插件化。本文聚焦其 hooks 子系统的地基——一组类型化、分权、可组合的拦截扩展点agent/*生命周期事件与tools/*五阶段工具执行管道。读完本文你将理解「原生 hook 即普通插件」这一设计重构的本质掌握PreStepDecision/PreToolDecision/PostToolDecision等类型化 Decision 的语义边界以及循环agent-loop与工具注册表dsh-tools之间如何各司其职并能在真实插件中直接复现这套拦截逻辑。一、背景与核心重构原生 Hook 不是「包」而是事件 API在 DeepSeek Harness 中hooks 子系统的设计起点是一个关键的思想重构「原生 hooks」并不是一个独立的软件包。一个原生 hook 本质上就是一个订阅了权威生命周期事件的普通 Cordis 插件而 Claude Code / Codex 的桥接层dsh-hooks-claude-code/dsh-hooks-codex只是把外部 shell hook 协议翻译到同一套事件 API 上的翻译器translator。这意味着一个重要的能力结论任何桥接层能做的事普通插件都能直接做而且做得更强——没有序列化边界、拥有完整的ctx、返回类型化typed结果。这一结论决定了本文后面所有事件签名的设计取向事件 API 必须「强大且类型完备」而不是围绕外部协议的兼容性打转。该设计还依托另一个前置约定.agents/notes/implemented/architecture/2026-06-30-event-domain-semantics.md 中提出的三域语义session 是事实日志、agent 是实时事件通道、tools 是工具注册表与执行管道以及类型化 Decision 惯用法。本文中的扩展点正是把这两条规则落实到 Agent 生命周期上的产物。二、事件面总览三类权威泾渭分明决策的核心是把拦截面拆成三种互相隔离的权威类型避免「给所有扩展同样的能力」带来的越权问题类别代表事件拥有的能力不能做的事可变换的策略瀑布waterfallagent/pre-step、tools/pre-execute、tools/post-execute返回扩展点专属的类型化 Decision 联合允许 / 拒绝 / 改写不得拥有与自身阶段无关的变更通道环绕派发控制around-dispatchtools/execute包装器用next()委托核心派发返回规范化结果不能移除exec.signal只读通知observe-onlyagent/session-start、tools/result、agent/turn-stopping接收不可变快照观察生命周期不能改变最终结果把各阶段混为一谈的坏处是双重的插件会获得它们根本不需要的变更通道同时「终局性」会依赖监听器的注册顺序。而上述划分让每个阶段只有一种权威策略瀑布的终局性由 Decision 的类型联合天然决定与监听器顺序解耦。三、Agent 生命周期事件dsh-agent3.1agent/session-start纯通知不能阻塞启动签名agent/session-start({ agent, source })触发时机turn 1 之前恰好发射一次。SessionStartSource取值startup全新创建或 fork 创建、resume重载持久化会话clear/compact为预留值。关键约束这是纯通知不能阻塞启动。这是一个刻意的设计缺口——桥接层在这里只负责「记日志 / 注入上下文」不负责「把关启动」。需要种入上下文的监听器应调用agent.inject()。3.2agent/pre-step每个提议步骤前的策略瀑布签名agent/pre-step({ agent, messages, turn, step, signal }, next) → PreStepDecision触发时机在循环原子地取走其独占收件箱批次inbox batch之后、每个被提议的步骤执行之前。载荷说明载荷携带请求的turn、step以及取消信号signal。被退役的PreStepContext字段直接并入载荷见 .agents/notes/implemented/architecture/2026-08-06-agent-event-payload-objects.md当工具延续tool continuation没有新的介入输入时messages为空数组。两种返回enter返回完整消息批次含监听器贡献的当前请求上下文步骤正式开启reject不开启任何步骤已认领的消息保持被移除状态不会回滚到收件箱。源码佐证在 packages/core/agent-loop/tests/interception.spec.ts 中agent/pre-step用例验证了坐标上报——初始提示与工具延续分别得到{ turn: 1, step: 1, messages: 1 }与{ turn: 1, step: 2, messages: 0 }正好对应「无介入输入的工具延续提交空批次」的约定同一测试还断言传入监听器的message及其content均被Object.isFrozen冻结证明输入身份不可变。3.3agent/turn-stopping自然停止边界的等待式通知在自然停止边界处该事件是**被等待awaited**的通知。需要再走一步的监听器调用agent.steer()并携带显式标明来源的、面向模型的内容循环随后重新读取 outbox决定继续推进还是关闭本回合。四、工具管道每个阶段只拥有一种权威每一次工具调用都严格遵循如下七段管线tools/pre-execute → guards → tools/execute → dispatch → tools/post-execute → ToolDefinition.finalizeContent → tools/result在策略开始之前注册表会完成三件事快照调用者输入、物化并冻结参数、分配不透明 token同时快照可见定义的 final-content 回调。嵌套调用只携带父 token执行身份identity不可变只有signal允许在派发期间发生变化。因此日志、UI 与工具本体三者看到的「执行的是什么」完全一致。4.1tools/pre-execute可扩展的瀑布闸门PreToolDecision三选一allow放行、deny拒绝、ask询问。deny会跳过tools/execute与核心派发ask通过可选的审批接缝ctx.approval解决只有allowed-once继续穿过 guards 与派发拒绝、取消、通道不可用、缺少审批服务、或无 agent 的调用全部归一化为规范化拒绝。无论决议结果如何都会进入后置策略post-policy抛异常的监听器最终归一化为失败结果。4.2ctx.tools.guard()同步、作用域感知的终局守门员安装在整个 pre-execute 瀑布之后。守卫只能deny或abstain弃权永远不能强制放行——这样监听器顺序无法复活一个被最终不变式final invariant禁止的操作。4.3tools/execute环绕派发瀑布面向超时timeout、重试retry、指标metrics插件。包装器用next()委托核心派发可以在委托前替换并恢复必需的exec.signal但不能移除它接收的是已归一化的权威成功 / 失败结果对抛异常或未知工具同样适用。包装器自行构造的「成功」会短路派发并经解析后的输出声明output declaration重新归一化。4.4tools/post-execute检查 / 变换瀑布PostToolDecision的能力集accept接受block携带反馈阻塞replace替换展示内容presentation content或权威值canonical value附加additionalContexts。值替换会重新校验并重算展示内容内容替换保留程序化值且不是机密性边界。返回的 Decision 是官方支持的变换通道。4.5ToolDefinition.finalizeContent工具自有的末段内容不变式可选的、同步的、纯内容边界的回调在调用创建时与可见定义一同快照。在注册表完成规范化、并对候选结果含绕过后续瀑布的 pre-/around-/post- 监听器失败、以及快照其他结果字段时发现的错误做无损快照之后恰好运行一次。可替换content或返回undefined保留原样但不能改写isError、结构化错误身份、上下文或展示元数据。价值在于工具在这里强制自己的末段内容不变式而不必把策略失败降级为更弱的 block 决策。4.6tools/result同步、受控的结果通知在每一次变换、无损 JSON 物化以及外层错误边界之后触发。收到同一个冻结的执行身份以及权威结果的不可变快照观察者失败按监听器隔离不能改变或拒绝ToolRuntime.execute()返回的结果。4.7 归一化边界错误永不逃逸出回合核心派发与工具本体都位于归一化边界之内工具抛错、监听器抛错、非法权威值、渲染器 / 投影器失败、非 JSON 展示、身份形状失败——全部归一化为 JSON 安全的isError结果而不是逃逸出回合。因此post-execute 监听器可以检查「抛了异常的工具」定义自有的 final content 不变式同时覆盖外层管道失败与候选物化失败最终观察者看到的是执行局部的权威值 会话日志恰好能持久化的展示字段。权威值与投影、持久化规则由 .agents/notes/implemented/architecture/2026-07-20-canonical-tool-output-contract.md 承载。五、三个承重load-bearing的循环决策在每个被提议的步骤运行 pre-step 策略。循环在首次认领与决策之前就打开回合因此reject关闭的是一个「有记录但无步骤、无模型可见消息」的受阻回合工具延续无新认领输入时仍提交空批次允许按请求的上下文生产者把日志消息追加到该精确请求上。enter时循环打开步骤并在请求推导前把返回批次作为user/message事件追加。依据 one-send-one-turn 简化每个被认领的后续消息仍是其回合内唯一的直接提示。post-tool 的additionalContexts与异步注入进入活动批次 FIFO在该批次落定时追加。content/feedback塑造execute()返回的结果但每个 context 都是独立的、带来源的user/message单个步骤或复合工具可能产生多个。若立即追加会得到result(c1) → context → result(c2)的穿插序列或让嵌套 context 出现在其外层 result 之前破坏「工具调用/结果相邻」的不变式。为此ToolRunContext.deferContext()在失败路径上收集嵌套派发的 contextexecute()在ToolExecutionResult上暴露有序数组循环把它与执行期间产生的agent.inject()调用放入同一个 FIFOFIFO 在批次落定时、每一条已记录 result 之后追加——包括在被打断的回合关闭之前。被接受的外层调用在 decision context 之前保留延迟 context被阻塞的外层调用丢弃延迟 context只暴露阻塞决策显式提供的 context。停止中的监听器通过 steering 通道请求续跑因此下一步循环顶部排空drain时会把这次续跑记录为同回合内下一步的 steering——是 next-step 而非 next-turn 的提示。六、边界什么不属于这套扩展点hook/*会话事件持久化的 hook 调用日志不属于Service Definition 包而归属于dsh-hook-protocol——因为原生插件使用类型化 Decision根本不需要外部 hook 日志。原生插件集成测试 packages/core/agent-loop/tests/interception.spec.ts 通过真实循环组合这些扩展点全程没有任何hook/*协议。CompactionPreCompact/PostCompact、Notification、以及 Codex 的PermissionRequest都排除在本决策之外。ask决议通过 审批接缝 以ctx.approval解决终态单调停止由工具结果数据表达而agent/turn-stopping是引导下一步的最后机会。七、被否决的备选方案把 pre-tool 输入改写并入本扩展点集合否决。理由是一个一致性问题——审计、历史与 UI 展示读的都是执行前记录的tool/call.arguments在身份创建前一次合法的改写必须同时更新历史、审计、展示与执行四者。该契约由 pre-tool input-rewrite 提案 单独拥有不应由扩展点隐式承担。在扩展点旁同时声明持久化hook/*会话事件否决。原生插件直接使用类型化 Decision、完全不产生 hook 日志集成测试已证明因此持久化日志属于 hook-protocol 库而非扩展面。八、后果与落地验证最终形态是一套统一类型化但权力分级的拦截面hooks 返回 Decision、执行包装器做 wrap、终局守卫只能 deny、最终观察者只能 observe。职责划分清晰循环agent-loop拥有session-start、pre-step 认领结算、post-tool 上下文缓冲、停止stopping。dsh-tools拥有身份密封identity sealing与五阶段执行管道。契约文档化位置docs/architecture.md、各包 README、docs/subsystems/core.mdinterception-decisions 一节以及 docs/subsystems/tools.mdtool structures 一节。ACP 桥接层会把初始 pre-step 拒绝导致的「无步骤回合」结算为end_turn而 hook 驱动的快照则端到端验证桥接层的可观察行为。对插件作者而言这套设计的实操含义可以浓缩为一张自检清单要放行或拒绝写agent/pre-step/tools/pre-execute返回 Decision要包裹派发做超时与重试写tools/execute包装器要校验或变换结果写tools/post-execute要强制工具自身的内容不变式用ToolDefinition.finalizeContent要观察而不得干预订阅agent/session-start/tools/result。记住每条原则对应的权威类型就能在保持循环与管道不变式的前提下安全地把任何外部 hook 协议「翻译」为原生插件能力。【免费下载链接】deepseek-harnessDeepSeek Harness: Everything is a Plugin.项目地址: https://gitcode.com/gh_mirrors/de/deepseek-harness创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

相关新闻

MicroPython RP2 端口 rp2.Flash 类详解:SPI Flash 的低层访问、块协议实现与分区配置

MicroPython RP2 端口 rp2.Flash 类详解:SPI Flash 的低层访问、块协议实现与分区配置

MicroPython RP2 端口 rp2.Flash 类详解:SPI Flash 的低层访问、块协议实现与分区配置 【免费下载链接】micropython MicroPython - a lean and efficient Python implementation for microcontrollers and constrained systems 项目地址: https://gitcode.com/gh…

2026/9/20 20:43:05 阅读更多 →
UI-TARS 桌面版完整上手指南:用自然语言让电脑自动完成点击和填表

UI-TARS 桌面版完整上手指南:用自然语言让电脑自动完成点击和填表

UI-TARS 桌面版完整上手指南:用自然语言让电脑自动完成点击和填表 【免费下载链接】UI-TARS-desktop The Open-Source Multimodal AI Agent Stack: Connecting Cutting-Edge AI Models and Agent Infra 项目地址: https://gitcode.com/GitHub_Trending/ui/UI-TARS…

2026/9/20 20:43:05 阅读更多 →
基于CA-PIC/MCC的HIPIMS靶面动态蚀刻仿真方法

基于CA-PIC/MCC的HIPIMS靶面动态蚀刻仿真方法

简介:面向高功率磁控溅射研究与等离子体仿真的动态蚀刻模型资料,结合元胞自动机与PIC/MCC方法,精准模拟阴极在强电离放电下的蚀刻演变,形貌模拟误差仅0.8%,适用于科研人员、物理仿真工程师及等离子体材料加工方向研究生…

2026/9/20 20:43:05 阅读更多 →

最新新闻

Agent技能库设计指南:从工具封装到智能编排的完整实践

Agent技能库设计指南:从工具封装到智能编排的完整实践

1. 先把“agent-skills”拆开看:它到底在解决什么问题这两年只要做 Agent 相关项目的人,基本都会遇到一个很尴尬的现状:模型能力越来越强,可每次落地一个新场景,还得从头把工具、流程、边界条件一点点喂给模型。今天写…

2026/9/20 21:21:33 阅读更多 →
MMPose 关键点半自动标注:5 步跑通实战

MMPose 关键点半自动标注:5 步跑通实战

MMPose 关键点半自动标注:5 步跑通实战 【免费下载链接】mmpose OpenMMLab Pose Estimation Toolbox and Benchmark. 项目地址: https://gitcode.com/GitHub_Trending/mm/mmpose 数据集到 5000 张还在一张张手标?单人 17 个关键点加上框和分割&am…

2026/9/20 21:21:33 阅读更多 →
Phoenix Contexts 入门:用 Elixir 模块封装数据访问与业务逻辑

Phoenix Contexts 入门:用 Elixir 模块封装数据访问与业务逻辑

Phoenix Contexts 入门:用 Elixir 模块封装数据访问与业务逻辑 【免费下载链接】phoenix Peace of mind from prototype to production 项目地址: https://gitcode.com/gh_mirrors/ph/phoenix 本指南介绍 Phoenix 框架的核心设计概念 —— Contexts&#xff…

2026/9/20 21:21:32 阅读更多 →
Atlas 300V AI推理加速卡:YOLO模型从零部署与性能调优实战

Atlas 300V AI推理加速卡:YOLO模型从零部署与性能调优实战

1. 这块“运算加速卡”,到底解决了什么问题先给你吃一颗定心丸:Atlas 300V 24G 不是我们常说的那种跑训练的大显卡,它是一张面向推理场景的专用加速卡,官方定位是数据中心和边缘侧的人工智能推理。很多人第一次看到“24G”这个数字…

2026/9/20 21:21:32 阅读更多 →
ComfyUI 工作流中文合集:16 个预设模板,导入即可出图

ComfyUI 工作流中文合集:16 个预设模板,导入即可出图

ComfyUI 工作流中文合集:16 个预设模板,导入即可出图 【免费下载链接】ComfyUI-Workflows-ZHO 我的 ComfyUI 工作流合集 | My ComfyUI workflows collection 项目地址: https://gitcode.com/GitHub_Trending/co/ComfyUI-Workflows-ZHO ComfyUI-Wo…

2026/9/20 21:21:32 阅读更多 →
AI漫剧制作工具全攻略:从一站式工作台到量产变现

AI漫剧制作工具全攻略:从一站式工作台到量产变现

2026年了,漫剧在短视频赛道上已经不是新鲜词。所谓漫剧,就是用动态漫画的形式讲一个短剧故事,单集1到3分钟,强冲突、快反转,剧情密度比传统动画高一截,特别适合碎片化刷视频的用户。以前做漫剧是专业团队的…

2026/9/20 21:20:31 阅读更多 →

日新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/20 0:00:46 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/20 0:00:46 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/20 0:00:46 阅读更多 →

周新闻

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

Flutter for OpenHarmony游戏卡片渐变背景实战:从原理到性能优化

直接铺开项目本身吧。这几个月我一直在折腾一件事:用Flutter给OpenHarmony做一款游戏集合类的App,说白了就是把若干小游戏塞进一个壳里,用统一入口分发。这个方向本身不算新鲜,真正让我花了不少心思的,是首页那堆游戏卡…

2026/9/20 0:00:46 阅读更多 →
Word表格编号全攻略:从列表编号到题注交叉引用

Word表格编号全攻略:从列表编号到题注交叉引用

写Word文档,最让人头疼的往往是那些“看起来不起眼”的小问题。比如表格编号这事:今天在表后面多加了两个空白行,明天给客户交稿前发现整个章节的编号全部错位,光是挨个改序号就能耗掉大半个下午。我前阵子帮人整理一份上百页的技…

2026/9/20 0:00:46 阅读更多 →
从第一个站到第二个站:独立开发者的静态网站选型与落地实践

从第一个站到第二个站:独立开发者的静态网站选型与落地实践

1. 项目概述1.1 核心需求解析做独立开发者这几年,说实话,第一个网站上线的那天晚上我兴奋得没睡着。但等它跑了半年,流量惨淡、功能臃肿、代码自己都懒得看第二遍之后,我才慢慢琢磨明白一个道理:第一个网站是练手&…

2026/9/20 0:00:46 阅读更多 →

月新闻

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能

持续集成 流水线自动化与 声明式交付 实践:原型怎样变成可用功能分类:[AI/大模型]细分主题:AI 增强型 CI/CD 流水线自动化与 GitOps 实践:Agent 工作流、工具调用与任务拆解:从原型到生产的验收清单很多团队在尝试用大…

2026/9/19 23:01:36 阅读更多 →
容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场

容器编排 生产环境运维与排障实战:复盘记录怎样真正派上用场分类:[工程技术]细分主题:Kubernetes 生产环境运维与排障实战:可复制的项目复盘模板与决策记录大部分团队的事故复盘报告,最后都变成了躺在 Confluence 或钉…

2026/9/19 17:50:38 阅读更多 →
容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步

容器 容器化技术与镜像安全管理:核心链路应该先拆哪一步分类:[工程技术]细分主题:Docker 容器化技术与镜像安全管理:核心链路的逐步实现与关键代码取舍面对一个积累了五六年历史包袱的单体架构应用(包含 Web 接口、后台…

2026/9/19 23:35:34 阅读更多 →