LAYER 06 · 动手扩展并交付

实战:设计 Capability Seam 与 Provider

接口、实现和消费者要一起设计;只抽象一个 class 不等于拥有 seam

22 min3 处源码锚点upstream@47f9438
definition + provider + consumer
本章要解决的问题

什么时候应该新增 Provider,什么时候应该新增完整能力 seam?

先建立直觉

插座标准不是一个插座外壳:它同时定义电气接口、生产插座的厂商和使用插头的设备。缺少任一角色,标准都没有产品意义。

MECHANISM

机制拆解

已有 service contract 时,新增 provider 只需实现语义并注册;新增能力则要同时选择 service 定义、至少一个 provider、消费方与替换价值。

Provider 特有配置留在实现包;consumer 只依赖 service。能力目录与模块图用于核验没有不必要反向依赖。

第 1 步 / 共 5 步

证明替换价值

至少有两个合理实现或一个明确部署边界。

INVARIANTS

无论怎么扩展,都不能破坏

  • 消费者不 import provider 包
  • 接口错误语义能被所有实现兑现
  • Provider dispose 完全释放 SDK、进程或远程资源
FAILURE MODES

最容易踩中的坑

  • ×为一个实现提前抽象
  • ×把 provider 名称泄漏到 Agent Loop
  • ×接口提供任意协议 escape hatch
● ● ●h26-build-adapter.ts TypeScript
abstract class WeatherService extends Service {
  abstract lookup(input: WeatherQuery, signal?: AbortSignal): Promise<WeatherSnapshot>
}

class HttpWeatherProvider extends WeatherService {
  async lookup(input: WeatherQuery, signal?: AbortSignal) {
    return normalize(await this.client.fetch(input, { signal }))
  }
}
VERIFY IN SOURCE

不要相信结论,去源码里复核

以下链接固定到官方 deepseek-harness@47f9438;查看当前上游时请留意后续 breaking changes。

KNOWLEDGE CHECK

先停十秒,再揭晓答案

为什么 LSP seam 不提供 sendRawRequest()?

为什么下一章紧接在这里

能力完成后还要被人类或其他客户端使用;下一章讲 Web、CLI、ACP、SDK 与 Host 如何共享同一 Agent。

Learn DeepSeek Harness

独立教学项目。解释力来自源码,判断边界以官方仓库为准。