11.6 VoteWorkflow 投票聚合
`VoteWorkflow` 实现了投票聚合编排模式——多个 Voter Agent 并行对同一问题独立投票,结果通过聚合器(Aggregator)合并为最终决策。适用于需要多方共识的决策场景。
执行流程
sequenceDiagram
participant U as 用户
participant WF as VoteWorkflow
participant E as WorkflowEngine
participant V1 as Voter 1
participant V2 as Voter 2
participant V3 as Voter 3
participant AG as Aggregator
U->>WF: as_agent().run(input)
WF->>E: 构建图 source→FanOut→[V1,V2,V3]→FanIn→Aggregator
E->>E: SuperStep 启动
par 并行投票
E->>V1: 消息分发
V1-->>E: 投票结果
and
E->>V2: 消息分发
V2-->>E: 投票结果
and
E->>V3: 消息分发
V3-->>E: 投票结果
end
E->>E: FanIn 栅栏等待全部投票
E->>AG: 聚合结果
AG-->>U: 最终决策
内部建图:`source → FanOut → [Voter₁, ..., Voterₙ] → FanIn → Aggregator → output`
核心接口
IVoteAggregator — 投票聚合策略
pub trait IVoteAggregator: Send + Sync {
fn aggregate(&self, votes: &[String]) -> Result<String>;
}
内置聚合器
| 聚合器 | 策略 | 行为 | |--------|------|------| | `MajorityAggregator` | 多数决 | 出现次数最多的选项胜出 | | `UnanimousAggregator` | 全票通过 | 所有投票相同则通过,否则返回错误 | | `WeightedAggregator` | 加权投票 | 根据预设权重计算加权结果 |
API 参考
VoteWorkflowBuilder
use rust_agent_workflow::{
VoteWorkflowBuilder, MajorityAggregator, WeightedAggregator,
};
// 多数决
let workflow = VoteWorkflowBuilder::new()
.add_voter(analyst_a)
.add_voter(analyst_b)
.add_voter(analyst_c)
.aggregator(MajorityAggregator)
.build()?;
let agent: Arc<dyn IAgent> = workflow.as_agent();
let stream = agent.run(messages, session, None).await?;
加权投票
let workflow = VoteWorkflowBuilder::new()
.add_voter(senior_analyst) // 权重 0.5
.add_voter(junior_analyst) // 权重 0.3
.add_voter(intern) // 权重 0.2
.aggregator(WeightedAggregator::new(vec![0.5, 0.3, 0.2]))
.build()?;
自定义聚合器
use rust_agent_workflow::IVoteAggregator;
struct ConsensusAggregator {
threshold: f64,
}
impl IVoteAggregator for ConsensusAggregator {
fn aggregate(&self, votes: &[String]) -> Result<String> {
use std::collections::HashMap;
if votes.is_empty() {
return Err(AgentError::WorkflowError("No votes".into()));
}
let total = votes.len() as f64;
let mut counts: HashMap<&str, usize> = HashMap::new();
for v in votes { *counts.entry(v.as_str()).or_default() += 1; }
let (winner, count) = counts.iter()
.max_by_key(|(_, &c)| c)
.unwrap();
if *count as f64 / total >= self.threshold {
Ok(winner.to_string())
} else {
Err(AgentError::WorkflowError(
format!("Consensus not reached: {:.0}%", *count as f64 / total * 100.0)
))
}
}
}
完整示例
use std::sync::Arc;
use rust_agent_core::{IAgent, ChatMessage, Content};
use rust_agent_workflow::{VoteWorkflowBuilder, MajorityAggregator};
use rust_agent_framework::AgentBuilder;
use futures_util::StreamExt;
async fn run_consensus_vote() -> anyhow::Result<()> {
let client = DeepSeekChatClient::new(/* ... */)?;
let voter_a = AgentBuilder::new("voter_a")
.chat_client(client.clone())
.instructions("你是评审专家。对方案给出'A-通过'、'B-修改后通过'或'C-否决'的投票。只输出投票结果。")
.build()?;
let voter_b = AgentBuilder::new("voter_b")
.chat_client(client.clone())
.instructions("你是评审专家。对方案给出'A-通过'、'B-修改后通过'或'C-否决'的投票。只输出投票结果。")
.build()?;
let voter_c = AgentBuilder::new("voter_c")
.chat_client(client.clone())
.instructions("你是评审专家。对方案给出'A-通过'、'B-修改后通过'或'C-否决'的投票。只输出投票结果。")
.build()?;
let workflow = VoteWorkflowBuilder::new()
.add_voter(voter_a)
.add_voter(voter_b)
.add_voter(voter_c)
.aggregator(MajorityAggregator)
.build()?;
let agent: Arc<dyn IAgent> = workflow.as_agent();
let input = vec![ChatMessage::user("评审方案:在项目中使用 Rust 替代 C++ 作为主要开发语言")];
let mut stream = agent.run(input, None, None).await?;
while let Some(chunk) = stream.next().await {
if let Ok(result) = chunk {
for content in &result.contents {
if let Content::Text(ref t) = content {
print!("{}", t.delta);
}
}
}
}
Ok(())
}
适用场景
| 场景 | 说明 | |------|------| | 评审委员会 | 多位专家独立评审后聚合决策 | | 多模型投票 | 不同 LLM 对同一问题独立回答后取多数 | | 风险决策 | 多视角评估风险等级后加权聚合 | | 质量审查 | 多个审查员独立评分后汇总 |
注意事项
1. **并行执行**:所有 Voter 在同一 SuperStep 中并行执行,响应时间约等于最慢的 Voter 2. **FanIn 栅栏**:所有 Voter 完成后才触发 Aggregator 3. **聚合器可扩展**:实现 `IVoteAggregator` trait 即可自定义聚合策略 4. **引擎驱动**:由 `WorkflowEngine` 驱动,自动获得事件流和检查点