同一个服务如何让不同插件组看到不同实例?背后是 Cordis 的**服务隔离(service isolation)**与 **agent 作用域(scope)**机制。
服务隔离:isolate
cordis.yml 支持服务隔离:同一个服务可以有多个实例,不同插件组看到不同实例。关键词是 isolate 配置,配合 group 插件把插件分成组。
1# 文件路径:scratch-plugin/cordis.yml
2# 定义两个插件组 group-a 与 group-b,各自隔离一份 shell 服务
3- id: group-a
4 name: '@deepseek-ai/cordis-plugin-group'
5 group: true
6 isolate:
7 shell: true # 让本组内的 shell 服务独立实例化
8 config:
9 - name: '@deepseek-ai/dsh-bash-local'
10 config:
11 timeoutMs: 5000 # group-a 的 Bash 超时 5 秒
12 - name: './src/plugin-a.ts'
13
14- id: group-b
15 name: '@deepseek-ai/cordis-plugin-group'
16 group: true
17 isolate:
18 shell: true
19 config:
20 - name: '@deepseek-ai/dsh-bash-local'
21 config:
22 timeoutMs: 60000 # group-b 的 Bash 超时 60 秒
23 - name: './src/plugin-b.ts'
plugin-a 和 plugin-b 各自看到自己组内的 Bash 实例,互不影响。group-a 的 Bash 命令超时 5 秒,group-b 的超时 60 秒,两边互不知道对方存在。
为什么需要隔离:不同任务对同一能力的需求可能完全不同。隔离让同一份服务按组配置、按组生效,而不是全局一刀切。
作用域:scope
scope 是按 agent(智能体)划分的注册单位。一项贡献(工具、提示词段、变量、限制、监听器)要么是全局的,要么归属于恰好一个 scope key。
| 概念 | 含义 |
|---|---|
| scope | 按 agent 划分的注册单位;只有两层,采用扁平结构 |
| scope key | scope 的不透明标识;一个活跃的 agent 就是其自身 scope 的 key |
| agent.ctx | agent 的带作用域上下文,注册既有 scope 可见性,生命周期也绑定该 scope |
| shadowing | 最具体者胜出的名称解析:带作用域的工具/片段/变量仅在自身 scope 内替换全局同名项 |
| restriction | tools.restrict 为单个 scope 过滤全局工具集合,多个 restriction 取交集组合 |
| lineage | 以数据形式携带的父子关系事实(parentSession、delegationDepth 等),从不影响可见性 |
- 带作用域的注册不会向下继承给 subagent。
- 子树行为通过 lineage 数据表达,而不是通过 scope 结构。
shadowing:最具体者胜出
shadowing 是按 agent 定制 persona 和定制工具变体的机制。一个带作用域的工具,仅在该 scope 内替换同名的全局工具;其它 agent 仍看到全局版本。
restriction:过滤全局工具
restriction 用 tools.restrict 为单个 scope 过滤全局工具集合。被过滤掉的全局工具既不进入提示词,也拒绝执行,与不存在的工具无法区分。
换句话说,restriction 让一个 scope 里的 agent 完全「看不见」某些全局工具,而不是在调用时再拒绝。
要点
isolate: { shell: true }让 group-a 与 group-b 的 Bash 实例相互独立、互不影响。- 带作用域的注册不会继承给 subagent。
- shadowing 解决「同名替换」,restriction 解决「全局过滤」。