从生成到创作:RabbitVis如何用Agent编排重塑视觉AI工作流
2026/9/25 0:06:24 网站建设 项目流程

视觉AI当下最大的瓶颈不是生成能力,而是连贯创作能力。单张图片生成已经非常成熟,输入一段提示词就能得到一张精致图像;但用户真正需要的往往是一个完整的视觉作品,比如一套海报、一段分镜脚本、一个产品主图和配套详情图,甚至是带叙事逻辑的短视频画面。这里的差距,正是视觉AI从「会生成」走向「能创作」要解决的问题。RabbitVis 这个探索性项目,把大模型生成、多模态理解、工具调用和流程编排放在同一个应用框架里,用一套可复现的工程方案演示视觉AI应用的新范式。本文以 RabbitVis 为例,梳理这种新范式的核心机制、整体设计、关键实现、验证方法以及生产化改造思路,适合正在做 AI 应用产品、视觉工具链或 Agent 工程的开发者参考。

1. 先理解视觉AI从「会生成」到「能创作」到底变了什么

1.1 「生成」和「创作」在工程上不是同一个问题

单次文生图任务,输入是一段提示词,输出是一张图片,整个链路是「理解提示词 -> 扩散采样 -> 解码图像」。这个链路已经有大量现成模型和开源工具可以覆盖,比如 Stable Diffusion、Flux、Midjourney 类接口。工程上关心的是采样步数、CFG Scale、负提示词、LoRA 加载这类参数。

但「创作」不同。以一张电商主图为例,用户真正要的不是随便生成一张图,而是「品牌调性统一、产品角度正确、背景干净、带营销文案、尺寸符合平台要求、和详情页风格一致」的一组图。这要求 AI 不只完成一次生成,而是完成一整套策划和制作流程:

  • 理解需求:从自然语言描述中抽取主体、风格、场景、用途。
  • 拆解任务:把一个复杂目标拆成多个可执行子任务,比如主体设计、背景生成、局部重绘、文案排版。
  • 调用工具:不同子任务可能需要不同模型或不同参数,比如外观一致性用 IP-Adapter,精细修改用局部重绘。
  • 迭代修正:生成结果不理想时,要能自动或半自动地回到前置步骤修改,而不是重新随机生成。
  • 组装输出:多张图片按模板或版式合成最终作品,并对应到不同尺寸和文件格式。

这就是视觉AI从「单点生成」走向「多步创作」的差别:创作是带状态、带目标、带校验的流程,而生成只是其中一个原子动作。

1.2 RabbitVis 选择的技术路线:不是又一个大模型,而是一个 Agent 编排层

RabbitVis 的定位不是训练一个新模型,而是把已有视觉模型、大语言模型和图像处理能力封装成可编排的 Agent 任务。它要解决的问题是:当用户提出一个模糊的创作目标时,系统如何把它变成一组可落地、可回溯、可修正的视觉任务。

这里有两个关键判断:

第一,视觉创作需要语言模型作为「宏观调度器」。大语言模型擅长任务理解、目标拆解、参数格式化和结果评价。图像生成模型擅长像素空间的具体输出。前者负责想清楚做什么,后者负责把它画出来。

第二,多步创作不能靠「一次提示词搞定」,必须保存中间状态。每一步生成结果要能被后续步骤引用,失败时还要能定位到具体环节。所以 RabbitVis 的架构里引入了一个工作流引擎,而不是简单把多个 API 串起来。

1.3 以「创作」为目标的视觉 AI 应用通常包含哪些核心能力

参考 RabbitVis 的设计,一个能「创作」的视觉 AI 应用至少需要具备五类能力:

能力模块作用典型依赖
意图理解把用户需求转成结构化创作方案LLM、多模态大模型
方案拆解把创作方案拆成有序的生成步骤LLM + 工作流模板
视觉生成完成具体图像/视频内容生成Diffusion 模型、GAN
资产管理管理参考图、生成图、LoRA、风格模板对象存储、向量数据库
校验反馈判断结果是否符合目标,决定是否重试多模态评分模型、规则引擎

这五类能力不是独立的工具集,而是需要通过一个统一的任务模型串联起来。RabbitVis 在这一点上选择用一个「创意蓝图(Creation Blueprint)」数据结构来承载整个创作任务。它既保存了用户原始需求,也保存了拆分后的步骤、每个步骤的入参出参、生成结果的状态,以及失败时的重试记录。这样整个创作过程才是可解释、可调试、可复用的。

2. RabbitVis 的总体设计:一个可复现的视觉创作应用骨架

2.1 整体模块划分和核心概念

RabbitVis 参考实现可以分为四个层次。第一层是接入层,负责接收用户请求,比如文本描述、参考图上传、创作类型选择。第二层是编排层,核心是 Agent 调度和任务流程管理,它决定创作者意图如何被拆解和执行。第三层是执行层,封装各类生成工具、图像处理工具和校验工具。第四层是资产层,负责统一保存和索引所有输入输出文件以及中间状态。

这种分层的核心意图是解耦。编排层不直接依赖具体模型厂商;执行层的模型可以替换;资产层独立演进。否则一旦换一个图像模型,整个流程都要跟着改,很难持续迭代。

RabbitVis 里最核心的概念是「创作任务(CreationTask)」。一个任务包含:任务 ID、用户需求、拆解后的步骤列表、每个步骤的执行状态、全局上下文、最终产物地址。结构上接近一个带状态机的 DAG 图,但为了保持简单,第一版可以先支持顺序执行和条件分支。

2.2 项目目录结构建议

实际开发时,目录结构直接影响后续维护成本。RabbitVis 第一版可以采用这样的结构:

rabbitvis/ ├── app/ │ ├── api/ # API 路由 │ │ ├── tasks.py # 创作任务接口 │ │ └── assets.py # 素材上传与查询接口 │ ├── core/ # 配置与基础设施 │ │ ├── config.py # 环境变量与配置 │ │ ├── storage.py # 文件与对象存储封装 │ │ └── logging.py # 日志初始化 │ ├── orchestration/ # 编排层 │ │ ├── planner.py # 用 LLM 拆解任务 │ │ ├── executor.py # 执行步骤并维护状态 │ │ └── workflow.py # 工作流定义与分支逻辑 │ ├── tools/ # 执行层工具 │ │ ├── text_to_image.py # 文生图工具 │ │ ├── img2img.py # 图生图工具 │ │ ├── inpaint.py # 局部重绘工具 │ │ └── evaluator.py # 质量评分工具 │ ├── schemas/ # 数据模型 │ │ ├── task.py │ │ └── blueprint.py │ └── main.py # FastAPI 入口 ├── tests/ # 单元测试与集成测试 ├── examples/ # 示例请求与配置 ├── requirements.txt └── .env.example

这个结构不是必须照搬,但有一个原则不要违背:编排层、执行层和 API 层之间不要互相 import 具体实现。例如planner.py只负责返回步骤列表,不直接调用某个图像模型的 SDK;真正调用发生在executor.py通过工具注册表找到对应工具并执行。

2.3 依赖选型和环境准备

RabbitVis 面向的是 Python 技术栈,因为视觉模型和 Agent 框架的生态都在 Python 侧更成熟。核心依赖可以分成三组:Web 框架、AI 推理和图像处理、Agent 编排。

依赖分组建议选型用途说明
Web 框架FastAPI + Uvicorn提供 REST API 和异步支持
图像生成diffusers + transformers加载 Diffusion 模型
图像处理Pillow + opencv-python图像缩放、合成、遮罩处理
Agent 编排LangGraph 或自研状态机管理多步任务状态和重试
LLM 调用openai SDK 或 langchain 兼容层调用语言模型做任务拆解
存储本地文件目录 + SQLite学习和演示阶段最低成本方案

学习环境快速跑通时,不需要引入 Redis 和 Postgre。SQLite 加本地文件目录已经能承载整个任务状态和素材管理。生产环境再替换为对象存储和关系数据库。

要注意依赖版本必须根据实际安装环境固定。下面是一个参考的requirements.txt片段:

fastapi>=0.110,<1.0 uvicorn[standard]>=0.29,<1.0 diffusers>=0.27,<1.0 transformers>=4.40,<5.0 sentencepiece>=0.1.99 opencv-python>=4.9 pillow>=10.0 pydantic>=2.6 python-dotenv>=1.0 sqlalchemy>=2.0

这里没有把特定视觉模型的版本写死,因为模型文件通常单独管理,不同机器使用不同硬件,需要单独下载。推荐把模型下载脚本放到scripts/目录,而不要放在应用代码里。

3. 核心实现:从文本创意到可分镜视觉作品的完整链路

3.1 用创意蓝图管理创作任务的输入和中间状态

RabbitVis 的核心数据结构是创意蓝图。它描述了一个视觉创作任务的完整过程。下面是一个简化版 Pydantic 模型:

from pydantic import BaseModel, Field from typing import List, Optional from enum import Enum class StepStatus(str, Enum): PENDING = "pending" RUNNING = "running" SUCCEEDED = "succeeded" FAILED = "failed" RETRYING = "retrying" class ToolCall(BaseModel): tool_name: str params: dict = Field(default_factory=dict) result_ref: Optional[str] = None class CreationStep(BaseModel): step_id: str description: str tool_calls: List[ToolCall] = Field(default_factory=list) status: StepStatus = StepStatus.PENDING retry_count: int = 0 error_message: Optional[str] = None output_ref: Optional[str] = None class CreationBlueprint(BaseModel): task_id: str user_request: str creative_goal: str = "" style_tags: List[str] = Field(default_factory=list) steps: List[CreationStep] = Field(default_factory=list) global_context: dict = Field(default_factory=dict) created_at: str = ""

这个模型看起来简单,但它解决了创作类应用最关键的问题:系统知道每一步在做什么、是否成功、输出在哪里。很多只接大模型 API 的 Demo 失败后整个任务就丢了,就是因为没有保存中间状态。

创意蓝图的global_context字段非常重要。它用来存放各步骤之间需要共享的信息,比如生成的主视觉图路径、提炼出的色彩主题、统一的产品描述等。后续步骤可以直接读取,避免重复计算或出现前后风格不一致。

3.2 让 LLM 把用户需求拆解成可执行的视觉步骤

「创作」的第一步不是画图,而是计划。RabbitVis 用一个planner模块调用语言模型,将用户需求转换为结构化步骤。这里不直接让用户写步骤,是因为普通用户不会用「先生成主体,再局部重绘背景」这类语言表达需求。

一个关键技巧是给 LLM 提供工具清单和输出格式约束。比如在 prompt 中列出可以调用的工具、每个工具的参数要求,并要求只输出 JSON。下面是一个简化实现:

import json from openai import OpenAI client = OpenAI() tool_declaration = """ 可用工具: 1. text_to_image: 文生图,参数 {prompt, width, height, style} 2. img2img: 图生图,参数 {prompt, input_image, denoise_strength} 3. inpaint: 局部重绘,参数 {input_image, mask, prompt} 4. assemble: 图像合成,参数 {background, foreground, position} 请把用户需求拆解为最多5个步骤,每个步骤只调用一个工具。 输出 JSON 格式: { "creative_goal": "这里写创作目标总结", "steps": [ {"description": "步骤说明", "tool": "工具名", "params": {...}} ] } """ def plan_creation(user_request: str) -> dict: response = client.chat.completions.create( model="gpt-4o-mini", response_format={"type": "json_object"}, messages=[ {"role": "system", "content": "你是视觉创意流程规划器。" + tool_declaration}, {"role": "user", "content": user_request}, ], ) return json.loads(response.choices[0].message.content)

这里要强调一个容易忽略的坑:大模型输出的 JSON 不一定是有效 JSON,尤其是复杂 prompt 时容易多出注释或代码块标记。生产环境一定要对输出做二次解析和字段校验,不能直接json.loads并假设成功。推荐的做法是使用response_format指定 JSON,同时在后端用 Pydantic 校验并抛出可读错误。

3.3 执行器:按步骤调用图像工具并维护任务状态

步骤拆解完成后,executor负责依序执行。RabbitVis 里每个工具都是一个普通 Python 函数,通过工具注册表按名称查找。这样编排层不需要写大量 if-else。

class ToolRegistry: def __init__(self): self._tools = {} def register(self, name: str, func): self._tools[name] = func def get(self, name: str): if name not in self._tools: raise ValueError(f"Tool {name} not found") return self._tools[name] registry = ToolRegistry() def run_blueprint(blueprint: CreationBlueprint, registry: ToolRegistry) -> CreationBlueprint: for step in blueprint.steps: step.status = StepStatus.RUNNING try: for tool_call in step.tool_calls: func = registry.get(tool_call.tool_name) result = func( **tool_call.params, context=blueprint.global_context ) tool_call.result_ref = result.get("ref") if "context_update" in result: blueprint.global_context.update(result["context_update"]) step.status = StepStatus.SUCCEEDED except Exception as exc: step.status = StepStatus.FAILED step.error_message = str(exc) # 在这里决定重试或终止 raise return blueprint

这里的run_blueprint是顺序执行的简化版。实际 RabbitVis 可以引入状态机或 LangGraph 来做更复杂的控制流,但顺序执行已经把核心逻辑表达清楚了:每步执行、记录状态、更新全局上下文。

在上述代码中,工具函数的参数里注入了context,这样工具可以读取之前步骤的输出。例如局部重绘工具需要主图路径,主图路径就是前一个文生图步骤写入 global_context 的字段。

3.4 工具层示例:把生成、重绘和合成封装成统一接口

工具层必须保持统一的输入输出协议。RabbitVis 约定每个工具返回一个 dict,包含ref和可选的context_updateref指向存储在资产目录中的文件路径。下面是一个文生图工具示例:

from diffusers import StableDiffusionPipeline import torch class TextToImageTool: def __init__(self, model_id: str, device: str = "cuda"): self.pipe = StableDiffusionPipeline.from_pretrained( model_id, torch_dtype=torch.float16 ).to(device) def __call__(self, prompt: str, width: int = 768, height: int = 768, style: str = "default", context: dict | None = None, **kwargs): # 这里可以从 context 读取统一风格描述 if context and "global_style" in context: prompt = f"{context['global_style']}, {prompt}" image = self.pipe( prompt=prompt, width=width, height=height, num_inference_steps=25, ).images[0] asset_path = f"assets/generated/{uuid4().hex}.png" image.save(asset_path) return { "ref": asset_path, "context_update": {"latest_image": asset_path} }

这个实现里有一个值得学习的点:工具函数可以通过context感知全局风格,从而保证多次生成结果风格一致。它没有把风格参数写死在 prompt 里,而是从上下文读取。这是保持一致性的一个有效手段,也避免用户每次重复描述风格。

局部重绘工具的接口类似,差别在于需要输入遮罩 mask。RabbitVis 里 mask 可以由用户上传,也可以由前置步骤根据目标区域生成。因为输入输出统一,后面的合成步骤不需要关心上一张图是生成的还是重绘的。

4. 验证、评估与排查:如何判断 AI 是在「创作」而不是「随机生成」

4.1 创作类应用要验证四个层面,不能只看最终图片好不好看

很多视觉 AI 项目上线后的最大问题是「演示效果很好,用户一用就崩」。原因在于只验证了生成结果的美观度,没有验证流程的确定性、资产的完整性和步骤的可恢复性。RabbitVis 把验证拆成四个层面:

验证层面验证内容通过标准
输入解析用户需求能否被正确拆解为步骤步骤数在预期范围,参数合法
流程执行每个步骤能否按顺序完成无未处理异常,状态流转正确
产物一致性多次生成风格、尺寸、内容是否稳定同一需求两次结果相似度可接受
失败恢复步骤失败后能否定位并重试错误信息可读,任务可恢复

单张图片的美观度属于第三层里面的内容相似性,但不能替代整个过程验证。尤其要注意:用户第一次使用时,流程可能完全正常;第二次调整了提示词,LLM 拆解出步骤数可能变了,工具参数可能超出预期。所以必须对 LLM 输出做持续性校验。

4.2 建立「创作过程日志」定位问题到底出在哪一环

传统生成应用出问题只需要看生成日志。创作类应用的问题可能出在规划、执行、工具、资产引用四个环节。RabbitVis 要求在每一步开始和结束时都记录结构化日志。

{ "event": "step_started", "task_id": "task_001", "step_id": "step_2", "tool": "img2img", "params": { "prompt": "把背景换成办公室场景", "input_image": "assets/generated/xxx.png", "denoise_strength": 0.6 }, "timestamp": "2025-01-01T12:00:00Z" }

日志里必须包含task_idstep_idtool_name和完整 params。这样当最终图片异常时,可以回放「每一步用了什么参数、输入了哪张图」。很多问题,比如背景没有变化、主体被改变、生成结果僵硬,通过对步骤日志逐层检查很快就能定位到是工具参数设置错误还是模型问题。

一个典型排查链路如下:

  1. 用户反馈「最终图片和第一张图风格完全不一样」。
  2. 检查任务日志中的每一步context_update,确认global_style是否被后续步骤覆盖。
  3. 检查img2imgdenoise_strength参数,太大会导致原图被破坏,太小导致修改不生效。
  4. 检查assemble工具读取的前背景路径是否正确,是否存在文件覆盖。
  5. 根据日志判断需要调整哪一步,而不是盲目重跑整个任务。

4.3 至少要注意这三个典型坑

第一个坑:认为 LLM 的 JSON 输出可以直接使用。真实项目中 LLM 可能输出非法 JSON、字段缺失、工具名拼写错误、参数超出枚举范围。解决办法是让 LLM 返回一个结构化推理结果,同时在后端做 schema 校验,校验失败时重新请求一次或抛出明确错误。

第二个坑:把global_context当成公共垃圾桶。所有步骤都往里塞字段,很快会出现 key 覆盖和隐式依赖。例如文生图步骤把result_image写入 context,局部重绘步骤又写入result_image,最终引用时不知道是哪一个。推荐做法是每个步骤的输出使用step_id作为命名空间,读取时明确指定step_1.output_ref,避免全局字段互相污染。

第三个坑:忽略硬件和模型版本差异。Diffusion 模型在不同设备上可能得到不同结果,同一模型不同版本的效果也可能变化。RabbitVis 在资产元数据中必须记录模型名称、版本、采样器、种子等参数。否则同一个任务在 A 机器上成功,在 B 机器上失败,排查时没有足够信息,几乎无法定位问题。建议生成结果旁边保存一张 JSON 元数据,内容至少包括:

{ "asset_path": "assets/generated/xxx.png", "tool_name": "text_to_image", "model_id": "stabilityai/sdxl-turbo", "prompt": "...", "seed": 20250101, "width": 768, "height": 768, "steps": 4, "created_at": "2025-01-01T12:00:00Z" }

4.4 在开发环境加入「半自动修正」而非全部自动

创作类 AI 的第一步可以先做成半自动。用户确认每一个关键步骤的结果,再进入下一步。例如用户需要一张产品图,系统生成产品主体后,用户确认外观满意,再让系统生成背景。这个模式的工程代价更低,同时能收集用户在每个环节的反馈,为以后训练自动决策模型积累数据。

如果直接做成全自动,一旦生成结果不符合预期,用户只能重新开始,体验很差。半自动模式下,用户可以在任意步骤回退或修改参数。RabbitVis 实现半自动时,只需要在CreationStep上增加一个requires_confirmation字段,执行器在遇到该字段时暂停并等待用户确认。

5. 最佳实践:从 RabbitVis Demo 到生产级视觉 AI 应用要做什么

5.1 学习环境怎么快速跑通,生产环境需要补足哪些能力

学习环境下,核心目标是把链路跑通。可以把所有资产存在本地目录,使用 SQLite 保存任务和元数据,图像模型加载到单张 GPU 或 CPU。示例任务建议从「一套 3 张风格统一的社交媒体配图」开始,不要一开始就做复杂分镜视频,因为流程越复杂,排查成本越高。

生产环境则需要在五个方向上补强:

维度学习环境生产环境
配置管理项目内.env配置中心或环境变量,敏感信息加密
存储本地文件目录对象存储 + CDN + 备份策略
队列同步执行消息队列 + 异步 worker
监控print 日志结构化日志 + 指标采集 + 告警
权限无鉴权API Key、用户体系、配额管理

生产环境最容易被忽略的是资源隔离。多个用户同时提交创作任务时,如果每个任务都加载一个独立的 Diffusion 模型,显存会直接溢出。正确的做法是模型常驻内存,用并发队列控制同时生成的请求数,不同模型可以部署到不同推理服务中。

5.2 推荐一个可复用的「创作任务上线前检查清单」

在发布 RabbitVis 类应用之前,建议至少过一遍这个清单。不要只检查功能是否可用,还要检查异常路径和运维保障。

  • [ ] 用户输入为空、过长、含敏感词时,接口是否返回明确错误。
  • [ ] LLM 拆解结果非法时,是否触发重试或降级方案。
  • [ ] 每个步骤超时是否有限制,超时后任务状态是否正确。
  • [ ] 步骤失败后,用户能否根据任务 ID 看到具体失败原因。
  • [ ] 全局上下文是否有命名空间,是否会被无意覆盖。
  • [ ] 生成资产的元数据是否完整,是否能追溯到模型、参数和 seed。
  • [ ] 多个步骤并发执行时,资产路径是否冲突。
  • [ ] 模型加载失败或显存不足时,是否有健康检查和自动恢复。
  • [ ] 生产环境是否开启鉴权和限流。
  • [ ] 是否有清理老旧临时资产的定时任务。

这条清单不是一次性的,每次增加新工具或新模型时都要重新跑一遍,尤其是「模型是否可替换」这一项。RabbitVis 的核心价值在于编排层模型无关,新接入一个文生图模型时,不要修改 planner 和 executor,只替换工具实现和配置。

5.3 下一步扩展方向:从单图创作走向多模态叙事

RabbitVis 第一个可落地的版本可以先处理静态图像创作。再往后走,不外乎三个方向。

第一个方向是视频分镜。把创作蓝图扩展为「镜头列表」,每个镜头包含场景描述、构图、时长和运镜方式。每一步生成的图片作为关键帧,再用视频生成模型或插帧工具生成短镜头。这个过程中,当前实现里的分步执行和状态管理可以直接复用,难点在于镜头之间保持角色一致性。

第二个方向是品牌一致性。建立一个品牌视觉库,里面存储颜色、字体、参考图、LoRA 和禁止元素。在 planner 拆解任务时将品牌视觉库注入 global_context,所有工具在生成时都受品牌约束。这比在 prompt 里重复描述品牌风格更稳定。

第三个方向是有人参与的人机协同。把 RabbitVis 从「AI 自动完成任务」变成「AI 完成初稿,人类在关键节点反馈」。实践中会发现,创意类任务中人类反馈比任何自动评分模型都有效。因此在工具链中预留人工修订接口,比强行追求全自动更有产品价值。

5.4 给开发者的实践建议

如果现在要开始做一个视觉 AI 创作类应用,建议不要直接去写大量 Agent 编排代码。先用最简单的方式把一个真实创作场景打通:比如用 Python 脚本串起文生图、抠图、合成三个步骤,把每步的输入输出记录成 JSON。跑通一次后再考虑引入 FastAPI、LangGraph、消息队列等架构组件。

RabbitVis 这个例子想说明的,不是某个框架或某个模型最好,而是视觉 AI 应用的设计重心已经从「生成一张图」转移到「管理一次创作过程」。谁能把模型能力、任务编排和用户反馈揉进一个可维护的系统里,谁才真正把 AI 能力变成了产品能力。对于视觉 AI 应用开发者来说,多花时间在任务状态设计、结果验证和失败恢复上,比不断换更大的模型更有价值。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询