自学教程

DeepSeek Harness 服务与依赖

DeepSeek Harness 基于 Cordis 内核构建,采用一切皆插件的架构。插件不直接互相导入代码,而是通过服务(Service) 对外暴露能力;插件通过声明依赖来消费服务,内核自动解析依赖树、编排插件加载顺序,实现模块解耦、热插拔与可替换能力。

一、什么是服务

服务是插件对外提供的能力抽象,挂载在运行时上下文 ctx 上,是插件之间通信与能力调用的标准入口。

  • 每个服务对应一个唯一上下文键,例如 ctx.llm、ctx.tools、ctx.sessions、ctx.agentLoop,插件通过 ctx 访问服务,不需要硬编码引入其他插件源码。
  • 一个插件可以提供一个或多个服务;多个插件也可以实现同一份服务接口,运行时可直接替换,无需修改业务代码。
  • 服务封装实现细节:调用方只关心服务接口,底层实现可以随时更换,例如把模型后端从 DeepSeek API 切换到 Ollama,只更换提供 ctx.llm 的插件,其余插件代码不变。

Harness 内置核心服务

上下文键服务名称作用
ctx.llm大模型服务统一模型调用、流式消息封装,对接各类模型适配器
ctx.tools工具注册服务管理工具注册、参数校验、执行流水线
ctx.sessions会话服务会话日志、轨迹记录、会话分支与回放
ctx.agents智能体注册服务智能体实例管理与事件分发
ctx.agentLoopAgent 循环服务驱动智能体思考、工具调用的主循环

二、依赖的概念

依赖描述插件运行所需要的服务。插件通过 inject 声明依赖,告诉 Cordis 内核:本插件需要哪些服务就绪之后,才能启动。

  1. 依赖声明:插件在定义中声明需要注入的服务名称,内核自动收集全部依赖关系,构建有向依赖图。
  2. 自动排序:内核按照依赖拓扑顺序加载插件,被依赖的服务优先启动。A插件依赖B插件提供的服务,则B先挂载,A后挂载。
  3. 缺失依赖处理:如果依赖的服务不存在,插件加载失败,内核会抛出明确的依赖缺失提示,不会静默启动。
  4. 可选依赖:支持声明可选依赖,当对应服务存在时启用相关逻辑,不存在时插件依然可以正常加载,只是关闭对应能力。

依赖声明示例

// 插件声明依赖:需要 llm 和 tools 服务
export default definePlugin({
  inject: ['llm', 'tools'],
  setup(ctx) {
    // 此时 ctx.llm、ctx.tools 一定已经就绪
    ctx.tools.register({
      name: "demo_tool",
      description: "演示工具",
      schema: {}
    })
  }
})

三、服务与依赖的协作流程

  1. 读取配置:Harness 读取插件列表,加载所有插件元信息,收集每个插件的 inject 依赖声明。
  2. 构建依赖图:内核扫描每个插件对外提供的服务、以及所需要的依赖,生成拓扑图。
  3. 按拓扑顺序挂载:优先加载无依赖的底层插件,启动并注册服务;后续插件等待依赖服务就绪后执行 setup。
  4. 运行时调用:插件通过 ctx 使用已就绪服务,使用事件系统完成消息通信。
  5. 卸载与逆序销毁:卸载插件时按依赖反向顺序销毁,依赖方先卸载,提供服务的插件后卸载,保证不会出现服务中途丢失。

四、服务与依赖的典型使用场景

1. 替换底层能力

例如你希望更换模型后端:只需要启用另一个提供 ctx.llm 的插件,原有依赖 ctx.llm 的所有插件不需要修改代码,内核自动完成服务替换。

2. 按需启用插件

部分插件仅在安装对应服务后启用。如网页搜索插件声明依赖 ctx.llm,当LLM服务正常加载,搜索插件自动启用;没有LLM服务时,该插件直接跳过加载。

3. 多插件共用同一个服务

多个工具插件可以同时依赖 ctx.tools,向同一个工具注册表注册自定义工具,实现插件能力聚合。

五、依赖冲突与排查

  1. 循环依赖:A依赖B,B又依赖A,内核检测到环,直接终止加载并抛出报错。解决:抽离公共能力为独立服务,解除互相依赖。
  2. 服务版本冲突:多个插件要求同一个服务的不同版本。Harness 允许在配置中指定服务实现,选择单一提供者。
  3. 依赖名称拼写错误:inject 内的服务名和实际插件提供的服务键不一致,提示依赖缺失。检查服务名称大小写。
  4. 可选依赖误写为必选依赖:非核心能力写成必选依赖,导致整个插件无法启动,按需调整为可选依赖。

六、最佳实践

  1. 插件尽量只依赖抽象服务,不要直接依赖具体插件,保持实现可替换。
  2. 最小依赖原则:只声明运行必须的服务,减少依赖链路长度,提升启动速度,降低冲突概率。
  3. 服务保持接口稳定:自定义插件对外暴露服务时,尽量不随意修改接口,避免下游依赖插件报错。
  4. 开发调试时查看依赖图:Harness 提供依赖拓扑查看,可快速定位加载顺序、缺失服务、循环依赖。

七、小结

服务是 DeepSeek Harness 插件对外暴露能力的标准接口,依赖是插件对运行环境能力的需求声明。Cordis 内核基于服务与依赖自动管理插件加载顺序,实现模块解耦与灵活组合。理解服务与依赖,是开发自定义插件、组装和扩展Harness智能体能力的基础。

标签:

0 条笔记