课程总纲 / 阶段 1 · 理念
L06

核心理念三:能力缝与三角色

dsh 如何做到"换一个实现 = 换掉整个产品的某项能力"。

预计阅读 20 分钟难度 ★★★☆☆读懂社区插件的第一把钥匙

一、什么是能力缝Capability Seam

能力缝(seam)= 可替换能力的标准切口。seam 本义是衣服上的缝:沿缝拆开就能换掉一只袖子,不用重做整件衣服。一条完整的缝由三个角色构成:

Service Definition声明接口
"这个能力长什么样"
Service Provider提供实现
"具体我来干"
Consumer使用能力
"通常是一个
模型可调的工具"
角色职责通俗理解
Service Definition(服务定义)声明 Cordis 服务 + 请求/结果类型合同模板:规定接口的形状
Service Provider(服务提供者)实现接口施工队:可以换,合同不变
Consumer(消费者)使用能力(常是模型工具)住户:只认合同,不认施工队
铁律:三角色齐全才构成缝;依赖方向固定——Provider 和 Consumer 都只依赖 Definition,彼此互不依赖,这就是"换施工队,住户无感"。

二、真实例子:Bash 执行能力The Bash Seam

角色它做什么
Definitiondsh-shell定义 shell 服务和 Bash 请求/结果类型
Providerdsh-bash-local在你本机执行命令
Consumerdsh-tool-bash把能力包成模型可调用的 bash 工具

想换掉"在本机执行",把 dsh-bash-local 那行换成任何同样实现 shell 服务的包(如远程沙箱),Definition 和 Consumer 一个字不用改

# cordis.yml —— 换 Provider 就是换一行配置
- name: '@deepseek-ai/dsh-bash-local'      # 本地执行
# 换成另一个提供 shell 服务的包即可,其余不动

三、为什么这招威力巨大Why It Matters

文件系统和子进程共享一个执行环境:把它们的 Provider 一起指向远程沙箱后,Bash、持久终端(PTY)、LSP 全部无感跟随——这些 Consumer 只是插在缝上的住户,施工队搬走了它们跟着搬,没有任何工具需要改代码。像整栋楼换物业:住户不换门牌、不动装修,水电气已全部切到新供应商——一处替换、全局跟随。

类似的缝有一整排:shell、fs、web(搜索/抓取)、subagent(提供者从"进程内新生"到"另一个产品"都有)、sandbox(Landlock / bwrap / Seatbelt)、compaction、persistence(JSONL / SQLite)……完整清单见 docs/capability-seams.md

四、使用守则Rules of Use

  1. 扩展插件依赖 Definition,永不依赖具体 Provider——依赖了具体实现,替换能力就对你失效。
  2. 不要过早拆三角色:简单工具一个包就够,只有实现确实需要独立演化/替换时才拆(官方原话:不要 preemptively 拆分)。
  3. Request/Result 类型归 Definition 所有——合同条款跟合同走,不散落在施工队手里。
钩子:L16 会带你把一个工具拆成三角色包;L18"读插件五步法"第一步就是判断插件站在哪个角色——看到社区插件先问"它是 Definition、Provider 还是 Consumer?"
seam 能力缝
可替换能力的标准切口:三角色齐全才构成。
Definition
合同模板:服务接口 + 请求/结果类型。
Provider
施工队:接口的具体实现,可整体替换。
Consumer
住户:使用能力的插件,常见形态是模型工具。
✏️ 动手练习
  1. 打开 docs/capability-seams.zh.md,数一数仓库里有多少条完整的能力缝。
  2. 对照 packages/subagent/:找出三角色各是什么包,Provider 有几种(spawn-in-process / fork / acp / codex / claude-code / dsh-sdk)。
  3. 自问:公司的"内部工单系统"想接进 dsh,该站在哪个角色?(答案不止一个,想想为什么。)
📝 自测(点击展开答案)
1. 一条能力缝的三个角色是什么?依赖方向如何?
Definition(接口声明)、Provider(实现)、Consumer(使用,常为工具)。Provider 和 Consumer 都只依赖 Definition,彼此互不依赖。
2. 为什么换掉 fs 和 subprocess 的 Provider 后,Bash/PTY/LSP 工具会"自动跟着走"?
这些 Consumer 都只依赖 fs/subprocess 的 Definition、共享同一执行世界;Provider 换了地址,插在缝上的住户整体迁移,无需改任何 Consumer 代码。
3. "单独一个角色不构成缝"是什么意思?
只有接口声明、只有实现或只有使用者,都不构成可替换能力的完整闭环;三角色齐全是逻辑要求,与是否拆包无关。
4. 什么时候应该把三个角色拆成三个包?
只有当角色需要独立演化或替换时(如多 Provider 并存);简单工具不要过早拆分,拆分是手段不是目的。
权威出处:architecture.zh.md(Capability seams 节) · practice/index.zh.md(三角色教程) · capability-seams.zh.md · glossary.zh.md