DSH 的 ACP 与 SDK

ACP = 对外的业界标准接口(Agent Client Protocol),把 DSH agent 暴露给任意 ACP 客户端,纯自动化,只给干净结果。 SDK = DSH 自家的进程外驱动协议(私有 JSON-RPC),把完整 harness runtime 交给你的 TS/Python 代码掌

ACP = 对外的业界标准接口(Agent Client Protocol),把 DSH agent 暴露给任意 ACP 客户端,纯自动化,只给干净结果。 SDK = DSH 自家的进程外驱动协议(私有 JSON-RPC),把完整 harness runtime 交给你的 TS/Python 代码掌控,附全量事件流。 两者都能"从另一个进程驱动 agent",但一个对外互操作,一个对内程序化。不是竞争关系,是两扇门。


一、本质定位对比

维度

ACP (dsh-acp)

SDK (sdk/ 三件套)

协议来源

外部业界标准 Agent Client Protocol

DSH 仓库私有 wire 协议

身份标识

agentInfo: deepseek-harness-acp

serverInfo.name: deepseek-harness-sdk-runtime

角色

transport adapter,不含 UI/交互层

protocol + client + server 三层驱动栈

版本协商

✅ 有(initialize 协商协议版本)

❌ 无(0.0.1,pre-release 无兼容承诺)

谁消费它

任意 ACP 客户端;仓库内 = subagent-acp

TS 客户端 SDK + Python SDK;仓库内 = subagent-dsh-sdk

SDK 三个包的职责:

  • dsh-sdk-protocol——wire 协议定义(JsonRpcLineTransport + 全部具名类型),纯库,无插件。

  • dsh-sdk-client——TS 客户端:高层 DeepSeekHarnessrun() 一体化)、底层 HarnessClient(显式握手)。

  • dsh-sdk-jsonrpc-server——jsonrpc 插件,在 stdio 上服务客户端。


二、方法集对比(协议能力)

能力

ACP

SDK

握手

initialize(协商版本、只声明 baseline prompt)

initialize(provider/model 路由 + 可选 maxTokens

发任务

session/prompt → 等 agent 完全 idle → 返回 {stopReason}

session/prompt立即返回 {messageId}(仅入队回执)

中途取消

session/cancel(只取消目标 session)

❌ 无(想停 = 关掉整个 runtime 进程)

权限审批

session/request_permission(一次性 allow/reject 自动回答)

❌ 预留但未实现(server→client 请求是"死能力")

内容回传

session/update → 只发 committed assistant 文本agent_message_chunk

session.event完整 session 日志信封,不过滤)+ session.status + subagent.started/finished

关闭

无 per-session close(连接断=全部释放)

无 per-session close(agent 活到进程 shutdown)

最核心的一句话差异

  • ACP 给你"一个干净最终答案 + stopReason",代价是看不到过程——reasoning、工具活动、plan、token 用量、实时进度全部不上 wire(刻意设计)。

  • SDK 给你"全程事件直播",但没有 prompt 级结果归属——messageId 只标识"已入队","什么时候算完成"要你自己从事件流 + session.status 判断。


三、session 模型(你最容易搞错的地方)

ACP:有状态、多轮、可复用

  • session/new 创建的是持续存在的 agent,不是一次性函数。

  • 同一个 session 可以连续发多个 prompt,上下文累积(测试 turns.spec.tsmulti-session.spec.ts 均证实)。

  • 每 session 同时只允许 1 个 in-flight prompt(第二个会被拒 already in flight),但可顺序多轮。

  • 一个连接可持有多个 session,彼此完全隔离(并发、独立取消、独立 workspace)。

  • 只支持 fresh session:load/list/resume/delete/fork 都不支持。

SDK:按 id 取 agent

  • server 对每个 sessionId get-or-create 一个 agent。

  • session 一经创建活到进程结束,无 per-session 关闭。

  • 独立请求可以在同一 session 上入队更多工作。


四、"一次调用"到底是什么粒度

这是前面的重点纠正,值得单独记住:

  1. 一次 session/prompt ≠ 一问一答。 内部是 agent.followup(message) + await agent.whenIdle()——模型会自主多步(多想多调工具)直到整个 agent idle 才返回。你外包的是一段"自主干活的时间",不是一次 API 往返。

  2. ACP 零编排能力。 只有 6 个原始动词(initialize/authenticate/new/prompt/cancel/request_permission),没有 DAG、plan、分支、重试。编排永远在 client 侧

  3. 多轮任务的处理:连续对话 → 复用同一 session 顺序 prompt;并发任务 → 多个 session 并行;真正的工作流(分支/并行/子任务)→ 上层的 workflow / subagent 包或自己写,ACP 只当叶子执行器。


五、作为 subagent backend 的对比(进程外子代理)

subagent-acp

subagent-dsh-sdk

驱动协议

ACP(外部标准)

SDK JSON-RPC(私有)

子进程身份

任意 ACP agent

完整 peer harness(自带 cordis.yml 组合、持久化、模型路由、工具)

每次 run

新进程 + 新 session + 一次 prompt

新进程 + 完整 runtime boot

启动成本

较低

较高(先 boot 整棵插件树)

结果提取

汇总 streamed agent_message_chunk

读最后一个完整非空 assistant/message / 累计 text-delta

取消

可发 ACP cancel,再走 EOF→SIGTERM→SIGKILL

无 wire cancel,本地标 aborted + protocol shutdown 再走阶梯

共同点

不继承父对话(inheritsParentContext: false),只传 workspace cwd;无 start-time 能力(outputSchema/depth/persona 全拒)

同左

配置默认值差异:subagent-acp 的权限默认 rejectsubagent-dsh-sdk 默认 provider deepseek-official、model deepseek-v4-flash


六、选型速查表(应用场景)

诉求

选谁

脚本批量跑任务、只要最终答案

SDKDeepSeekHarness.run() / Python deepseek-harness

接入第三方 ACP 客户端 / 编辑器生态

ACP

任务可能跑偏、要中途取消

ACP

要处理"是否允许某操作"的审批

ACP

要看完整过程(reasoning/tool/usage/日志)

SDK

你自己定义"何时算完成"、做二阶编排

SDK

子代理 = 完整 harness runtime

SDK(subagent-dsh-sdk)

子代理 = 任意 ACP agent

ACP(subagent-acp)

判断口诀:对方认不认 ACP 标准? 认 → ACP;你要的是"DSH 自家完整 runtime / 全事件流 / 在代码里做细" → SDK。


七、各自已知限制(260903)

ACP:

  • 只支持 fresh sessions,baseline text prompt(图/音/embedded context/MCP 全拒,resource link 扁平化成文本引用)。

  • 只给 committed 答案,过程不可见。

  • 连接级生命周期:断连 = 该连接所有 session 全释放。

  • 单 session 单 in-flight。

SDK:

  • 无版本协商、无 cancel、无 per-session close、无 per-prompt 结果。

  • stdout 纯净性是部署约定(协议帧独享 stdout,不能配 stdout logger)。

  • 自动挂载模型适配器只认 deepseek-official(其余需预先注册)。

  • 无打包 runtime 解析(TS 侧要自己指定 command/args;打包解析是 Python 发行版的事)。


八、心智模型(记住这三句就够)

  1. ACP = 外包一段自主活:给任务(session 维度)、拿干净结果 + stopReason,可取消、可审批,但过程你是盲的。它不是流水线编排器,编排得站在它上面做。

  2. SDK = 雇了个完整员工全程直播:能看到每一步,但"干完没有"要你自己判断,想叫停只能整个关掉。

  3. 对比的敌人是搞反取向:想要"看不见的过程"却用 SDK、想要"事件流但发现 ACP 不给"——先对号入座上面的速查表。