本文深入揭秘 media_agent 的架构设计——一个用 Rust 构建的 ComfyUI 智能编排引擎。文章详细拆解了五层架构(对话交互层、LLM 智能编排层、ComfyUI 通信层、工作流执行引擎、推理后端集成层),并对比了与 Python 版 ComfyUI 的性能差异。适合对 AI 图片生成、Rust 系统编程、Agent 架构感兴趣的开发者阅读。
关键词:ComfyUI, Rust, media_agent, LLM 编排, 工作流引擎, AI 图片生成, Gliding Horse, Agent 架构, stable-diffusion.cpp, 多后端推理

玩 Stable Diffusion 的人都知道 ComfyUI 的好——节点化、可复现、功能强大。但用久了也明白它的痛:工作流是死的。文生图、图生图、ControlNet、LoRA 叠加……每次需求变了,就得重新拖拽节点、调整参数、一遍遍抽卡。

我就在想:如果让 AI 自己来编排工作流呢?

于是我把之前写的 Gliding Horse(流马)——一个完整的 AI Agent 操作系统——的能力注入到了图片生成领域,用 Rust 从零构建了 media_agent。它不是一个 ComfyUI 的 Rust 复刻,而是在 ComfyUI 成熟的节点思想之上,架设了一层 LLM 智能编排引擎,让图片/视频生成从“手工作坊”进化到了“自动化流水线”。

这篇文章,我就把 media_agent 的五层架构完整拆开给你看。

一、五层架构总览:从推理芯片到对话大脑
media_agent 采用严格的五层分层设计,每一层都有明确的职责边界:

Layer 1: 推理后端集成层

Backend A
stable-diffusion.cpp
扩散主干

Backend B
llama.cpp GGUF
LLM文本编码

Backend C
本地CLIP/VAE处理

后端路由器
按模型类型自动选择

Layer 2: 工作流执行引擎 (Rust 实现)

验证器
拓扑排序

任务队列
优先级堆

执行器
逐节点执行

层级缓存
节点指纹匹配

事件系统
实时进度推送

Layer 3: ComfyUI 通信层

HTTP 客户端
/prompt /history /view

WebSocket 客户端
进度/预览/完成

素材管理器
上传/下载/缓存

Layer 4: LLM 智能编排层

LLM 路由器
按复杂度选模型

意图解析器
Function Calling

任务规划器
多步推理拆解

模板选择器
LLM推理 + 规则

工作流校验器
本地校验

质量评估器
VLM评分

Layer 5: 对话交互层 (Web UI)

多轮对话引擎

富文本渲染
图片/视频/进度卡片

素材选择器
音视频时间轴

这套架构的核心哲学是:让 LLM 做决策,让 Rust 做执行。上方三层负责“想”,下方两层负责“做”。LLM 不需要知道底层推理引擎的细节,推理引擎也不需要关心用户意图——它们通过标准化的工作流 JSON 协议通信。

二、Layer 4:LLM 智能编排层——这是 media_agent 的“大脑”
这是 media_agent 区别于传统 ComfyUI 最关键的一层,也是 Gliding Horse 的核心能力所在。它包括八个子组件:

LLM 路由器:根据任务复杂度自动选择模型——简单参数填充用本地小模型,复杂创意任务上 GPT-4 或 Claude。
意图解析器:通过 Function Calling 将用户的自然语言描述映射为具体的操作意图(T2I、I2I、ControlNet、视频生成……)。
任务规划器:将复杂需求拆解为多步执行计划,例如“把这张照片变成吉卜力风格,分辨率 2K”会被拆解为“图像加载→风格迁移→超分”。
模板选择器:从 29 个预置 JSON‑LD 工作流模板中匹配最接近的,LLM 根据意图和上下文推理选择。
参数填充器:基于选定的模板,LLM 自动推断并填充采样步数、CFG 值、种子、LoRA 权重等参数。
工作流校验器:在发送给执行引擎之前,本地做一次拓扑排序校验,确保没有循环依赖或缺失节点。
参数调优器:记录每次生成的质量反馈,形成闭环学习,下次同类任务自动优化参数。
质量评估器:可选调用 VLM(视觉语言模型)对生成结果进行美学/合规评分。
举个实际例子:用户输入“把这张照片里的背景换成赛博朋克城市,人物保持清晰”。

意图解析器识别出这是“I2I + ControlNet”任务。
模板选择器匹配到 controlnet_canny 模板。
参数填充器推断需要 Canny 边缘检测 ControlNet、背景替换 LoRA、denoise=0.75。
任务规划器生成 DAG:加载图像→Canny 预处理→KSampler(含 LoRA+ControlNet)→VAE 解码→输出。
工作流校验器确认 DAG 无环,发送到 Layer 2 执行。
整个过程,用户只需要说一句话。

三、Layer 2:工作流执行引擎——ComfyUI 的核心逻辑,Rust 实现
这是 media_agent 的“心脏”,完全用 Rust 重写了 ComfyUI 的执行引擎:

Validator:对工作流进行拓扑排序,检测循环依赖,输出缺失节点列表。
PromptQueue:基于二叉堆的优先级队列,支持队首插入和历史缓存。
PromptExecutor:逐节点执行工作流,管理缓存命中和事件推送。
HierarchicalCache:基于节点指纹的层级缓存——指纹由节点类型、输入参数和 IS_CHANGED 函数返回值联合哈希计算,最大化复用已有计算结果。
事件系统:通过 WebSocket 实时推送执行进度、中间预览图、完成或错误事件。
执行引擎的异步运行时基于 Tokio,充分利用 Rust 的无 GIL 原生并发特性,多个节点可以真正并行执行——这是 Python 版 ComfyUI 的 asyncio 无法做到的。

四、Layer 1:四后端混合推理
media_agent 不绑定单一推理引擎,而是设计了一个后端路由器,根据模型类型自动选择最优后端:

模型类型 推理后端 说明
扩散主干 (SD1.5/SDXL/SD3/Flux) stable-diffusion.cpp GPU 推理 (CUDA/Vulkan),支持 Flash Attention
LLM 文本编码器 (T5/Qwen) llama.cpp GGUF 高效 LLM 推理
CLIP/VAE 本地处理器 轻量组件本地执行
PyTorch 模型 预留接口 显存充足时可切换
后端路由器会根据当前 GPU 显存、模型大小等因素自动决策。例如显存小于 12GB 时,优先使用 stable-diffusion.cpp 而非 PyTorch,避免 OOM。

五、Gliding Horse 为 media_agent 注入了什么?
media_agent 的智能编排层本质上就是 Gliding Horse 的 Agent 能力在图片生成领域的垂直应用。具体来说:

动态 PDCA 编排:复杂任务自动拆解为 Plan→Do→Check→Act 循环,不合格自动重试调参。
JSON‑LD DAG 工作流:29 个预置模板和运行时编译的 DAG 都使用 JSON‑LD 表达,支持 SPARQL 查询和语义推理。
上下文管理:多轮对话的上下文不膨胀,历史摘要通过 IRI 索引,LLM 需要细节时按需检索。
工具调用门:参数填充器和后端路由器的调用经过 Schema 校验,确保不会传入非法参数。
可以说,Gliding Horse 是 Agent 操作系统,media_agent 是跑在这个系统上的图片生成应用。

六、与 Python 版 ComfyUI 的对比
维度 Python 版 ComfyUI media_agent
工作流编排 手动拖拽 自然语言 + LLM 自动编排
流程适应性 静态,改需求重搭 PDCA 动态调整,自动纠错
推理后端 PyTorch stable-diffusion.cpp + llama.cpp 混合
并发模型 asyncio (单线程) Tokio (真正多线程,无 GIL)
缓存策略 HierarchicalCache 同算法,Rust 实现,更快
节点定义 Python 类继承 Rust Trait,编译期类型检查
部署方式 Docker 单容器 Docker Compose 多服务
media_agent 不是在替代 ComfyUI,而是在它成熟的节点思想之上增加了一个“大脑”,同时用 Rust 重写了执行引擎以获得更好的性能和安全性。

八、实战:用 media_agent 生成一张赛博朋克图片
下面通过一个完整的 Rust 代码示例,展示如何调用 media_agent 的 API 完成从自然语言描述到图片生成的完整流程。

use media_agent::client::MediaAgentClient;
use media_agent::types::{GenerationRequest, ProgressEvent};
use std::path::PathBuf;
use tokio::time::{sleep, Duration};

#[tokio::main]
async fn main() -> Result<(), Box> {
// 1. 初始化客户端,连接 media_agent 服务
let client = MediaAgentClient::new(“http://127.0.0.1:8080”)?;

// 2. 构造自然语言生成请求
let request = GenerationRequest::builder()
    .prompt("赛博朋克城市夜景,霓虹灯闪烁,雨夜街道,高对比度,4K")
    .negative_prompt("模糊,低质量,水印,文字")
    .model("sd3.5-medium")          // 使用 SD3.5 模型
    .width(1024)
    .height(1024)
    .steps(30)
    .cfg_scale(7.0)
    .seed(42)                        // 固定种子保证可复现
    .build()?;

// 3. 提交任务,获取任务 ID
let task_id = client.submit_generation(request).await?;
println!("任务已提交,ID: {}", task_id);

// 4. 轮询进度事件,实时展示生成状态
loop {
    match client.poll_progress(&task_id).await? {
        ProgressEvent::Queued { position } => {
            println!("排队中,当前第 {} 位", position);
        }
        ProgressEvent::Running { progress, stage } => {
            println!("生成中:{}% - {}", progress, stage);
        }
        ProgressEvent::Preview { image_base64 } => {
            // 中间预览图(可选,可展示给用户)
            println!("收到中间预览({} 字节)", image_base64.len());
        }
        ProgressEvent::Completed { image_url } => {
            println!("生成完成!图片地址: {}", image_url);

            // 5. 保存结果到本地文件
            let output_path = PathBuf::from("cyberpunk_result.png");
            client.download_image(&image_url, &output_path).await?;
            println!("图片已保存至: {:?}", output_path);
            break;
        }
        ProgressEvent::Failed { error } => {
            eprintln!("生成失败: {}", error);
            return Err(error.into());
        }
    }
    sleep(Duration::from_millis(500)).await;
}

Ok(())

}
代码要点说明
MediaAgentClient:封装了与 media_agent 服务通信的 HTTP 和 WebSocket 接口,自动处理 JSON‑LD 工作流的序列化与反序列化。
GenerationRequest:构建器模式,将自然语言描述转换为 LLM 编排层可理解的意图结构,底层自动触发模板选择、参数填充和工作流校验。
进度事件:通过 poll_progress 轮询获取实时状态,支持排队、运行中百分比、中间预览和最终结果。
保存结果:download_image 方法将生成的图片从服务端缓存下载到本地文件系统。
运行这段代码前,请确保 media_agent 服务已启动(docker compose up -d),且 SD3.5 模型已下载。你也可以将 prompt 替换为任意自然语言描述,media_agent 会自动选择最合适的模板和参数。

七、开源与未来

Logo

openEuler 是由开放原子开源基金会孵化的全场景开源操作系统项目,面向数字基础设施四大核心场景(服务器、云计算、边缘计算、嵌入式),全面支持 ARM、x86、RISC-V、loongArch、PowerPC、SW-64 等多样性计算架构

更多推荐