接第二种 Agent 实现时,会话、工具调用、权限请求和取消的差异就开始影响界面。若每种实现都带来一套聊天状态,接入数量增加以后,界面与执行侧很难一起维护。
最近研究 ACP,我更关注它能把哪些交互变成共同约定。这里的 ACP 是 Agent Client Protocol,面向客户端与 Agent 通信,不是所有同名缩写的协议。
文本只是会话的一种输出
一轮执行可能有计划、工具状态、等待用户决定、文件变化和结束原因。只给一个文本流,客户端就得从文字中猜“还在执行”还是“等待授权”。这类猜测不适合作为业务状态。
协议适配器把会话、轮次和工具调用分别关联。一个会话有多轮,一轮有多个工具,每项都有自己的标识;平台任务编号再关联到这些对象,不能以当前聊天窗口作为唯一关联依据。
客户端按协商能力提供输入和操作。某实现不支持图片或会话恢复,就不能因为平台界面有入口而假设它支持。发送前拒绝不支持的内容,比静默丢弃更容易排查。
协议事件在适配器里解释
适配器集中完成关联、状态转换与界面通知。平台可以增加本地事件序号,但不把自定义字段写成协议已有能力。下列是平台自己的状态约定,具体报文映射以选用版本为准。
turn: created → running → waiting_permission → running → completed
└→ rejected / failed
turn: running → cancel_requested → cancelled / failed / outcome_unknown收到一个工具结果,不等于整轮完成。工具失败后可能继续推理,权限拒绝也要落实到对应调用。候选选项、toolCallId 与用户选择必须保持关联,不能把一次同意应用到另一项请求。
停止按钮对应一个尚待确认的结果
界面可以立即显示停止请求已发出,但执行是否真正结束要等回执。取消之后可能仍有在途更新,适配器保留关联关系,按协议规则处理结束与未决权限请求,不全部丢掉。
连接断开是连接状态,不直接等于任务失败或已取消。子进程、远程任务和外部业务写入也不天然服从同一撤销语义。动作已提交时,需要读取业务结果,不能显示成已撤回。
恢复能力不足的实现,就明确保留结果未知和人工核对入口。统一接口不能靠隐藏差异完成。
协议之外仍有平台自己的工作
协议约定怎样交换消息,框架组织 Agent 内部执行,平台负责用户、授权、运行环境与交付。协议可以要求用户选择一个工具权限选项,谁有资格批准、批准什么资源、如何审计,仍由平台判断。
MCP 解决工具与上下文接入,ACP 关注客户端和 Agent 交互,二者可以同时存在。名称相近、都与 Agent 有关,并不意味着可以相互替代。
接入验收检查状态而不只看答案
固定文本、连续工具、权限拒绝、工具失败、执行中取消、断连和会话加载等消息序列。对照最终状态与事件归属,检查工具是否一直停在运行中、取消后是否被迟到结果改成成功、恢复后是否丢失关键上下文。
适配器把实现差异限定在这一层,界面消费共同模型;能力不支持就公开表达,业务授权与资源恢复仍按平台规则执行。这是我目前认为可维护的接入范围。