这是一个工作流型平台,不是常见的"自治多 Agent 系统"。它没有显式的 Agent 编排器(如 ReAct / AutoGen / CrewAI 那种 LLM-as-Planner),而是把每一道工序("剧本精修"、"分镜导演"、"运镜导演"…)做成 一个固定流水线节点(Stage Processor)+ 一个对应角色提示词(PromptTemplate)+ 一个 AI Client 执行器(Executor)。
所以本文档里说的「Agent」= 某个阶段上承担固定职责的角色,「Skill」= 该角色绑定的一组提示词 + 可调参数 + 可挂载的客户端能力(执行器)。
闭源目录
backend/apps/agent/与backend/apps/mcp/在开源仓中只有.so,无可读源码 —— 推测那里才是更"主动"的 Agent / MCP 工具调用层。本文档只覆盖开源可见的角色。
0. 全景图
┌─────────────── PromptTemplateSet ────────────────┐
│ 一个项目挂 1 个集合,集合下每阶段挂 1 个模板 │
└─────────┬────────────────────────────────────────┘
│
┌───────────── 8 个 Stage / 8 个角色(Agent) ─────────────┐
│ │
│ rewrite ─► 剧本精修 Agent │
│ asset_extraction ─► 资产抽取 Agent │
│ storyboard ─► 皮克斯分镜导演 Agent │
│ image_generation ─► 文生图 Agent │
│ multi_grid_image ─► 多宫格大图 Agent │
│ image_edit ─► 图片编辑 / 高清还原 Agent │
│ camera_movement ─► 皮克斯运镜导演 Agent │
│ video_generation ─► 图生视频 Agent │
│ │
│ * Agent 之间:节点对话协作助手(前端 Chat) │
└──────────────────────────────────────────────────────────┘
│
▼
┌──── Skills(每个 Agent 都有这 4 类)──────┐
│ 1. PromptTemplate (Jinja2 角色定义) │
│ 2. client_params (可调参数表) │
│ 3. ModelProvider (执行器 + API 配置) │
│ 4. GlobalVariable (用户/系统级注入变量) │
└────────────────────────────────────────────┘
1. 8 个核心 Agent(按 Stage 划分)
下表对应代码里的 STAGE_TYPES(在 apps/projects/models.py::ProjectStage 与 apps/prompts/models.py::PromptTemplate 中保持一致)。
| Stage Type | 显示名 | 角色定位(Agent) | Stage Processor | 默认 Executor 类型 |
|---|---|---|---|---|
rewrite | 剧本精修 | 文案/剧本改写助理 | LLMStageProcessor("rewrite") | LLM |
asset_extraction | 资产抽取 | 角色/场景/道具结构化抽取员 | AssetExtractionStageProcessor | LLM |
storyboard | 分镜生成 | 皮克斯动画分镜导演 | LLMStageProcessor("storyboard") | LLM |
image_generation | 文生图 | 文生图工匠(按分镜出图) | Text2ImageStageProcessor | Text2Image |
multi_grid_image | 多宫格图片 | 多宫格大图工匠(一张大图切 N 块) | MultiGridImageStageProcessor | Text2Image |
image_edit | 图片编辑 | 高清还原 / 图生图增强匠 | ImageEditStageProcessor | ImageEdit |
camera_movement | 运镜生成 | 皮克斯动画导演(运镜分配) | LLMStageProcessor("camera_movement") | LLM |
video_generation | 图生视频 | 图生视频工匠(图 + 运镜 → 5s 视频) | Image2VideoStageProcessor | Image2Video |
所有 Stage Processor 在 backend/apps/content/processors/。
2. 每个 Agent 的"Skills"画像
Skills = 这位 Agent 工作时能"调用"的资源:提示词模板 + 可调参数 + 真实执行器(AI 厂商 SDK)+ 全局变量。
⚠️ 提示词原文请见 03_提示词.md,本节只描述"角色 + 它有哪些 skill 能力开关"。
2.1 剧本精修 Agent(rewrite)
- 职责:把
Project.original_topic改写为更适合视频呈现的脚本。 - 输入:
project.original_topic - 输出:
ContentRewrite.rewritten_text - Skills(client_params)(来自 apps/prompts/client_param_specs.py):
max_tokens:默认 4096,1–65536temperature:默认 0.7,0–2top_p:默认 1
- 可挂执行器:
LLM_EXECUTORS(OpenAI 兼容 / Mock) - 备注:
signals.py默认提示词集没有 rewrite 模板(仅种入 storyboard / image_generation / camera_movement / video_generation 四阶段),rewrite 走完即跳过或留给用户自定义。
2.2 资产抽取 Agent(asset_extraction)
- 职责:从(已改写或原始)文案里抽取
summary+items[](角色/场景/道具)等结构化资产,供后续阶段做变量注入。 - 输入优先级:
ContentRewrite.rewritten_text→ContentRewrite.original_text→Project.original_topic - 输出:
ProjectStage.output_data={ summary, items, source_text, source_type, raw_text, prompt_used, generation_metadata } - Skills:
max_tokens=4096、temperature=0.3(建议低温减少结构抖动)、top_p=1 - 副作用:抽取出的项目可作为
GlobalVariable/资产上下文,被分镜模板通过 Jinja2 引用。
2.3 皮克斯分镜导演 Agent(storyboard)
- 职责:把改写后文案逐句拆成 N 个分镜,每个分镜生成结构化
visual_prompt、narration、shot_type。 - 角色设定:身份 = 皮克斯动画分镜导演;风格固定为 "3D 渲染,皮克斯动画风格";统一规约(例如同一宝宝穿浅黄色连体衣印 "小方圆")。
- 输入:
ContentRewrite.rewritten_text - 输出(必为严格 JSON):
{ "scenes": [ { "scene_number": 1, "narration": "…", "visual_prompt": "…", "shot_type": "特写" } ] } - Skills:
max_tokens=40960(远高于其他阶段,因为分镜列表长)、temperature=0.8(鼓励创意)、top_p=1 - 持久化:每条 scene 落到一行
Storyboard(sequence_number / scene_description / narration_text / image_prompt / duration_seconds)。
2.4 文生图 Agent(image_generation)
- 职责:按每个
Storyboard.image_prompt生成对应静态图。 - 输入模板(default_promot/image_generation.md):
图像生成,图片比例为 9:16: {{visual_prompt}} - Skills:分辨率、采样步数、负面提示词、批量大小等(详见
client_param_specs.py中image_generation段)。 - 可挂执行器:
Text2ImageClient(默认)/ComfyUIClient/MockText2ImageClient。 - 持久化:
GeneratedImage(generation_params、retry_count)。
2.5 多宫格大图 Agent(multi_grid_image)
- 职责:一次生成一张多宫格大图,再切成 N 块(rows × cols)以便对比/筛选。
- 入口参数:
grid_rows、grid_cols、tile_gap、outer_padding。 - Stage Processor:
MultiGridImageStageProcessor(继承Text2ImageStageProcessor,复用其 prompt/provider 解析)。 - 持久化:
MultiGridImageTask+MultiGridTile。
2.6 图片编辑 / 高清还原 Agent(image_edit)
- 职责:对多宫格切片或已有图做高清还原 / 图生图增强(强度
strength可调)。 - Stage Processor:
ImageEditStageProcessor(继承Text2ImageStageProcessor),但走ImageEditClient接口。 - Skills:
strength默认 0.35,width/height可覆盖。 - 持久化:
EditedImage,溯源到MultiGridTile或源图。
2.7 皮克斯运镜导演 Agent(camera_movement)
- 职责:按"万能提示词公式"为每个分镜配 2–3 个镜头的中文运镜描述(5 秒视频)。
- 角色设定:皮克斯动画导演;风格固定 "3D 皮克斯风格";输出格式:
镜头1: 3D皮克斯风格,xxx 镜头2: 3D皮克斯风格,xxx 镜头3: 3D皮克斯风格,xxx - 特点:本阶段是多任务 LLM,每个
Storyboard触发一次生成,task 由_build_tasks按分镜批量构造。 - 持久化:
CameraMovement(movement_type、movement_params)。
2.8 图生视频 Agent(video_generation)
- 职责:把
GeneratedImage+CameraMovement组合送入图生视频厂商,生成 5s 左右片段。 - 模板:
生成视频:{{camera_movement}} - 可挂执行器:
VideoGeneratorClient/VolcengineImage2VideoClient(火山引擎)/ComfyUIClient/ Mock。 - 持久化:
GeneratedVideo(duration / width / height / fps / file_size)。
3. 一个特殊的"协作 Agent":节点对话助手
文件: backend/apps/projects/views.py
node_chat_init等 action
它不是 Pipeline 的一环,而是用户在前端单击某个分镜节点 / 运镜节点时弹出的对话框协作者:
- 节点类型:
storyboard或camera_movement - 行为:把当前节点 JSON、历史对话、用户最新指令拼成 prompt,让 LLM 按"严格 JSON 协议"回吐
{ reply_text, apply_patch },前端把apply_patch直接合并回该节点。 - Skills:复用项目下已配置的 LLM provider;prompt 在
_build_node_chat_user_prompt内嵌,不落库。
可以理解为"本地化的微型 Agent" —— 只对单个节点字段负责的修改 Agent。
4. Skills 横切层(所有 Agent 公用)
4.1 PromptTemplate —— 角色定义
模型: PromptTemplate
- Jinja2 模板(
template_content) - 自动从模板抽取变量(
apps/projects/signals.py::_extract_template_variables),并按命名约定推断类型(is_*→ bool,_count→ int,_list→ list…) - 版本号
version+is_active唯一约束(每个模板集 / 每个阶段 同时只允许一个激活模板) - 可绑定默认
model_provider
4.2 client_params —— 可调参数
文件: apps/prompts/client_param_specs.py + client_param_resolver.py
- 每阶段定义自己可调的参数清单(key、label、type、default、min、max、step、description)
- 解析顺序:runtime overrides > template.client_params > provider 默认 > spec default
- 这是把"通用 LLM 参数(temperature / max_tokens / top_p)"和"特定阶段参数(图生图的 strength、视频生成的 duration / fps、负面提示词…)"统一抽象的中间层。
4.3 ModelProvider —— 执行器(真正调 API 的那个)
模型: ModelProvider
- 字段:
provider_type∈llm / text2image / image2video / image_edit executor_class完整 Python 类路径,由core/ai_client/factory.py动态导入- 自带白名单
LLM_EXECUTORS / TEXT2IMAGE_EXECUTORS / IMAGE2VIDEO_EXECUTORS / IMAGE_EDIT_EXECUTORS - 限流:
rate_limit_rpm/rate_limit_rpd - 优先级:
priority(用于ProjectModelConfig的weighted负载均衡) - 当前内置 Executor:
- LLM:
OpenAIClient、MockLLMClient - Text2Image:
Text2ImageClient、ComfyUIClient、MockText2ImageClient - Image2Video:
VideoGeneratorClient、VolcengineImage2VideoClient、ComfyUIClient、MockImage2VideoClient - ImageEdit:
ImageEditClient、MockImageEditClient
- LLM:
4.4 GlobalVariable —— 跨模板共享变量
模型: GlobalVariable
- 类型:
string / number / boolean / json / image(图片可上传文件) - 作用域:
system(全员可见)/user(仅创建者) - 模板里直接
{{ var_name }}即可注入,渲染优先级最低(global_vars < project < input_data)。 - 解析入口:
apps/projects/asset_context.py::build_project_asset_context
5. Stage 执行 / 调试 / 资产复用
5.1 异步执行
- 入口:
apps/projects/tasks.py中按 stage 注册 Celery 任务,分别派到llm/image/video队列。 - 实时进度:Worker 在执行过程中通过
core/redis/publisher.py::RedisStreamPublisher推送token / stage_update / done / error / camera_generated / skipped等事件,前端 SSE 订阅。
5.2 调试三件套(仅开发/调参用)
- PromptDebugSession:草稿(
draft_template_content/draft_variables/draft_client_params),不污染线上模板。 - PromptDebugRun:每次试跑保留
template_snapshot、rendered_prompt、raw_response、parsed_output、latency_ms。 - PromptDebugArtifact:把试跑结果(文本 / 分镜集 / 单条分镜 / 图 / 视频)固化为可被下游阶段复用的"资产",并支持
is_pinned、跨 run 引用。
这相当于一个离线的提示词工程台:写 prompt → 试跑 → 拿到 artifact → 喂给下游阶段重新跑。
6. 一句话总结
AI Story 的 "Agent" = 被 Stage 编排器固定调度的领域角色; 它的 "Skill" = 一组(提示词 + 参数 + 执行器 + 变量),在数据库里以
PromptTemplate / client_params / ModelProvider / GlobalVariable四张表存在; 任意时刻给一位 Agent 换 skill 都不需要改 Python 代码 —— 这就是它把 SOLID 与 OCP 推到极致的原因。