调试 ACP 集成:JSON-RPC 代理方法

通过 JSON-RPC 代理的方式调试 ACP 集成问题,分享调试技巧和解决方案。

本文摘要

通过 JSON-RPC 代理的方式调试 ACP 集成问题,分享调试技巧和解决方案。

Agent Communication Protocol (ACP) 是 AI 编码 agent 与宿主系统通信的标准。但当 agent 声称支持某个功能却未正确实现时会发生什么?这是一个真实的调试故事。

问题

我们正在将一个编码 agent 集成到 ACP 兼容的运行时中。ACP 握手流程是:

  1. 启动 agent 进程
  2. 发送 initialize 请求
  3. 发送 session/load 携带现有会话 ID

agent 在 initialize 响应中报告 agentCapabilities.loadSession: true,所以我们期望 session/load 能工作。但它返回了:

{
  "error": {
    "code": -32601,
    "message": "Session not found"
  }
}

根本原因

agent 只接受它自己创建的会话 ID。当 ACP 发送外部生成的会话 ID(来自其自己的记录跟踪),agent 不知道如何处理。能力标志具有误导性——它意味着”我支持会话管理”而不是”我接受任意会话 ID”。

解决方案:JSON-RPC 代理

由于无法修改 agent 的代码,我们构建了一个轻量级代理来拦截和转换 JSON-RPC 消息。代理的核心逻辑:

// 拦截 stdin/stdout JSON-RPC
function transform(msg) {
  if (msg.method === "session/load") {
    const acpxId = msg.params ? msg.params.sessionId : null;
    const mapFile = join(MAP_DIR, acpxId + ".json");
    
    if (existsSync(mapFile)) {
      // 已有映射,使用真实 session ID
      const mapping = JSON.parse(readFileSync(mapFile, "utf8"));
      msg.params.sessionId = mapping.realSessionId;
      return msg;
    }
    
    // 首次加载 — 转换为 session/new
    msg.method = "session/new";
    msg._acpxSessionId = acpxId;
    return msg;
  }
  return msg;
}

关键经验

  • 能力标志不保证兼容性 — 始终测试实际行为,而不仅仅是 agent 声称支持的内容。
  • 代理模式很强大 — 当无法修改源代码时,薄代理层可以桥接不兼容的接口。
  • 状态映射至关重要 — 跟踪外部 ID 和内部 ID 之间的映射,以便后续请求正确路由。
  • ACP 仍在成熟 — 不同的 agent 对规范的实现不同。防御性编码和回退策略是必要的。

关于 ACP

ACP (Agent Communication Protocol) 标准化了编码 agent 与宿主环境的通信方式。它使用 JSON-RPC 2.0 over stdio。关键方法包括 initializesession/newsession/loadsession/save。该协议很强大但实现各异——始终要有兼容层。

0 0 投票数
文章评级
订阅评论
提醒
guest

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理

0 评论
最多投票
最新 最旧
内联反馈
查看所有评论
0
希望看到您的想法,请您发表评论x