乐于分享
好东西不私藏

DeepSeek Harness 源码研究(五):如何只换两个 Provider,就迁走整个执行世界

DeepSeek Harness 源码研究(五):如何只换两个 Provider,就迁走整个执行世界

如何只换两个 Provider,就迁走整个执行世界

很多 Agent 项目的“可扩展”,实际只发生在模型和工具列表上。模型可以从 A 换到 B,工具可以多注册一个函数;一旦要求把本地执行迁到远程沙箱,Bash、文件、终端、LSP 和上传下载却要各写一套远程版本。

这说明系统有插件,却没有完整能力接缝。

dsh 对 seam 的定义很明确:一个能力至少要有 Service Definition、Service Provider 和 Consumer。三者共同存在,才形成可替换边界。

第一层:工具是用户界面,Provider 才是执行位置

以文件读取为例,模型看见的是 read_file 工具;工具依赖 ctx.fs 服务;真正访问本地磁盘还是远程工作区,由 FS Provider 决定。

Shell 也不是直接调用 Node spawn。Bash executor 依赖 ctx.subprocess,Sandbox 可以包裹 argv,Persistent Terminal 与 LSP 同样复用子进程和文件世界。

因此,当 ctx.fs 和 ctx.subprocess 同时从 local Provider 切到 E2B Provider,文件工具、Bash、PTY 与 LSP 可以一起进入远程执行环境。Consumer 仍调用同一接口,不需要每个工具理解 E2B API。

这种价值不是“少写几个 if remote”,而是让执行位置成为部署选择,而不是业务代码分叉。

第二层:dsh 的能力图远不止文件和命令

LLM seam 由 ctx.llm 提供。DeepSeek、pi-ai 与 Replay adapter 注册到同一个 registry;Agent Loop 只消费统一的 prepareCall/stream vocabulary。重试、Compaction 和 Session Title 可以在上层复用它,而不绑定单一 SDK。

Session persistence 由 ctx.sessionPersistence 定义。JSONL 与 SQLite 是实现选择;内存 Session 核心只广播 session/event 并在 flush 时等待参与者,不把数据库写死在 core/session

Subagent seam 更有代表性。同一个 ctx.subagents 可以接 in-process child、ACP、Codex、Claude Code 或 DSH SDK provider。One-shot provider 在 start 前公开能力 flags:output schema、depth limit、tool filter、persona。不支持的请求会 fail loud,而不是接受后静默忽略。

Continuable child 的生命周期则由通用 continuation manager 管理。Provider 只准备第一次创建所需的 detached spec;后续 cold resume 不再依赖原 Provider 的 live object,而是从 durable Session descriptor 重建 Agent。这里刻意把“执行后端差异”与“长期会话身份”分开。

Workflow 也有 Definition、worker-thread engine 和 model-facing tool。未来可以换进程或沙箱 engine,而不改变脚本与工具合同。

此外还有 Web、Storage、Attachments、Approval、Skills、Jobs、Directory Picker、LSP、Terminal 等 seam。docs/capability-seams.md 生成的图,本质上是一张供应商替换和依赖风险地图。

第三层:完整 seam 是技术架构,也是商业议价能力

对技术团队,seam 有三个直接收益。

第一,测试可以使用 fake/replay Provider,把模型、文件或外部服务的非确定性隔离掉。第二,安全策略可以放在 Definition 与 Provider 之间的统一边界,而不是散落于每个 Consumer。第三,新执行环境只需实现共享能力,而不用复制上层 Agent 产品。

对企业决策者,seam 决定供应商替换成本。如果模型、搜索、沙箱、存储和子 Agent 都通过稳定合同接入,采购路线变化不会立刻传导成前端和业务重写。这是一种长期议价能力。

但 seam 不是抽象越多越好。一个接口若只服务一个实现、没有独立 Consumer,可能只是提前设计。一个能力若声称可替换,却把路径语义、权限模型、取消、错误或流式行为留在实现私约里,也只是“长得像接口”。

安全上尤其不能误读。Provider 替换意味着授权能力也会变化。本地 Bash 在没有 sandboxing executor 时拥有完整执行权;Web tool 自身没有特定 URL/domain 审批策略;不同 OS 的 confinement 能力并不天然等价。ctx.approval、pre-execute policy、FS guard、sandbox 和 subprocess Provider 必须作为一个部署闭包验证。

因此,评估一个 seam 可以问五个问题:

  1. Definition 是否完整表达取消、错误、状态和资源所有权?
  2. 至少是否存在两个语义可对照的 Provider?
  3. Consumer 是否真的只依赖 Definition?
  4. Provider 替换后,安全与持久化合同是否仍然成立?
  5. 真实产品组合是否有跨 Provider 的契约测试?

dsh 的价值不只是提供很多能力,而是把“变化可能发生在哪里”画成了一张可执行的依赖图。

源码核验索引

  • 能力图:docs/capability-seams.md
  • 架构定义:docs/architecture.md
  • FS / subprocess / E2B:packages/fs/packages/subprocess/packages/e2b/
  • Subagent contract:packages/subagent/subagent/src/types.ts
  • Workflow seam:packages/workflow/workflow/README.md
  • Web 权限限制:packages/web/tool-web/README.md

事实边界:存在 Provider 并不证明它在所有平台和故障下语义等价。替换能力必须通过实际 profile 的跨 Provider 合同测试验证。