EnerOS v0.21.0 版本说明
发布日期:2025-06-22 版本代号:Swarm Git Tag:v0.21.0 支持状态:稳定(Stable) Crate 总数:48(新增 6 个) 测试用例数:6100+(新增 700+)
概述
EnerOS v0.21.0「Swarm」是 EnerOS 进入「多智能体协作」阶段的首个版本,聚焦于多智能体协作(Multi-Agent Collaboration)。在此版本之前,EnerOS 的 Agent 运行时已经能够支撑单 Agent 完成调度、巡检、交易等任务,但电力系统的真实业务场景往往需要数十甚至上百个 Agent 协同工作——例如一个省级调度中心可能同时运行 200+ Agent,覆盖发电调度、负荷预测、新能源消纳、故障定位、巡检编排等业务。v0.21.0 将「多 Agent 协作」从应用层下沉为内核一等能力。
本版本引入了完整的多智能体协作框架:Agent 通信协议(ACP)、任务分解与分配器(Task Dispatcher)、协商机制(Negotiation Protocol)以及集体决策(Collective Decision)引擎。Agent 之间不再是孤立的进程,而是构成一个可编排、可观测、可治理的「蜂群(Swarm)」。蜂群能够根据电网拓扑自动形成协作关系——例如某条线路发生故障时,故障定位 Agent、隔离 Agent、负荷转移 Agent、巡检 Agent 会基于电气连通性自动组成临时协作组,完成故障处置后自动解散。
v0.21.0 的核心设计哲学是「电网拓扑决定协作拓扑」——Agent 的协作关系不是开发者硬编码的,而是由电网的电气连通性、设备管辖关系、安全责任边界动态推导出来的。这使得协作具备电气语义:当拓扑发生变化(开关操作、设备投退)时,Agent 协作关系会自动重新平衡。
关键数据
| 指标 | 数值 | 说明 |
|---|---|---|
| 协作 Agent 规模 | 1-1024 | 单集群支持 |
| Agent 通信延迟 P99 | 180μs | 同节点共享内存 |
| 任务分发延迟 P99 | 850μs | 同节点 |
| 协商达成延迟 | < 50ms | 3 节点 PBFT |
| 集体决策吞吐 | 12 万条/秒 | 单集群 |
| 新增 Crate | 6 | 协作相关 |
| 新增测试 | 700+ | 含 80 个端到端 |
新特性
1. 多智能体协作框架
引入 eneros-swarm Crate,提供完整的多智能体协作运行时。Swarm 是一组协作 Agent 的逻辑集合,拥有独立的生命周期、共享的上下文、统一的任务队列与可观测的协作图谱。
Swarm 数据结构
use eneros_swarm::{Swarm, SwarmConfig, SwarmId, AgentRole, Permission};
use eneros_swarm::consensus::ConsensusProtocol;
// 创建一个蜂群
let mut swarm = Swarm::new(SwarmId::from("dispatch-swarm-1"))
.config(SwarmConfig {
max_agents: 64,
task_queue_capacity: 4096,
consensus_protocol: ConsensusProtocol::Pbft,
topology_aware: true,
auto_rebalance: true,
});
// 注册 Agent 角色
swarm.register_role(AgentRole::new("coordinator")
.replicas(1)
.permission(Permission::DispatchCommand))?;
swarm.register_role(AgentRole::new("executor")
.replicas(8)
.permission(Permission::ExecuteCommand))?;
swarm.register_role(AgentRole::new("observer")
.replicas(4)
.permission(Permission::ReadOnly))?;
// 启动蜂群
swarm.start().await?;
协作拓扑自动构建
Swarm 会根据电网拓扑自动构建 Agent 间的通信拓扑,使得协作关系具备电气语义:
// 基于电气连通性自动构建协作关系
swarm.bind_to_topology(&network)?;
// 当拓扑变化时(开关操作),协作关系自动重平衡
network.on_event(TopologyEvent::SwitchOpened(switch_id), |event| {
swarm.rebalance_on_topology_change(event);
});
与传统方案的对比
| 维度 | 传统方案(应用层编排) | EnerOS Swarm(内核一等公民) |
|---|---|---|
| 协作关系来源 | 开发者硬编码 | 拓扑自动推导 |
| 拓扑变更响应 | 重启服务 | 自动重平衡 |
| 通信机制 | 外部中间件 | 内核共享内存 |
| 故障接管 | 手动配置 | 自动选举 |
| 可观测性 | 应用日志 | 协作图谱 + 追踪 |
2. Agent 通信协议(ACP)
引入 eneros-swarm-acp(Agent Communication Protocol),定义 Agent 间消息交换的统一协议。ACP 借鉴 FIPA-ACL 语义,并针对电力场景扩展了电气语义原语。
消息类型
| 消息类型 | 语义 | 电力场景示例 |
|---|---|---|
| Request | 请求执行 | 请求执行开关操作 |
| Inform | 通知事实 | 通知故障定位结果 |
| Query | 查询信息 | 查询母线电压 |
| Propose | 提出建议 | 提出负荷转移方案 |
| Accept | 接受建议 | 接受转移方案 |
| Reject | 拒绝建议 | 拒绝越限方案 |
| Subscribe | 订阅事件 | 订阅拓扑变更 |
| Coordinate | 协调动作 | 协调多 Agent 隔离 |
消息结构
use eneros_swarm_acp::{AcpMessage, Performative, AgentId};
let msg = AcpMessage::new()
.from(AgentId::from("fault-locator-1"))
.to(AgentId::from("isolator-3"))
.performative(Performative::Inform)
.content(FaultLocation {
bus_id: 42,
distance_km: 3.2,
confidence: 0.97,
})
.ontology("grid-fault")
.reply_by(Duration::seconds(5));
swarm.send(msg).await?;
传输层
ACP 支持多种传输后端,自动根据 Agent 位置选择最优路径:
use eneros_swarm_acp::transport::{Transport, SharedMemory, TcpTransport};
// 同节点:共享内存 + 无锁队列(180μs)
let local = Transport::SharedMemory(SharedMemory::new()
.ring_size(4096)
.zero_copy(true));
// 跨节点:TCP + Protobuf(2.3ms)
let remote = Transport::Tcp(TcpTransport::new()
.compression(Compression::Zstd)
.tls(TlsConfig::from_file("agent.crt")?));
swarm.set_transport(local, remote);
传输性能对比
| 传输方式 | 延迟 P99 | 吞吐 | 适用场景 |
|---|---|---|---|
| 共享内存 | 180μs | 50 万/s | 同节点 |
| Unix Socket | 350μs | 20 万/s | 同主机跨进程 |
| TCP 本地 | 800μs | 10 万/s | 同机架 |
| TCP 跨节点 | 2.3ms | 5 万/s | 跨主机 |
3. 任务分解与分配
引入 eneros-swarm-dispatcher,提供任务分解(Task Decomposition)与分配(Dispatch)能力。复杂任务会被自动分解为子任务,并根据电气语义、优先级、负载情况选择合适的 Agent 执行。
任务分解
use eneros_swarm_dispatcher::{Dispatcher, Task, Decomposer};
let dispatcher = Dispatcher::new(&swarm);
// 复杂任务自动分解
let complex_task = Task::new("fault-handling")
.payload(FaultEvent {
bus_id: 42,
fault_type: FaultType::ShortCircuit,
});
let subtasks = Decomposer::decompose(&complex_task)?;
// 分解为:
// 1. fault-location(故障定位)
// 2. fault-isolation(故障隔离)
// 3. load-transfer(负荷转移)
// 4. inspection(巡检编排)
for sub in subtasks {
dispatcher.dispatch(sub).await?;
}
分发策略
use eneros_swarm_dispatcher::DispatchStrategy;
// 策略 1:就近分发(电气距离最近)
dispatcher.strategy(DispatchStrategy::NearestByElectricalDistance);
// 策略 2:负载均衡
dispatcher.strategy(DispatchStrategy::LeastLoaded);
// 策略 3:亲和性分发(同一区域优先)
dispatcher.strategy(DispatchStrategy::Affinity {
key: "region_id",
sticky: true,
});
// 策略 4:优先级分发
dispatcher.strategy(DispatchStrategy::Priority {
high_priority_agents: vec!["executor-0", "executor-1"],
});
// 分发任务
let task = Task::new("check-bus-1")
.target(BusId::from(1))
.priority(Priority::High)
.deadline(Duration::seconds(30));
let handle = dispatcher.dispatch(task).await?;
let result = handle.await?;
分发策略性能
| 分发策略 | 调度延迟 P99 | 吞吐 | 适用场景 |
|---|---|---|---|
| 就近 | 850μs | 5 万/s | 故障处置 |
| 负载均衡 | 1.2ms | 12 万/s | 批量任务 |
| 亲和性 | 950μs | 8 万/s | 区域任务 |
| 优先级 | 1.5ms | 6 万/s | 紧急任务 |
4. 协商机制
引入 eneros-swarm-negotiation,提供多种协商协议,确保多 Agent 在关键决策上达成一致。电力系统的关键操作(开关操作、发电机出力调整、负荷切除)必须经过协商,防止单点错误导致电网事故。
协商协议选择
use eneros_swarm_negotiation::{Negotiator, Protocol};
// PBFT:3-7 节点小集群,强一致性
let negotiator = Negotiator::new(Protocol::Pbft {
n: 3,
f: 0,
timeout: Duration::milliseconds(500),
});
// Raft:3-9 节点,CP 系统
let negotiator = Negotiator::new(Protocol::Raft {
election_timeout: Duration::milliseconds(150),
heartbeat_interval: Duration::milliseconds(50),
});
// Gossip:大规模最终一致
let negotiator = Negotiator::new(Protocol::Gossip {
fanout: 6,
interval: Duration::milliseconds(100),
});
关键操作协商
// 开关操作必须经过协商
let proposal = NegotiationProposal::new("open-switch-42")
.payload(Command::OpenSwitch { id: 42 })
.required_quorum(Quorum::TwoThirds)
.timeout(Duration::seconds(5));
match negotiator.propose(proposal).await {
Ok(consensus) => {
ctx.syscall(ExecuteCommand(consensus.command)).await?;
}
Err(NegotiationError::Timeout) => {
log::warn!("开关操作未达成协商共识");
}
}
协商协议对比
| 协议 | 节点数 | 一致性 | 延迟 | 容错 | 适用场景 |
|---|---|---|---|---|---|
| PBFT | 3-7 | 强 | < 50ms | f < n/3 拜占庭 | 关键操作 |
| Raft | 3-9 | 强 | < 100ms | f < n/2 崩溃 | 配置变更 |
| Gossip | 任意 | 最终 | 100ms-1s | 任意分区 | 状态同步 |
5. 集体决策
引入 eneros-swarm-collective,支持多 Agent 集体决策。在多个 Agent 提出不同方案时(如多个负荷转移方案),通过投票、加权、拍卖等机制选出最优方案。
决策模式
use eneros_swarm_collective::{CollectiveDecision, Voting, Auction};
// 模式 1:多数投票
let decision = CollectiveDecision::new(Voting::Majority)
.proposals(vec![plan_a, plan_b, plan_c])
.voters(all_agents)
.decide().await?;
// 模式 2:加权投票(按 Agent 权重)
let decision = CollectiveDecision::new(Voting::Weighted)
.proposals(vec![plan_a, plan_b])
.weight("dispatcher", 5.0)
.weight("protection", 3.0)
.decide().await?;
// 模式 3:拍卖(价高者得)
let auction = Auction::new("load-transfer-job")
.bidders(executors)
.bid_fn(|agent| agent.estimate_cost(&job))
.settle().await?;
决策记录
所有集体决策均落盘审计,包含提案、投票、结果、时间戳:
// 决策记录可追溯
let record = decision.record();
assert!(record.proposals.len() == 3);
assert!(record.winner == "plan_b");
assert!(record.votes_for == 5);
assert!(record.votes_against == 2);
改进
- Agent 通信:将 Agent 间通信从基于 TCP 改为基于共享内存 + 无锁队列,单节点消息延迟从 2.3ms 降至 180μs
- 拓扑感知调度:调度器现在会感知电气岛边界,避免跨岛任务分发
- 可观测性:新增
eneros-swarm-traceCrate,提供协作图谱可视化 - 故障检测:Agent 心跳检测从 5 秒缩短至 500ms,故障发现更及时
- 资源隔离:每个 Swarm 拥有独立的任务队列与内存池,避免相互干扰
Bug 修复
- 修复
eneros-agent在 Agent 数量超过 64 时调度器死锁的问题(#2103) - 修复
eneros-agent心跳超时后未清理 Agent 上下文的内存泄漏(#2107) - 修复
eneros-topology拓扑变更事件在 Swarm 模式下广播延迟过高的问题(#2112) - 修复
eneros-constraint在多 Agent 并发校验时出现竞态条件的问题(#2118) - 修复
eneros-timeseries在聚合查询时区处理错误(#2120)
破坏性变更
Agent::run签名变更:新增swarm_ctx: &SwarmContext参数,原有签名迁移至Agent::run_standaloneDispatcher::dispatch返回类型:从Result<TaskResult>改为Result<TaskHandle>,需.await获取结果ConsensusEngine重命名:统一更名为Negotiator,原名称保留别名至 v0.25.0
升级指南
从 v0.20.0 升级至 v0.21.0:
- 执行
cargo update -p eneros-swarm - 将
Agent::run调用替换为Agent::run_standalone,或迁移至 Swarm 模式 - 更新
Dispatcher::dispatch调用以适配新的TaskHandle返回类型 - 参考
docs/migration/v0.21.0.md获取详细迁移步骤
致谢
感谢 12 位贡献者参与本版本开发,特别感谢调度算法、共识协议、通信传输三个工作组的辛勤付出。