# Agent Note: ACP 作为仅面向自动化的协议

Status: implemented

[English](2026-07-23-acp-automation-only-protocol.md) | 中文

> 仅面向自动化的边界仍然有效。[标准 ACP v1 自动化控制](../feature/2026-08-22-standard-acp-automation-controls.zh.md)仅取代本说明中仅支持提示词的方法、配置、MCP、更新和生命周期清单；它不会把 ACP 恢复为 UI。

## 问题

ACP（Agent Client Protocol）桥接层已经变成第二套交互式产品 UI。它将持久事件转换为编辑器卡片、终端元数据、diff、计划、标题、推理（reasoning）、命令、模式、模型和权限选择器、会话导航以及面向人类的询问。这些职责与 TUI 和 Web 客户端重复，同时将自动化传输层与 UI 服务、持久化查询、展示策略和编辑器特定约定耦合在一起。

ACP 仍有一个有用的职责：另一个 agent（智能体）或自动化控制器可以启动 harness 进程、创建隔离会话、发送文本或范围狭窄的受支持内联图片、接收已提交的文本／图片回答、取消工作并回答权限请求。跨进程 ACP subagent 后端依赖这个标准协议边界。

快照套件使移除工作更复杂。大多数 ACP 场景测试的是组装后的 agent 后端，而不是 ACP 展示层；如果随编辑器桥接层一起删除整个套件，就会丢失大量无密钥行为测试。

## 决策

`@deepseek-ai/dsh-acp` 是位于 [`packages/acp/acp`](../../../../packages/acp/acp/README.zh.md) 下、独立于 `ui` 包组的自动化传输层。其公开协议包含标准自动化控制，而非展示：持久会话创建／列出／恢复／关闭、每会话一个在途提示词、模型配置、stdio／HTTP MCP 挂载、已提交语义更新、取消、并发会话和一次性权限请求。提示词按协议顺序保留文本与受支持光栅图片，资源链接则展平为方括号文本引用；桥接层仍拒绝附加目录、音频、嵌入资源、格式错误或空提示词、未知会话和重叠提示词。

图片能力必须真实，而不能只看结构：只有持久附件存储存在，且配置的确切提供方／模型解析后明确支持图片输入时，`initialize` 才会公布该能力。每个提示词都会在异步准入前快照确切路由、严格解码全部图片块，并在发布用户事件前把完整批次委托给 `AttachmentStore.saveImages()`。即使下一轮配置并发变化，同一快照仍驱动已准入轮次。取消会在任何异步工作前预留并中止准入槽位，使提示词在已经启动的写入停稳后才结算，而且绝不发布迟到消息；提示词进入 Agent inbox 前既不会取消，也不会等待无关的 Agent 工作。已经完成的内容寻址写入可能保持不可达，因为对去重存储执行破坏性回滚并不正确。可由调用方修正的图片策略失败会映射为无效参数，路由查询、存储损坏和持久化失败则仍属于内部故障。

桥接层只发出已提交的语义事实。每个会话使用一条 Promise 链，在异步重新读取并校验助手图片引用、将其转换为 ACP base64 交付时，保持 reasoning、assistant 块、工具生命周期、配置和用量更新顺序；对象缺失或损坏会使提示词交付失败，而不是变成占位符。原始分片、待办事项、计划、标题、重试标记、终端元数据、diff、位置和展示投影不会进入 ACP wire。标准模型和 reasoning 选项、列出／恢复／关闭以及 stdio／HTTP MCP 属于自动化控制；会话加载／删除／fork、命令、模式、plan 评审、终端、客户端文件系统操作和面向人类的询问仍不受支持。

保留一次性 `session/request_permission`。它是为桥接层拥有的 agent 提供的机器策略通道，而不是面向人类的审批 UI：应答者只接受桥接层当前会话映射中登记的同一 agent 对象；不属于桥接层当前 agent 的请求或未关联具体调用的请求会继续委派；RPC 失败则映射为故障时默认拒绝的 `unavailable` 结果。客户端可选择允许一次、拒绝一次或取消，桥接层绝不会将该响应转换为持久授权。询问策略仍归审批 seam 及其生产者所有；[`dsh-subagent-acp`](../../../../packages/subagent/subagent-acp/README.zh.md) 会以程序化方式使用该通道。

应用组装包含 agent 主干、持久化、检查点策略、派生会话查询和 ACP 传输层。ACP 桥接层直接读取持久化以生成标准可恢复摘要；它不公开命令、会话引用、plan mode、权限选择器或用户问题展示接口。

传输层调用 agent、会话和审批的接口服务，而不依赖具体的 agent loop（智能体循环）。工具执行仍留在 harness 内；ACP 绝不会把 shell 执行委派给编辑器。stdout 只承载分帧 JSON-RPC，因此 app 不挂载 stdout logger，桥接层也不会 monkey-patch 进程输出。

断开连接与插件 dispose（资源释放）共享同一个经记忆化的完全停稳边界。传输关闭无论成功还是失败，都会取消提示词准入和 agent、排空有序输出、将待处理提示词以已取消状态结算、dispose 每个由桥接层拥有的 agent，并等待循环和会话清理完成。创建流程如果在与关闭的竞态中落败，就会 dispose 其尚未发布的 handle。

<a id="snapshot-boundary"></a>

## 快照边界

ACP 快照套件仍会启动组装后的 ACP 示例，并保留用于锁定后端行为的场景。从该套件移出的只有通过已删除 UI 方法驱动的场景。标准恢复会还原持久 Agent，但不会重放 transcript UI；当 headless SDK 协议本身是测试对象时，语义检查点恢复覆盖仍可使用其示例。

协议与生命周期测试会锁定停止原因编解码器、版本协商、真实图片能力、新会话创建、有序文本／图片准入、资源链接展平、写入前校验全部成员、持久事件中不含内联 base64、拒绝空提示词或不受支持的提示词、基于同一 agent 对象的权限归属、多会话隔离、在有序输出后结算提示词、经过校验的助手图片交付、准入期间取消且不产生迟到 followup 或取消无关 Agent 工作、排除进入 inbox 前的无关失败、传输关闭失败、ACP 专属重载清理，以及拆卸完全停稳。组装后的无密钥快照通过可运行 ACP 示例发送一张真实内联 PNG，并在会话日志中只固定其持久引用。构建产物冒烟测试与真实 stdio 冒烟测试会拒绝混入 stdout 的额外输出。`session/new` 中在真实 stdio 关闭竞态中落败的分支仍豁免覆盖率要求，因为内存传输层无法复现这一顺序；该分支会 dispose 尚未发布的 handle，而周边 dispose 测试会锁定无遗留资源不变式。

## 考虑过的替代方案

**在 Web 达到同等能力前，继续将 ACP 作为编辑器 UI。** 不予采用，因为这会留下两套需要演进的交互约定，并使编辑器约定继续存在于自动化边界中。

**通过严格的服务边界保留早期编辑器桥接层。** 不予采用，尽管该桥接层正确使用了接口服务、工具自有的 render intent、审批与用户交互应答者、harness 自有执行，以及保持 stdout 纯净的组装。其终端卡片是经过能力门控、仅用于展示的 Zed `_meta` 投影，并提供文本回退，而非使用 ACP `terminal/create`，因此 shell 执行从未离开 harness。该投影从稳定的逐调用 id 派生每个展示用终端 id，以避免冲突；由于纯结果展示器接收的是内容块，而不是结构化退出信息，它会从渲染后的状态标记中恢复退出码或信号。标记往返测试和显式的无能力 `console` 回退测试锁定了这两项约定。这些边界保持一致，却无法让编辑器卡片、会话导航、配置选择器和面向人类的询问成为自动化协议应有的职责。

**用私有 subagent RPC 替换 ACP。** 不予采用，因为 ACP 已经提供类型化、可互操作的进程协议，并由跨进程 subagent 后端使用。

**随其他交互功能一起移除机器权限请求。** 不予采用，因为自动化父 agent 必须回答子 agent 的一次性策略决策；这是 agent 之间的控制流，而不是展示层。

**删除 ACP 快照套件，或在本次变更中迁移每个场景。** 不予采用，因为大多数场景测试后端且仍有价值，而完整的 harness 迁移是一项独立的测试变更。只有通过已删除的 UI 方法驱动的场景才离开该套件。

**只要 ACP SDK 具有图片块就公布图片支持。** 不予采用，因为协议词汇不能证明当前部署可以持久化字节，也不能证明配置的确切路由接受视觉输入。初始化时能力未知即为 false；提示词准入会重新检查实时路由。

**把内联图片和助手图片展平为标记，或把 ACP base64 持久化进会话事件。** 不予采用，因为标记会静默丢失模型／用户意图，base64 则会让持久日志变成二进制存储。ACP 在传输边界把自身协议块与现有持久 `ImageBlock` 引用相互转换。

**为 ACP、MCP 和 Web 创建通用 RichContent 服务。** 不予采用，因为核心 `ContentBlock` 与附件 seam 已经拥有共享契约。每个入口只保留协议解析、能力证明与生命周期编排；共享批次限制和图片校验留在 `AttachmentStore.saveImages()` 中。

## 结果

ACP 具有适合 agent 与自动化的精简约定，而 TUI 和 Web 拥有面向人类的交互与展示。该包注入的服务、依赖、协议分支和生命周期状态更少，也不再将自身定位为通用编辑器入口。

自动化客户端收到已提交消息、reasoning、通用工具、配置和用量事实，而不是 token 增量或结构化工具 UI。标准列出／恢复／关闭和会话配置覆盖自动化生命周期，同时不增加导航、transcript 重放、标题或其他人工展示。

因此，后端快照测试仍与 ACP 传输层耦合，尽管对于受测行为而言，该传输层只是附带因素。
