$dshubuser@dshub:~/plugins$
  • 插件
  • 提交插件
  • 博客
服务与上下文:Cordis 如何共享能力而不绑定实现
2026/08/22

服务与上下文:Cordis 如何共享能力而不绑定实现

从 Service、Context 与声明合并出发,理解提供者、消费者和作用域如何连接 DeepSeek Harness 的能力。

一句话:服务提供稳定的能力名称,Context 提供查找入口,消费者只依赖名称而不依赖 provider 的文件或类。

这让“换一个实现”不再意味着修改所有调用方:组合层换 provider,消费者仍然读取同一个 ctx.<key>。

01 / 一个服务有三个角色

Cordis service definition provider and consumer roles connected through Context

一个可替换能力至少包含三类角色:

角色负责什么Cordis 中的落点
Service Definition规定能力名称和可调用接口TypeScript 类型与服务约定
Service Provider创建实例并注册名称Service 子类或注册器
Consumer使用能力完成自己的工作inject 加 ctx.service

只有一方存在时,它还不是完整的可替换能力。Provider 没有 consumer,没人使用;consumer 直接导入 provider,则替换点又消失了。

02 / Provider 如何进入 Context

import { Service, type Context } from '@deepseek-ai/cordis'

declare module '@deepseek-ai/cordis' {
  interface Context {
    greeter: GreeterService
  }
}

export class GreeterService extends Service {
  constructor(ctx: Context) {
    super(ctx, 'greeter')
  }

  greet(who: string) {
    return 'Hello, ' + who + '!'
  }
}

export function apply(ctx: Context) {
  ctx.plugin(GreeterService)
}

super(ctx, 'greeter') 把实例注册到名为 greeter 的服务槽位。注册属于当前 Fiber 的 effect,provider 卸载时,服务也会从作用域中移除。

declare module 只做 TypeScript 声明合并,不产生运行时代码。运行时接线来自 Service 的注册;声明合并的价值是让消费者获得 ctx.greeter 的类型检查。

03 / Consumer 只声明需要什么

Cordis Context resolving a named provider through root and isolated child scopes
import type { Context } from '@deepseek-ai/cordis'

export const name = 'consumer'
export const inject = ['greeter']

export function apply(ctx: Context) {
  console.log(ctx.greeter.greet('world'))
}

inject 确保 apply 运行时服务已经存在。Consumer 不需要导入 GreeterService,因此配置可以把 greeter 替换为另一种 provider。

如果依赖是可选的,用 ctx.get('greeter') 探测。ctx.get() 默认只返回 ACTIVE 服务;没有可用 provider 时返回 undefined,也不会创建依赖边。不要在未声明注入时直接读取 ctx.greeter,属性代理可能抛出缺少 inject 的错误。

04 / Context 不止一个平面

Cordis 的 Context 是服务解析、插件注册和事件分发的入口。根 Context 之下可以创建子 Context:

  • extend() 添加子作用域的元数据,但不修改父级。
  • isolate(name) 为某个服务创建独立作用域。
  • intercept(name, config) 为子树中的服务合并局部配置。

因此同一个服务名可以在不同组里指向不同实例。DeepSeek Harness 用这种思路支持 profile、agent preset 和隔离的能力组合。

05 / DSH 中的命名能力

DeepSeek Harness Context connecting tools llm agents and sessions services

在 Harness 架构中,工具注册表、LLM 适配器、Agent 注册表和会话存储都是通过 Context 连接的能力:

  • ctx.tools 管理工具注册与执行流水线。
  • ctx.llm 承载消息、流和模型适配器能力。
  • ctx.agents 管理 live Agent 与 agent/* 事件。
  • ctx.sessions 管理持久的 session event log。

Provider 可以替换,Consumer 仍然使用稳定服务名。这就是 capability seam 能够把一个 provider 选择扩散成产品级行为的原因。

下一步

  • inject:让依赖决定加载顺序
  • 事件:不知道谁在听,也能发通知
  • Cordis 在 DeepSeek Harness 里

来源:服务教程、Context 实现、Service 实现、Harness 架构。

全部文章

作者

avatar for DSH Research
DSH Research

分类

  • Agent 基础设施
01 / 一个服务有三个角色02 / Provider 如何进入 Context03 / Consumer 只声明需要什么04 / Context 不止一个平面05 / DSH 中的命名能力下一步

更多文章

动手:从 hello.ts 写出你的第一个 Cordis 插件
Agent 基础设施

动手:从 hello.ts 写出你的第一个 Cordis 插件

用一个函数插件和一份 cordis.yml,跑通 Loader、Context 与 Fiber 的最短路径。

avatar for DSH Research
DSH Research
2026/08/20
Cordis:五个核心概念,读懂一棵插件树
Agent 基础设施

Cordis:五个核心概念,读懂一棵插件树

用 Plugin、Context、inject、Events 与 Effect 五个概念,建立 Cordis 运行时的最小心智模型。

avatar for DSH Research
DSH Research
2026/08/19
生命周期与 effect:让 Cordis 注册可以回卷
Agent 基础设施

生命周期与 effect:让 Cordis 注册可以回卷

跟随 Fiber 从 PENDING 到 DISPOSED,理解 effect、disposer 与 HMR 如何共同管理插件副作用。

avatar for DSH Research
DSH Research
2026/08/24

邮件列表

加入我们的社区

订阅邮件列表,及时获取最新消息和更新

[dshub] [zsh]$ dshub ls$ dshub submit$ dshub blog
-- NORMAL -- ✓ 2026 dshub