DeepSeek Harness:连 Agent Loop 都能替换的插件架构

看到 DeepSeek Harness 的"一切皆插件",我最关心的是:到底能替换到哪一层?

增加一个工具,接入一个模型,还是连 Agent 的执行方式都能改?

顺着 dsh 的公开文档往下看,会发现模型适配器、工具注册表、会话日志,甚至 Agent loop 本身,都被放进了同一套插件组合机制。

开发者能够调整的范围,因此从"Agent 有什么能力",延伸到了"Agent 怎样运行"。这是理解 dsh 的起点,也是它最值得展开讲的地方。

一、执行循环也能替换

一个 Agent 的基本工作过程,可以画得很简单:接收输入,准备上下文,请求模型;模型提出工具调用,程序执行并记录结果,再把结果交给模型继续处理。

一次用户输入,可能在内部触发多次模型请求。Agent loop 负责组织这些步骤。

单看这个循环,并没有特别神秘的地方。dsh 值得关注的是:组织循环的组件,本身也是插件。

模型适配器、工具注册表、会话日志和默认执行循环,都可以通过配置组合与替换。它们共同依赖的插件底座是 Cordis。官方架构文档

这让扩展有了不同深度。增加工具,可以扩充能力;接入模型请求事件,可以调整请求行为;替换压缩组件,可以改变上下文处理方式。默认循环确实无法满足需要时,还可以实现自己的 Agent 驱动。

当然,能替换不代表可以忽略接口约定。新实现仍然需要正确处理输入、状态、取消和资源释放等问题。这里的价值在于,框架给出了可替换的位置,开发者不必把所有变化都塞进同一个核心实现。

连默认运行方式都保留扩展空间,是 dsh 插件架构最有辨识度的一点。

二、插件怎样正确退出

插件加载成功,只完成了一半。

它可能注册了工具,添加了监听器,又往提示词里贡献了一段内容。卸载时,这些注册也需要清理。否则,重新加载几次以后,旧监听器和重复注册就可能留在运行环境里。

Cordis 为此提供了依赖注入和生命周期机制。插件通过稳定的服务名使用能力,例如 ctx.llm、ctx.tools 和 ctx.sessions,通过依赖声明等待服务就绪。

工具、监听器和提示词片段等注册,则跟随所属插件的生命周期清理。Cordis 入门

这样,组件替换就有了明确的归属:谁注册,谁拥有,退出时由谁撤销。使用服务的插件,也不需要到处绑定某个具体实现。

这里的"可逆"有准确范围。撤销一个工具注册,不会自动撤销它已经修改的文件;释放运行资源,也不等于回滚所有外部操作。

这部分底层能力来自 Cordis。dsh 的设计价值,是把它贯穿到 Agent 的主要运行组件中。讨论它的创新,应该把这层来源讲清楚。

三、共享能力,分层装配

组件能替换以后,还要回答一个问题:这次替换影响谁?

dsh 使用 Profile、Agent preset 和作用域表达不同范围。把这些名字放回各自的位置,就容易理解了。

概念 主要职责
Profile 定义启动哪一套应用组合
Agent preset 定义创建 Agent 时使用的插件组合
Agent 实际工作的运行实例
Session 保存会话事件,提供模型历史的来源

Profile 是具名的启动组合。web、headless、sdk 等入口,通过同一个启动器加载不同组合,并应用配置覆盖。它不能直接等同于开发、测试、生产环境。应用启动文档

preset 更接近装配模板。同一套模板可以创建多个 Agent,也可以声明多套模板,供不同会话选择。加载了模板,不代表候选 Agent 已经全部启动。

已有 Agent 的组合保持稳定,修改后的模板供后续创建的 Agent 使用。这个约定能避免一次模板编辑,让正在执行的实例突然换掉整套能力。Agent preset 文档

作用域进一步控制注册的可见范围:可以提供宿主级公共能力,也可以只向特定 Agent 注册工具和监听器。不过,作用域本身不构成操作系统沙箱。作用域文档

因此,"共享"需要说具体。多个 Agent 可以复用插件代码和公共服务,同时保留各自的配置与会话历史。复用了同一份代码,不等于运行状态和模型上下文也合成了一份。

四、日志与上下文分开管理

这一点不如插件口号显眼,却直接影响系统能不能解释清楚自己的行为。

dsh 的 Session 使用仅追加的事件日志,再从日志中派生模型可见的消息历史。

发生过什么,与下一次让模型看到什么,可以分别管理。

一次工具返回的原始文本,可以保留在日志中;后续请求使用经过修剪的版本。较早的一段对话,也可以在模型可见的历史里被摘要替代,而原始事件仍然存在。

Session 文档将"模型可见即已记录"作为约束:模型请求中的内容,应当能够从日志重建。Session 文档

模型漏掉某个信息时,就有了更具体的检查方向:信息有没有进入会话?进入了原始日志,还是也进入了当前消息视图?中间是否发生过修剪或压缩?

屏幕上看得到一段内容,并不能充分说明模型当时也看到了它。

重建输入,也不保证重新调用模型会生成完全相同的输出。跨进程保留记录,则需要配置持久化后端;Session 组件本身使用内存存储。

这套设计给上下文处理留出了空间:既能控制当前输入长度,又能保留检查内容来源的依据。

五、判断与执行各司其职

"一切皆插件"不意味着所有插件都由模型挑选,也不存在每轮必须执行一遍的固定插件清单。

读取文件这样的工具,可以由模型选择。上下文压力检查、会话记录和执行策略,则有自己的程序触发点。

以原生工具调用为例,模型看到当前可见工具的名称、描述和参数结构。模型提出调用后,框架校验参数、执行允许/拒绝/询问策略,再分发到具体实现。工具执行文档

dsh 还区分了会话事件、Agent 事件和能力事件,供插件接入不同阶段的行为。扩展者需要选择合适的事件接口,遵守其分发与调用约定。

这条边界很重要。模型可以承担语义判断和内容生成,已经明确的执行约束则需要程序落实。不能只在提示词里写一句"请遵守规则",就认为框架已经完成了控制。

六、用压缩检验组合设计

架构最终要落到具体功能上。上下文压缩就是一个很好的观察点。

当会话越来越长,基础压缩实现会根据窗口容量、输出预算和预留空间判断压力。组合了工具结果修剪器以后,处理过程大致如下:

修剪器按规则缩短超大的工具文本结果,保留头尾并加入标记。这一步不调用模型。如果修剪后空间已经足够,就可以跳过摘要。工具结果修剪器

仍然过大时,才需要额外调用模型提炼较早历史,同时保留近期内容。压缩组件还要负责范围选择、结果验证和状态提交。基础压缩文档

这里能看出组合的价值:压力测量、规则修剪、模型摘要,各自承担明确职责。改变摘要方式时,可以复用已有的状态管理和校验机制,把定制集中在摘要实现上。

摘要毕竟会丢失细节。保留日志,提供了追查来源的条件,却不能保证模型压缩后仍然掌握全部信息。压缩也不等于提取跨会话的长期记忆,那需要另外设计存储、写入和检索链路。

最后,怎样看 dsh 的创新

我更看重的是这些机制组合起来后的结果。

核心运行组件可以替换,依赖和生命周期有统一管理,公共能力与局部配置能够分层,会话记录又为上下文变化保留了来源。开发者于是有机会调整 Agent 的运行方式,同时沿用已有的接口、记录和控制机制。

这里有来自 Cordis 的底层能力,也有 dsh 面向 Agent 场景作出的具体设计。将它们贯穿成一套可组合的运行架构,是 dsh 最值得研究的地方。

接下来值得观察的,是这套设计能否经受真实扩展的检验:换掉一个核心组件后,其他部分还能否沿着原有接口工作;加入新插件后,依赖、状态和退出行为是否仍然说得清楚。

这些问题,比插件数量更能说明架构的成色。

相关推荐
老李IT笔记33 分钟前
关掉设备上的 AI 扩展:两个键各管一层,配错了等于没配
人工智能·ios·智能手机
SL_staff33 分钟前
私有化低代码运维三重雷区:JVS开源栈中的Kafka/ES/RabbitMQ治理实践
java·低代码·全栈
yuniko-n34 分钟前
【算法】约瑟夫环问题
java·算法
李航198336 分钟前
DeepSeekAI建模三 - 实战建模一组柜子
人工智能·python·计算机视觉·ai·ai编程
javaDocker40 分钟前
1800 亿科技投入砸下去,多数机构平的只是服务器,不是能力
运维·服务器·人工智能·科技·研发效能·金融科技
郝亚军44 分钟前
manifest 中 `sha256` 与 `signValue` 的作用
java·开发语言·数据结构
AI天行健1 小时前
星宇智算无限画布如何参与节点式工作台的事实标准塑造
人工智能
譕痕1 小时前
stripe 实例
java·开发语言·stripe·checksession
AI视频工具指南1 小时前
文字怎么变成视频?同一地点的几个画面怎样接起来
人工智能·aigc·音视频