我用 RTS 游戏的方式管理了 100 个 AI Agent,效率提升了 10 倍

30 阅读6分钟

当 Agent 数量突破临界点,人类反而成了瓶颈。于是我做了个"星际指挥官"系统。

一个真实的痛点

上周,我的 OpenClaw 实例跑着 47 个 Agent。

开发 Agent 在写代码,文案 Agent 在写文档,数据分析 Agent 在跑报表...理论上,我应该像坐拥千军万马的将军一样威风。

实际上呢?

我开了 15 个终端窗口,7 个浏览器标签页。为了找一个 Agent 的执行结果,我要在 5 个窗口间来回切换。为了给 10 个 Agent 下同一个指令,我要复制粘贴 10 次。

更崩溃的是:我不知道哪个 Agent 在干活,哪个在摸鱼。

Terminal 1: [agent-dev-1] 执行中...
Terminal 2: [agent-dev-2] 等待输入
Terminal 3: [agent-copy-1] 连接超时
Terminal 4: [agent-data-1] ???
Terminal 5: [agent-dev-3] ...
...
Terminal 15: 我是谁?我在哪?

这不对。

AI 一分钟出结果,我花十分钟在协调。人类成了整个系统中最慢的一环。

一个疯狂的想法

那天晚上打了一局 RTS 游戏,突然灵光一现:

为什么不能用指挥军团的方式,来指挥 AI Agent?

想象一下这个场景:

  • 地图视角:所有 Agent 一览无余,谁在执行、谁在待命,一目了然
  • 框选编队:框选 10 个 Agent,Ctrl+1 编队,一键下发指令
  • 实时状态:血条显示执行进度,状态栏显示任务队列
  • 小地图:全局态势感知,异常自动告警

这不就是我需要的东西吗!

开始动手:Stratix 星策诞生了

说干就干。我给这个项目起名叫 Stratix 星策 —— Strategy(策略)+ 后缀 -ix(科技感),中文名"星策"(星间军团,智能策控)。

技术选型

前端 RTS 界面:Phaser 3(游戏引擎)
英雄设计器:Vue 3 + Vite
中间件网关:Node.js + WebSocket
Agent 框架:OpenClaw(兼容层)

为什么选 Phaser?因为它本身就是做游戏的,地图、精灵、框选、拖拽这些功能都是现成的。我只需要把 Agent 映射成游戏单位就行了。

核心架构

┌──────────────────────────────────────┐
│          前端层 (用户界面)            │
│  ┌────────────┐  ┌────────────┐     │
│  │ RTS 指挥中心│  │ 英雄设计器 │     │
│  │ (Phaser 3) │  │  (Vue 3)   │     │
│  └────────────┘  └────────────┘     │
└──────────────────────────────────────┘
              ↓ WebSocket
┌──────────────────────────────────────┐
│        星策网关 (中间件层)            │
│  · 指令转换与路由                     │
│  · 状态广播与同步                     │
│  · 多实例管理                         │
└──────────────────────────────────────┘
              ↓ HTTP/WebSocket
┌──────────────────────────────────────┐
│          Agent 层 (执行层)            │
│  ┌─────────┐ ┌─────────┐ ┌─────────┐│
│  │OpenClaw │ │OpenClaw │ │OpenClaw ││
│  │ (本地)  │ │ (远程)  │ │ (云端)  ││
│  └─────────┘ └─────────┘ └─────────┘│
└──────────────────────────────────────┘

关键设计决策:

  1. WebSocket 全双工通信:指令下发和状态回传走同一通道,延迟控制在 50ms 以内
  2. 中间件解耦:前端不直接连 Agent,通过网关中转,方便扩展和替换
  3. 配置即代码:Agent 配置存为 JSON,可以版本管理、模板化

核心功能实现

1. RTS 游戏化界面

这是最核心的部分。我用 Phaser 实现了:

地图系统

// 创建网格地图
const grid = this.add.grid(0, 0, 1920, 1080, 64, 64, 0x000000, 0, 0x00d9ff, 0.1);

// Agent 精灵
const agent = this.add.sprite(x, y, 'agent-sprite');
agent.setData('agentId', 'dev-alpha');
agent.setData('status', 'idle');

框选系统(最爽的功能)

// 鼠标拖拽框选
this.input.on('pointermove', (pointer) => {
  if (pointer.isDown && this.isSelecting) {
    this.selectionBox.width = pointer.x - this.startX;
    this.selectionBox.height = pointer.y - this.startY;
  }
});

// 检测框选范围内的 Agent
const selectedAgents = this.agents.filter(agent => 
  Phaser.Geom.Rectangle.Overlaps(this.selectionBox.getBounds(), agent.getBounds())
);

右键菜单指令

// 右键弹出指令菜单
['执行任务', '暂停', '查看日志', '重新配置'].forEach((cmd, i) => {
  const btn = this.add.text(x, y + i * 30, cmd, { fontSize: '16px' });
  btn.on('pointerdown', () => this.executeCommand(selectedAgents, cmd));
});

效果:

RTS 界面示意转存失败,建议直接上传图片文件

2. 英雄设计器

配置 Agent 不应该写 JSON。于是我做了个可视化配置器:

<template>
  <div class="designer">
    <div class="sidebar">
      <div class="section" @click="activeSection = 'soul'">⚡ Soul 配置</div>
      <div class="section" @click="activeSection = 'memory'">🧠 记忆系统</div>
      <div class="section" @click="activeSection = 'skills'">⚔ 技能树</div>
      <div class="section" @click="activeSection = 'model'">🎛 模型参数</div>
    </div>
    
    <div class="main">
      <!-- 动态表单 -->
      <component :is="currentSection" v-model="agentConfig" />
    </div>
  </div>
</template>

配置结构:

{
  "id": "dev-alpha",
  "name": "开发战士",
  "soul": {
    "role": "全栈开发工程师",
    "systemPrompt": "你是一名专业的..."
  },
  "memory": {
    "shortTerm": { "maxTokens": 4000 },
    "longTerm": { "enabled": true, "vectorStore": "pinecone" }
  },
  "skills": ["code_review", "write_code", "debug"],
  "model": {
    "provider": "openai",
    "model": "gpt-4-turbo",
    "temperature": 0.3
  }
}

模板库:一键导入"开发战士"、"文案刺客"、"数据法师"等预设配置。

3. 星策网关

中间件层,负责:

指令转换

// RTS 指令 -> OpenClaw 调用
class CommandTranslator {
  translate(rtsCommand: RTSCommand): OpenClawRequest {
    return {
      method: 'POST',
      endpoint: `/agents/${rtsCommand.agentId}/execute`,
      body: {
        task: rtsCommand.task,
        params: rtsCommand.params
      }
    };
  }
}

状态广播

// Agent 状态变化 -> 前端实时更新
wss.on('connection', (ws) => {
  ws.on('message', (msg) => {
    const { agentId, status, progress } = JSON.parse(msg);
    // 广播给所有连接的前端
    broadcast({ type: 'AGENT_UPDATE', agentId, status, progress });
  });
});

多实例管理

const instances = new Map<string, OpenClawInstance>();
instances.set('local', new LocalOpenClaw('/path/to/openclaw'));
instances.set('remote-1', new RemoteOpenClaw('https://server1.com'));
instances.set('remote-2', new RemoteOpenClaw('https://server2.com'));

// 统一接口
gateway.registerInstances(instances);

效果如何?

Before(传统方式):

  • 管理 50 个 Agent:需要 15+ 个窗口
  • 批量下发指令:复制粘贴 N 次,耗时 5 分钟
  • 查看执行状态:逐个检查,耗时 10 分钟
  • 发现问题 Agent:靠运气

After(Stratix):

  • 管理 50 个 Agent:1 个界面,一屏看完
  • 批量下发指令:框选 -> 右键 -> 执行,5 秒
  • 查看执行状态:实时刷新,0 延迟
  • 发现问题 Agent:地图上直接看到红色状态

量化指标:

指标传统方式Stratix提升
指令下发时间5 分钟5 秒60x
状态检查时间10 分钟实时
异常发现时间不确定< 1 秒???
窗口数量15+115x

技术亮点

1. 50ms 响应延迟

通过 WebSocket 全双工通信 + 优化的消息格式:

// 精简的消息格式
interface Message {
  t: number;      // timestamp (4 bytes)
  e: string;      // event type (1-2 bytes)
  d: any;         // data
}

// 总大小 < 1KB,序列化 + 传输 + 反序列化 < 10ms

2. 1000+ 并发连接

网关使用 Node.js Cluster 模式:

const cluster = require('cluster');
const numCPUs = require('os').cpus().length;

if (cluster.isMaster) {
  for (let i = 0; i < numCPUs; i++) {
    cluster.fork();
  }
} else {
  // 每个 worker 处理 1000 个连接
  createGatewayServer();
}

3. Phaser 性能优化

100 个 Agent 同时移动,如何保证 60fps?

// 1. 批量渲染
this.agentGroup = this.add.group();
this.agentGroup.addMultiple(agents);

// 2. 视口裁剪
this.cameras.main.setBounds(0, 0, 4000, 4000);
// 只渲染视口内的精灵

// 3. 降低更新频率
this.time.addEvent({
  delay: 100,  // 100ms 更新一次状态
  callback: updateAgentStatus
});

踩过的坑

1. WebSocket 断线重连

初期发现网络抖动会导致连接断开,状态丢失。

解决方案:

class ReconnectingWebSocket {
  connect() {
    this.ws = new WebSocket(url);
    this.ws.onclose = () => {
      setTimeout(() => this.connect(), 3000);  // 3 秒后重连
    };
    this.ws.onopen = () => {
      this.sendMessage({ type: 'SYNC_STATE' });  // 重连后同步状态
    };
  }
}

2. 状态同步冲突

多个前端同时操作,状态如何一致?

解决方案:CRDT(Conflict-free Replicated Data Types)

// 使用 LWW-Register (Last Write Wins)
interface State {
  value: any;
  timestamp: number;
}

function merge(local: State, remote: State): State {
  return local.timestamp > remote.timestamp ? local : remote;
}

3. Phaser 内存泄漏

长时间运行后,浏览器内存飙升。

解决方案:

// 及时销毁不再使用的对象
destroy() {
  this.agents.forEach(agent => {
    agent.destroy(true);  // true = destroy texture
  });
  this.agentGroup.destroy(true);
}

开源与未来

Stratix 星策已经在 GitHub 开源:

🔗 GitHub: github.com/stratix-rts
💬 Discord: discord.gg/3NysCNbe

当前功能(MVP):

  • ✅ RTS 游戏化界面
  • ✅ 框选、编队、批量指令
  • ✅ 英雄设计器(可视化配置)
  • ✅ 星策网关(多实例管理)
  • ✅ 实时状态同步

未来规划:

  • 🔜 Agent 模板市场
  • 🔜 任务编排(DAG 工作流)
  • 🔜 多人协作(实时同步)
  • 🔜 AI 自动编排(AI 指挥 AI)

最后

如果你也在管理多个 Agent,感到力不从心,欢迎试试 Stratix。

一人成军,万智听命。


相关资源

如果这个项目对你有帮助,请给一个 ⭐ Star!


作者:Stratix Team
发布日期:2024年
标签:AI Agent, OpenClaw, Phaser, 可视化管理, RTS, 开源项目