昊梵体育网

让编辑器直接调用 Agent,Covonaut 中的 ACP 实践

在开发 Go Agent 框架 Covonaut 过程中,我实现了一个让 Agent 真正“入住”编辑器的协议——ACP
在开发 Go Agent 框架 Covonaut 过程中,我实现了一个让 Agent 真正“入住”编辑器的协议——ACP(Agent Client Protocol)。
为什么需要 ACP 协议?官方将 ACP 类比为 LSP(Language Server Protocol),非常确切。当年 LSP 标准化了“编辑器与语言服务器的对话方式”,让编辑器不必为每种语言重复造轮子。ACP 想要解决的也是类似的问题,只不过对象换成了 Agent:把“编辑器如何与 Agent 对话”这件事标准化,达到“Agent 实现一次,任何兼容 ACP 协议的编辑器都能直接调用”的目的。
ACP 协议由 Zed 提出,核心设计理念是:Agent 是 Server,编辑器是 Client,Agent 作为编辑器的子进程启动,双方通过 JSON-RPC 通信。用户始终待在熟悉的编辑器里,需要时随时唤起 Agent,而不是切换到另一个专属界面。
Covonaut 的 ACP Server 实现Covonaut 的 ACP 模块本质上是一个运行在 stdio 上的 JSON-RPC 2.0 Server。交互流程可以分为三层:
握手层:编辑器发送 initialize 协商能力,再通过 authenticate 完成认证;会话层:支持 session/new 创建新会话,session/load / resume / fork / list 管理历史,session/prompt 下发任务,session/cancel 中止执行,还能在运行时通过 set_mode / set_model 动态切换模式与模型;持久化层:多会话可并存,元信息默认存储在 ~/.acp-agent/acp_sessions.json 中,重启后自动恢复。编辑器反向赋能 AgentACP 最值得关注的设计是编辑器反过来给 Agent 提供能力。Agent 在编辑器内工作时,文件系统、权限等本应由宿主把关的事,通过协议交回编辑器处理,而非 Agent 自行其是:
权限确认:当 Agent 要执行有风险的工具时,会反向发送 session/request_permission 请求,让用户选择 allow_once、allow_always或 reject_once。给危险操作加了一道安全闸门。文件读写(感知 Buffer):若客户端在初始化时声明了文件系统能力,Agent 的读写工具就不再直接操作磁盘,而是走 fs/read_text_file / fs/write_text_file。这就意味着它能读到编辑器里尚未保存的 buffer,真正实现“所见即所得”的协作。让 Agent 的行为可见当 session/prompt 触发 Agent 运行后,内部事件会被翻译成 session/update 通知推回编辑器。协议对更新类型做了细致区分:
消息增量:user_message_chunk / agent_message_chunk / agent_thought_chunk,分别对应用户输入、Agent 回复和思考过程;工具调用:tool_call / tool_call_update,每个调用都带有 kind(read/edit/execute/fetch 等)和一行可读标题,编辑器可据此渲染出 UI,而非暴露原始 JSON;状态更新:还包括 plan、available_commands_update、current_mode_update 等,为编辑器预留了丰富的展示空间。此外,ACP 复用了 MCP 的大量 JSON 结构,并补充了 Coding 场景特有的类型(如 diff 展示),用户可读文本默认使用 Markdown 格式。
小结把“编辑器如何调用 Agent”这一层标准化后,Agent 和编辑器就能各自独立演进,使用者也能自由选择趁手的工具组合。