11.1 编排引擎概述
RAF 的多智能体编排引擎是一个图驱动的异步工作流执行系统,参考 Microsoft Agent Framework (MAF) 的 Orchestrator 设计模式,提供完整的图拓扑定义、SuperStep 执行模型、状态管理、检查点恢复、事件驱动机制和全链路流式可观测性。
核心架构
graph TB
subgraph "编排模式 Orchestrations"
SEQB[SequentialWorkflowBuilder]
CONB[ConcurrentWorkflowBuilder]
HOB[HandoffWorkflowBuilder]
GC[GroupChatWorkflowBuilder]
MAG[MagenticWorkflowBuilder]
VOTE[VoteWorkflowBuilder]
end
subgraph "图引擎 Graph Engine"
WG[WorkflowGraph]
WE[WorkflowEngine]
WR[WorkflowRuntime]
EVT[EventBus]
end
subgraph "执行器 Executors"
AE[AgentExecutor]
FE[FunctionExecutor]
HTE[HumanTaskExecutor]
SFE[SubFlowExecutor]
CE[CompensableExecutor]
end
subgraph "持久化 Persistence"
CP[CheckpointManager]
FCS[FileCheckpointStore]
ICS[InMemoryCheckpointStore]
end
SEQB --> WG
CONB --> WG
HOB --> WG
GC --> WG
MAG --> WG
VOTE --> WG
WG --> WE
WE --> WR
WE --> AE
WE --> FE
WE --> HTE
WE --> SFE
WE --> CE
WE --> CP
WE --> EVT
CP --> FCS
CP --> ICS
核心设计链路
所有编排模式统一的构建-执行-门面链路:
XXXWorkflowBuilder.build() → Workflow.as_agent() → IAgent
前端与编排系统只与 `IAgent` 接口交互,编排细节(图结构、SuperStep、边路由)完全透明。
关键组件
WorkflowGraph — 不可变图定义
`WorkflowGraph` 是工作流的唯一真相来源。它定义了不可变拓扑结构,通过 `WorkflowBuilder` 构建后冻结。
pub struct WorkflowGraph {
nodes: HashMap<String, Node>, // 全部节点,按 ID 索引
edges: HashMap<String, HashSet<Edge>>, // 边,按源节点 ID 分组
ports: HashMap<String, RequestPort>, // 外部请求端口
output_node_ids: HashSet<String>, // 标记为输出的节点 ID
start_node_id: String, // 入口节点 ID
}
图构建后自动执行验证: - **入口节点存在性**:`start_node_id` 必须在 `nodes` 中 - **边引用完整性**:所有边的源和目标节点必须存在 - **BFS 可达性**:从入口出发的所有可达节点检测;不可达节点仅产生警告 - **DFS 环检测**:三色标记法检测有向图中的环;显式标记 `is_loopback = true` 的边不会被检测为环
Node — 图节点
每个节点关联一个执行器,并支持多种运行时配置:
pub struct Node {
pub id: String,
pub executor: Arc<dyn IExecutor>,
pub is_output: bool,
pub retry: Option<RetryOptions>, // 节点重试策略
pub timeout: Option<Duration>, // 单节点超时
pub loop_options: Option<LoopOptions>, // 循环配置(最大迭代次数、循环变量)
}
Edge — 有向边
支持三种边类型,实现灵活的消息路由:
| 边类型 | API | 行为 | |--------|-----|------| | `DirectEdge` | `add_edge(src, dst)` | 1:1 路由,支持 `IEdgeCondition` 条件过滤 | | `FanOutEdge` | `add_fan_out_edge(src, vec![...])` | 1:N 广播,消息通过 `Arc` 零拷贝共享 | | `FanInEdge` | `add_fan_in_edge(vec![...], dst)` | N:1 栅栏同步,所有源到达后才触发目标 | | `LoopbackEdge` | `add_loopback_edge(src, dst)` | 显式标记的循环回边,图校验允许 |
pub struct DirectEdgeData {
pub edge_id: EdgeId,
pub source_id: String,
pub sink_id: String,
pub label: Option<String>,
pub condition: Option<Arc<dyn IEdgeCondition>>,
pub is_loopback: bool, // 标记为循环回边
}
IExecutor — 执行器接口
每个节点通过 `IExecutor` 定义其运行时行为,支持完整的生命周期钩子:
#[async_trait]
pub trait IExecutor: Send + Sync {
fn id(&self) -> &str;
fn accepted_types(&self) -> Vec<TypeTag>;
fn send_types(&self) -> Vec<TypeTag>;
fn is_output(&self) -> bool;
// 生命周期钩子
async fn on_init(&self, ctx: &dyn IWorkflowContext) -> Result<()>;
async fn on_checkpoint_save(&self, ctx: &dyn IWorkflowContext) -> Result<()>;
async fn on_checkpoint_restore(&self, ctx: &dyn IWorkflowContext) -> Result<()>;
async fn on_delivery_start(&self, ctx: &dyn IWorkflowContext) -> Result<()>;
async fn on_delivery_end(&self, ctx: &dyn IWorkflowContext) -> Result<()>;
async fn on_timer(&self, timer_name: &str, ctx: &dyn IWorkflowContext) -> Result<()>;
async fn compensate(&self, ctx: &dyn IWorkflowContext) -> Result<()>;
// 核心执行
async fn handle(
&self,
message: Arc<dyn Any + Send + Sync>,
ctx: &dyn IWorkflowContext,
progress: UnboundedSender<NodeProgress>,
) -> Result<HandlerResult>;
}
SuperStep 执行模型
RAF 采用 SuperStep 模型(类似 Google Pregel 的批量同步并行计算模型):
sequenceDiagram
participant E as WorkflowEngine
participant N1 as Node A
participant N2 as Node B
participant CK as CheckpointManager
loop 每个 SuperStep
E->>E: 获取当前活跃节点
par 并行执行
E->>N1: 分发消息
N1-->>E: 进度事件(NodeStreaming)
N1-->>E: HandlerResult
and
E->>N2: 分发消息
N2-->>E: 进度事件(NodeStreaming)
N2-->>E: HandlerResult
end
E->>E: 通过 EdgeRunner 路由消息
E->>E: 推导下一批活跃节点
E->>E: 检查循环迭代限制
E->>CK: 保存检查点
end
E->>E: 所有节点完成
每个 SuperStep 支持: - **并发控制**:通过 `Semaphore` 限制 `max_parallel_nodes` - **节点超时**:每个节点独立超时(`Node.timeout`) - **全局超时**:工作流整体超时(`WorkflowConfig.global_timeout`) - **节点重试**:指数退避,支持 `Fail/Skip/FallbackNode` 耗尽策略 - **补偿回滚**:节点失败后沿执行链反向调用 `compensate()` - **定时器**:节点可注册定时器,引擎在 SuperStep 循环中 poll 到期检查
流式可观测性:WorkflowEvent
整个编排过程通过事件流对外暴露,实现完全可观测:
#[derive(Clone, Serialize)]
#[serde(tag = "event_type", content = "data")]
pub enum WorkflowEvent {
// 工作流生命周期
WorkflowStarted { session_id, graph_node_ids, start_node_id },
WorkflowCompleted { total_steps, total_nodes, total_usage },
WorkflowError { error, node_id },
WorkflowTimeout { elapsed },
// SuperStep 生命周期
SuperStepStarted { step_number, active_nodes },
SuperStepCompleted { step_number, outputs_count },
// 节点生命周期
NodeInvoking { node_id, node_name, step_number },
NodeStreaming { node_id, chunk: NodeChunk },
NodeCompleted { node_id, messages_produced, usage },
NodeFailed { node_id, error },
// 暂停/恢复
WorkflowHalted { step_number, reason },
WorkflowResumed { step_number },
// 定时器/外部事件
TimerFired { node_id, timer_name },
ExternalEventReceived { port_id, signal_name, timer_id, timestamp },
// 自定义
Custom { key, data },
}
每个 `NodeStreaming` 携带 `node_id`,前端可据此实现: - DAG 图实时高亮(`NodeInvoking` 变色,`NodeCompleted` 绿色) - 每节点独立打字机效果(按 `node_id` 分组展示) - 工具调用卡片(`ToolCallStart` / `ToolCallArgs` / `ToolCallEnd` / `ToolResult`) - 多节点并行进度条 - Token 用量仪表(`UsageUpdate` 累计)
执行器类型一览
| 执行器 | 用途 | 特点 | |--------|------|------| | `AgentExecutor` | 包装 `IAgent` 为 `IExecutor` | 流式桥接 IA 到引擎,全链路 Streaming | | `FunctionExecutor` | 执行纯函数/闭包 | 泛型参数 I→O,用于条件判断、数据转换 | | `HumanTaskExecutor` | 人工审批/输入 | 暂停工作流等待外部 `ResumeCommand` 注入 | | `SubFlowExecutor` | 动态子流程 | 运行时构造子图并作为子引擎执行 | | `CompensableExecutor` | Saga 补偿 | 为任意 Executor 附加补偿函数 |
事件驱动机制
工作流引擎支持外部事件注入:
pub enum ExternalEvent {
MessageReceived { port_id: String, payload: Value },
SignalReceived { signal_name: String, payload: Value },
TimerElapsed { timer_id: String },
}
通过 `EventBus`(基于 tokio broadcast channel)进行事件分发。外部系统通过 `WorkflowEngine::inject_event()` 注入事件,引擎将其包装为 `WorkflowEvent::ExternalEventReceived` 广播。
编排模式总览
RAF 提供六种编排模式,每种通过专属 Builder 构建:
| 编排模式 | Builder | 适用场景 | 对应 MAF | |---------|---------|---------|---------| | **Sequential** | `SequentialWorkflowBuilder` | 流水线处理、阶段性任务 | `SequentialWorkflow` | | **Concurrent** | `ConcurrentWorkflowBuilder` | 并行分析、多角度评估 | `ConcurrentWorkflow` | | **Handoff** | `HandoffWorkflowBuilder` | 智能路由、专家分发 | `HandoffWorkflow` | | **GroupChat** | `GroupChatWorkflowBuilder` | 多 Agent 讨论、轮流发言 | `GroupChatWorkflow` | | **Magentic** | `MagenticWorkflowBuilder` | 自主编排、推理-行动循环 | `MagenticOne` | | **Vote** | `VoteWorkflowBuilder` | 投票聚合、多方决策 | — |
所有编排模式内部由 `WorkflowEngine` 驱动,自动获得检查点、重试、超时、事件等基础设施能力。每种模式通过 `as_agent()` 收敛为 `Arc<dyn IAgent>` 统一门面。
Builder DSL 网关语义
`WorkflowBuilder` 提供声明式网关 DSL:
| 网关 | 方法 | 行为 | |------|------|------| | 并行网关 | `parallel_gateway(src, branches)` | 自动创建 FanOut 边,所有分支同时执行 | | 排他网关 | `exclusive_gateway(src, branches, default)` | 据条件创建多条带条件的 DirectEdge,仅一条激活 | | 包容网关 | `inclusive_gateway(src, branches)` | 所有满足条件的分支并行执行 |