当 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 ││
│ │ (本地) │ │ (远程) │ │ (云端) ││
│ └─────────┘ └─────────┘ └─────────┘│
└──────────────────────────────────────┘
关键设计决策:
- WebSocket 全双工通信:指令下发和状态回传走同一通道,延迟控制在 50ms 以内
- 中间件解耦:前端不直接连 Agent,通过网关中转,方便扩展和替换
- 配置即代码: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));
});
效果:
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+ | 1 | 15x |
技术亮点
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。
一人成军,万智听命。
相关资源
- 在线演示: stratix-rts.github.io/homepage/
- GitHub: github.com/stratix-rts
- Discord 社区: discord.gg/3NysCNbe
如果这个项目对你有帮助,请给一个 ⭐ Star!
作者:Stratix Team
发布日期:2024年
标签:AI Agent, OpenClaw, Phaser, 可视化管理, RTS, 开源项目