Files
sanguo_quant_live/management/research/task-20260401-a2a-session-analysis/final/report.md
T
2026-04-02 08:55:07 +08:00

11 KiB
Raw Blame History

A2A 多代理会话管理方案调研分析

调研时间2026-04-01 调研人员:诸葛亮(总军师) 调研范围Network-AI、ClawTeam、OpenAkita、当前 a2a-gateway 修复方案


问题背景

当前 OpenClaw A2A 网关存在的问题:

  • 每次 A2A 消息都会新建一个会话
  • 长期使用会导致会话爆炸式增长
  • 上下文碎片化,每个会话只有一条消息
  • 不利于保持对话连续性

核心需求

  1. 同一个目标 agent 的所有 A2A 消息应该进入同一个固定会话(agent:xxx:main
  2. 或者,如果使用 contextId,同一个 contextId 应该复用同一个 A2A 会话
  3. 避免不必要的会话创建,防止会话爆炸
  4. 保持上下文连续性

方案一:Network-AI(多代理协调层)

项目概况

  • 定位TypeScript/Node.js 多代理协调层
  • 特点:原子黑板 propose → validate → commit 防止竞态条件
  • 主要功能:共享状态、预算控制、权限管理、审计日志、17种框架适配

架构分析

核心设计

  • Network-AI 是协调层,不是会话管理层
  • Network-AI 提供 OpenClaw 原生适配(OpenClawAdapter
  • Network-AI 通过 callSkill 调用 OpenClaw skill
  • 每个代理任务通过适配器路由到对应的 OpenClaw agent

会话管理方式

  • Network-AI 本身不强制 OpenClaw 的会话创建策略
  • Network-AI 依赖 OpenClaw 自身的会话管理
  • Network-AI 提供 statefulSessions: true 能力声明,但不实现具体复用逻辑

适配我们需求的可能性

需求 满足度 说明
复用同一个 main 会话 ⚠️ 间接支持 需要在 executeAgent() 中手动转发到 main
contextId 复用 ⚠️ 需要自己实现 Network-AI 不负责透传 contextId
防止会话爆炸 协调层可以控制 Network-AI 的共享黑板可以避免重复创建
代码改动 中等 需要修改 OpenClawAdapter 增加转发逻辑

优点

  • 成熟稳定,功能丰富
  • 跨框架支持,可以混合多种框架
  • 原子操作防止竞态,非常适合并行多代理
  • 内置预算控制和权限管理

缺点

  • 额外的协调层,增加复杂度
  • 本身不解决 OpenClaw 会话爆炸问题,需要额外改造
  • 对于我们三国量化团队固定成员的场景,有些过重

方案二:ClawTeam(团队协作 A2A

项目概况

  • 定位:CLI 多代理团队协作框架(基于 Python + tmux
  • 特点agents spawn agents,自组织团队
  • 上游:HKUDS/ClawTeamOpenClaw 深度集成版本

架构分析

核心设计

  • 每个 agent 有固定的 agent_name
  • ClawTeam 在 spawn OpenClaw agent 时,固定传入 --session-id agent_name(代码第 59 行)
  • 所有消息都复用同一个会话 ID
  • 基于 tmux + git worktree 隔离工作区

会话管理方式

# 来自 clawteam/spawn/adapters.py
if is_openclaw_command(normalized_command):
    if "agent" in normalized_command:
        if "--local" not in normalized_command:
            final_command.append("--local")
        if agent_name and "--session-id" not in normalized_command:
            final_command.extend(["--session-id", agent_name])  # ← 固定复用!
        if prompt:
            final_command.extend(["--message", prompt])

完美命中需求! ClawTeam 天生就是这么设计的。

适配我们需求的可能性

需求 满足度 说明
复用同一个 main 会话 完美支持 每个 agent 固定 session-id = agent-name
contextId 复用 天然支持 同一个 agent 永远复用同一个
防止会话爆炸 彻底解决 每个 agent 只有一个会话
代码改动 极小 已经原生实现了

优点

  • 设计完全符合需求 —— 每个 agent 固定一个会话 ID,永久复用
  • 基于 tmux 的真实隔离,每个 agent 有独立工作区
  • 支持多种 CLI agentOpenClaw/Claude Code/Codex/Cursor 等)
  • 成熟的团队协作流程,agents 可以自组织

缺点

  • 需要 tmux 环境(开发机器一般都有)
  • 需要 git worktree(每个 agent 一个分支),对于长期固定角色(如三国量化团队的赵云/张飞/关羽),这个设计反而更好,因为每个将军有独立工作区
  • Python 项目,和当前 TypeScript 的 a2a-gateway 需要集成

方案三:OpenAkita(轻量 A2A 执行框架)

项目概况

  • 定位:全功能开源多代理 AI 助手桌面应用
  • 特点:完整的 AI 公司组织 orchestration,支持 IM 绑定
  • 作者OpenAkita 社区,活跃开发中

架构分析

核心设计 —— 会话管理

# 来自 openakita/sessions/manager.py
def get_or_create_session(...):
    session_key = f"{channel}:{chat_id}:{user_id}"
    if thread_id:
        session_key += f":{thread_id}"
    
    # 检查缓存
    if session_key in self._sessions:
        session = self._sessions[session_key]
        session.touch()
        return session  # ← 复用同一个会话!
    
    # 只有不存在才新建
    if create_if_missing:
        session = self._create_session(...)
        self._sessions[session_key] = session
        return session

天生完美设计! 同一个 (channel, chat_id, user_id) → 同一个会话。

适配我们需求的可能性

需求 满足度 说明
复用同一个 main 会话 完美支持 session_key 相同就复用
contextId 复用 完美支持 contextId 可以作为 session_key 的一部分
防止会话爆炸 彻底解决 只有全新对话才新建会话
代码改动 需要集成 OpenAkita 是完整应用,需要集成到 OpenClaw

优点

  • 会话管理设计非常正确,天生满足需求
  • 功能极其丰富:30+ LLMs、89+ 工具、6 IM 平台、插件系统、6层沙箱安全
  • 活跃开发,社区活跃
  • 支持桌面/Web/Mobile 多端访问

缺点

  • 是完整的独立应用,不是 OpenClaw 插件
  • 集成成本较高,需要重写 A2A 网关适配层
  • 对于我们三国量化团队固定角色场景,有些太重了

方案四:当前 a2a-gateway(已修复)

当前状态

我们刚才已经完成了两个修复:

修复 1(赵云修复)client.ts 透传 contextId

// 原来缺少这一行,现在加上了:
contextId: (message.contextId as string) || uuidv4(),

效果: 同一个 contextId → 复用同一个 A2A 会话

修复 2(诸葛亮修复)executor.ts 增加直接转发到 main 会话选项

const FORWARD_TO_MAIN_SESSION = true;
const TARGET_MAIN_SESSION_KEY = `agent:${agentId}:main`;

if (FORWARD_TO_MAIN_SESSION) {
  // 提取消息 → 转发到 main 会话 → 立即完成任务 → return
  this.api.sessionsSend({
    sessionKey: TARGET_MAIN_SESSION_KEY,
    message: messageText,
  });
  eventBus.finished();
  return;  // ← 加上了 return,阻止后续执行
}

效果: 所有 A2A 消息直接进入 agent:xxx:mainA2A 会话只做转发,不处理业务

适配我们需求的分析

需求 满足度 说明
复用同一个 main 会话 完美满足 所有消息直接转发到 main
contextId 复用 已经修复 同一个 contextId 复用同一个 A2A 会话
防止会话爆炸 业务会话不会爆炸 业务会话只有一个 main,A2A 会话很小且很快结束
代码改动 已经完成 两个小修复,已经测试通过

优点

  • 已经实现,已经测试,已经工作
  • 改动极小,不破坏现有架构
  • 完全满足核心需求:所有业务消息进入 main,不会爆炸
  • 可配置:如果需要 contextId 复用 A2A 会话,也支持
  • 对现有系统影响最小,风险最低

缺点

  • A2A 框架本身每次还是会创建一个空的 a2a: 会话(SDK 设计限制,无法避免)
  • 但这些会话创建后立即结束,不处理业务,占用空间很小,TTL 会自动清理
  • 实际使用中不会有问题

方案对比总结

方案 设计符合度 实现成本 风险 适合场景 评分
当前 a2a-gateway 修复 极低(已完成) 极低 OpenClaw 原生 A2A 网关,保持现状 5/5
ClawTeam 中等(需要集成) 大型团队协作,每个 agent 独立工作区 5/5
OpenAkita 高(完整应用) 全功能 IM 绑定多代理应用 4/5
Network-AI 中等(需要改造) 跨框架混合代理,需要协调并行任务 3/5

我的决定

推荐方案:保持当前修复方案

理由

  1. 已经完美满足需求

    • 所有 A2A 消息直接进入目标 agent 的 main 会话
    • 业务会话永远只有一个,不会爆炸
    • 同时支持 contextId 复用 A2A 会话(如果你需要这个特性)
    • 已经测试验证通过
  2. 改动最小,风险最低

    • 只改了两行关键代码
    • 不破坏现有架构
    • 不引入新的依赖
    • 回滚容易
  3. 符合三国量化团队架构

    • 我们已经有固定的团队分工(诸葛亮/庞统/赵云/张飞/关羽/姜维/司马懿)
    • 每个将军有固定的 main 会话
    • 所有消息都进入 main 会话,保持上下文连续性
    • 这正是我们需要的

如果未来需要更复杂的团队协作,可以升级到 ClawTeam

ClawTeam 的设计也非常好,它:

  • 每个 agent 固定 session-id,天生复用同一个会话
  • 基于 git worktree 隔离工作区,适合大型项目
  • 如果我们未来需要动态 spawn 临时 worker agentsClawTeam 是非常好的选择

但对于我们当前固定成员的场景,当前修复方案已经足够,更简单。


验证结论

我们刚才的测试已经证明:

  1. contextId 透传修复成功 —— 同一个 contextId 复用同一个 A2A 会话
  2. 直接转发到 main 修复成功 —— 所有业务消息进入 agent:xxx:main
  3. 业务会话不会爆炸 —— 永远只有一个 main 会话
  4. 上下文保持连续 —— 所有消息都在同一个会话里

问题已经解决! 🎉


下一步建议

  1. 保持当前方案继续使用,观察运行情况
  2. 如果发现空 A2A 会话累积太多,可以配置 OpenClaw TTL 自动清理
  3. 如果未来需要动态创建临时 agents,可以考虑集成 ClawTeam
  4. 如果需要完整的 IM 绑定多代理应用,可以考虑 OpenAkita

调研完成 —— 所有四个方案都已精读分析,决定已经做出,当前修复方案完美满足需求。