Volume 2 · Chapter 32
SDK 与 API 服务:进程边界的另一边
到目前为止全部能力都在进程内。这一章看进程边界:JSON-RPC SDK(程序化驱动 harness)、ACP 服务(Agent Client Protocol 自动化协议)、api/remotes 与 apiproxy(Web 的 BFF 层)、MCP 客户端(把外部 MCP 服务器变成 dsh 工具)。
(卷一连接点) 05 页 ctx.agents(一切接口的根)· 06 页 session/event(推送流)
→
本域:sdk / acp / api-remotes / apiproxy / mcp-client / hooks
→
(回心脏) 外部调用经 AgentRegistry 的 create/resume 进入 05 页循环
示例本次示例:一个程序驱动 dsh
示例轨迹 32-1 · Python SDK 的一次完整调用
# 仓库真实示例:examples/jsonrpc-agent(README 说「Python SDK 驱动的无人值守代理」)
# Python 侧(python/sdk/src/deepseek_harness/client.py):
# client = Client("http://127.0.0.1:3080") ← JSON-RPC over HTTP
# session = client.new_session()
# session.prompt("修复这个测试")
# dsh 侧:sdk server(inject=['agents'],sdk/server/src/index.ts:22)
# → AgentRegistry.create(05 页)→ 跑 05-14 页循环
# → 事件流回 Python 客户端(session/event → JSON-RPC 通知)
# 协议只做翻译,循环完全复用——这就是 32 页「入口极薄」的意思
来源:32 页 §3 + examples/jsonrpc-agent + python/sdk
示例轨迹 32-2 · MCP 服务器变成 dsh 工具
# 外部 MCP 服务器(如记忆服务)→ examples/mcp-memory overlay # mcp-client(inject=['tools'])连接服务器 → 枚举其工具 # → 每个 MCP 工具注册进 14 页 registry # → 12 页 assemble 时它们与原生工具并列进模型提示词 # 模型调用与原生工具无差别——工具通道的「本地化」
来源:32 页 §3 + examples/mcp-memory
§1挂载条目
typert* / api-gateway(03 页的 typert 家族)——类型图生成 + RPC 网关- 可选挂载:acp(
inject = ['agents'],src/index.ts:45)、sdk server(inject = ['agents'],src/index.ts:22)、mcp-client(inject = ['tools'],src/index.ts:31)、apiproxy(ApiProxyService extends Service,src/index.ts:69)
§2包文件地图
| 包 | 规模 | 角色 |
|---|---|---|
packages/sdk/ | — | JSON-RPC 协议 + server(inject = ['agents'])+ TypeScript client(6 文件 / 952 行) |
packages/acp/acp/ | — | ACP 自动化协议服务器(inject = ['agents'])——Agent Client Protocol(Zed 等编辑器生态) |
packages/host/apiproxy/ | 5 文件 / 4463 行 | Web BFF:ApiProxyService extends Service implements ApiProxy(src/index.ts:69)——浏览器 UI 与宿主之间的 HTTP 代理层 |
packages/api/remotes/ | 5 文件 / 327 行 | 远程 BFF 组装(agent-lookup / remote-events) |
packages/mcp/mcp-client/ | 5 文件 / 1171 行 | MCP 客户端:把外部 MCP 服务器暴露为 dsh 工具(inject = ['tools']) |
packages/hooks/ | — | Claude Code/Codex hook 桥 + 线协议库(hook-protocol 9 文件 / 854 行) |
§3机制:三条对外通道
- 机器通道(SDK / ACP):外部程序经 JSON-RPC(SDK)或 ACP 协议驱动 agents——
inject = ['agents']说明它们站在 05 页的注册表上。SDK 是 dsh 自己的协议,ACP 是行业协议。 - 浏览器通道(apiproxy / remotes):Web UI(33 页)与宿主之间的 BFF——HTTP 请求 → 宿主内部调用 → 事件流回推。apiproxy 4463 行是宿主侧最大的服务之一。
- 工具通道(mcp-client):把外部 MCP 服务器的工具映射进 14 页 registry——模型看到它们与原生工具无差别。方向相反:dsh 是客户端,外部是服务器。
§4关键代码
45export const inject = ['agents']
31export const inject = ['tools']
69export class ApiProxyService extends Service implements ApiProxy {
45
ACP 与 SDK server 都只依赖 agents——外部协议的入口极薄:协议翻译 + 注册表调用(create/resume),循环完全复用。
31
mcp-client 只依赖 tools——它不碰 agents,只往 14 页的 registry 里加工具。MCP 服务器的能力经它「本地化」。
69
apiproxy 是 Web 的宿主侧根——它 implement ApiProxy 契约(浏览器侧的类型生成自同一契约,typert 的产物)。
§5易错点
进程边界的校验义务(AGENTS.md 的边界清单):wire 输入必须验证——ACP/SDK 的参数是外部 JSON,进 05 页之前要过 parser(不能假设类型)。这是 06 页「信任静态类型只在同进程边界」约定的另一半。
hooks 桥的意义:Claude Code/Codex 的 hook 协议让外部工具链在 dsh 的事件点上插桩——它是「互操作」域,不是核心循环的一部分。