📅 分析日期:2026-06-05 📌 项目:https://github.com/AIDC-AI/Pixelle-Video 💡 用途:后期决定是否借鉴到自己的项目中
| # | 设计模式 | 评分 | 复杂度 | 可借鉴度 |
|---|---|---|---|---|
| 1 | Pipeline 架构模式 | ⭐⭐⭐⭐⭐ | 高 | 高 |
| 2 | 配置管理单例模式 | ⭐⭐⭐⭐⭐ | 中 | 高 |
| 3 | 任务管理异步模式 | ⭐⭐⭐⭐⭐ | 中 | 高 |
| 4 | Core 服务层聚合 | ⭐⭐⭐⭐⭐ | 中 | 高 |
| 5 | LLM 结构化输出 | ⭐⭐⭐⭐ | 中 | 中 |
| 6 | Storyboard 数据模型 | ⭐⭐⭐⭐ | 低 | 高 |
| 7 | Prompt 模板分离 | ⭐⭐⭐⭐ | 低 | 高 |
| 8 | API Schema 规范化 | ⭐⭐⭐⭐ | 低 | 中 |
| 9 | Lazy Initialization | ⭐⭐⭐⭐ | 低 | 高 |
文件位置: pixelle_video/pipelines/base.py
from abc import ABC, abstractmethod
from typing import Optional, Callable
class BasePipeline(ABC):
"""所有自定义 Pipeline 必须继承此基类"""
def __init__(self, pixelle_video_core):
self.core = pixelle_video_core
self.llm = pixelle_video_core.llm
self.tts = pixelle_video_core.tts
self.media = pixelle_video_core.media
@abstractmethod
async def __call__(
self,
text: str,
progress_callback: Optional[Callable[[ProgressEvent], None]] = None,
**kwargs
) -> VideoGenerationResult:
pass
# 内置 Pipeline
self.pipelines = {
"standard": StandardPipeline(self),
"custom": CustomPipeline(self),
"asset_based": AssetBasedPipeline(self),
}
# 调用
result = await self.pipelines["standard"](text="...", n_scenes=5)
progress_callback 实现进度追踪book-generator 模块可以用 Pipeline 重构文件位置: pixelle_video/config/manager.py
class ConfigManager:
_instance: Optional['ConfigManager'] = None
def __new__(cls, config_path: str = "config.yaml"):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
def __init__(self, config_path: str = "config.yaml"):
if hasattr(self, '_initialized'):
return
self._initialized = True
def update(self, updates: dict):
"""深度合并更新"""
def deep_merge(base: dict, updates: dict) -> dict:
for key, value in updates.items():
if key in base and isinstance(base[key], dict):
deep_merge(base[key], value)
else:
base[key] = value
return base
.env + config.ts 可参考此模式文件位置: api/tasks/manager.py
class TaskManager:
def __init__(self):
self._tasks: Dict[str, Task] = {}
self._task_futures: Dict[str, asyncio.Task] = {}
async def execute_task(self, task_id: str, coro_func, *args, **kwargs):
async def _execute():
try:
task.status = TaskStatus.RUNNING
result = await coro_func(*args, **kwargs)
task.status = TaskStatus.COMPLETED
task.result = result
except Exception as e:
task.status = TaskStatus.FAILED
task.error = str(e)
future = asyncio.create_task(_execute())
self._task_futures[task_id] = future
def update_progress(self, task_id: str, current: int, total: int, message: str = ""):
percentage = (current / total * 100) if total > 0 else 0
task.progress = TaskProgress(current=current, total=total, percentage=percentage)
def cancel_task(self, task_id: str) -> bool:
"""取消运行中的任务"""
future = self._task_futures.get(task_id)
if future and not future.done():
future.cancel()
task.status = TaskStatus.CANCELLED
return True
文件位置: pixelle_video/service.py
class PixelleVideoCore:
async def initialize(self):
# 核心服务
self.llm = LLMService(self.config)
self.tts = TTSService(self.config, core=self)
self.media = MediaService(self.config, core=self)
self.api_media = APIProviderMediaService(self.config, core=self)
self.video = VideoService()
# Pipeline 注册
self.pipelines = {
"standard": StandardPipeline(self),
"custom": CustomPipeline(self),
}
# 每个服务都可以访问 core
async def some_method(self):
audio = await self.tts("hello")
image = await self.media.generate(prompt="...")
server/src/services/ 可以整合到 Core文件位置: pixelle_video/services/llm_service.py
from pydantic import BaseModel
from typing import TypeVar, Type
T = TypeVar("T", bound=BaseModel)
async def __call__(
self,
prompt: str,
response_type: Optional[Type[T]] = None,
**kwargs
) -> Union[str, T]:
if response_type is not None:
# 自动生成 JSON Schema 指令
schema = response_type.model_json_schema()
json_instruction = f"""## JSON Output Required
json {json.dumps(schema, indent=2)}
Only output JSON, no other text."""
response = await client.chat.completions.create(
model=model,
messages=[{"role": "user", "content": f"{prompt}\n\n{json_instruction}"}],
)
return self._parse_response_as_model(content, response_type)
from pydantic import BaseModel
class BookOutline(BaseModel):
title: str
chapters: List[str]
total_words: int
outline = await llm(
prompt="为《Atomic Habits》生成大纲",
response_type=BookOutline
)
print(outline.title) # 强类型访问
文件位置: pixelle_video/models/storyboard.py
from dataclasses import dataclass, field
from datetime import datetime
from typing import List, Optional
@dataclass
class StoryboardFrame:
index: int
narration: str
image_prompt: str
audio_path: Optional[str] = None
media_type: Optional[str] = None
video_segment_path: Optional[str] = None
duration: float = 0.0
created_at: Optional[datetime] = None
def __post_init__(self):
if self.created_at is None:
self.created_at = datetime.now()
@dataclass
class Storyboard:
title: str
config: StoryboardConfig
frames: List[StoryboardFrame] = field(default_factory=list)
final_video_path: Optional[str] = None
@property
def progress(self) -> float:
"""自动计算进度"""
if not self.frames:
return 0.0
completed = sum(1 for f in self.frames if f.video_segment_path)
return completed / len(self.frames)
@property
def is_completed(self) -> bool:
return all(f.video_segment_path for f in self.frames)
@dataclass 简洁定义@property 计算属性文件位置: pixelle_video/prompts/*.py
# prompts/title_generation.py
TITLE_GENERATION_PROMPT = """Please generate a short, attractive title.
Requirements:
1. **Language Consistency (CRITICAL)**: The title MUST be in the same language as input
2. **Character Limit (CRITICAL)**: MUST NOT exceed {max_length} characters
3. **Core Message (CRITICAL)**: MUST capture the MAIN POINT
Title:"""
def build_title_generation_prompt(content: str, max_length: int = 15) -> str:
return TITLE_GENERATION_PROMPT.format(
content=content[:500], # 限制长度
max_length=max_length
)
prompts/
├── title_generation.py
├── content_narration.py
├── image_generation.py
├── topic_narration.py
└── video_generation.py
文件位置: api/schemas/video.py
from pydantic import BaseModel, Field
from typing import Optional, Literal, Dict, Any
class VideoGenerateRequest(BaseModel):
text: str = Field(..., description="Source text for video generation")
mode: Literal["generate", "fixed"] = Field(
"generate",
description="Processing mode"
)
n_scenes: Optional[int] = Field(
5,
ge=1, le=20, # 范围约束
description="Number of scenes"
)
template_params: Optional[Dict[str, Any]] = Field(
None,
description="Custom template parameters"
)
class Config:
json_schema_extra = {
"example": {
"text": "Atomic Habits teaches us...",
"n_scenes": 5,
}
}
ge, le)文件位置: pixelle_video/service.py
async def _get_or_create_comfykit(self) -> ComfyKit:
current_config = self._get_comfykit_config()
current_hash = self._compute_comfykit_config_hash(current_config)
# 配置变更检测
if self._comfykit is None or self._comfykit_config_hash != current_hash:
if self._comfykit is not None:
await self._comfykit.close() # 清理旧实例
self._comfykit = ComfyKit(**current_config)
self._comfykit_config_hash = current_hash
return self._comfykit
| 模式 | 理由 | 借鉴方式 |
|---|---|---|
| Pipeline 架构 | 解耦能力强,适合复杂业务流程 | 重构 book-generator 模块 |
| Storyboard 模型 | 简单实用,可追踪复杂任务状态 | 新建视频生成模块 |
| Prompt 模板分离 | 低侵入,易实施 | 新建 prompts/ 目录 |
| Lazy Loading | 性能优化,减少启动时间 | 重构配置加载 |
| 模式 | 理由 | 借鉴条件 |
|---|---|---|
| Core 服务聚合 | 需要重构较大范围 | 先小范围试点 |
| 配置单例 | 需统一配置入口 | 评估现有配置复杂度 |
| 模式 | 理由 |
|---|---|
| LLM 结构化输出 | 需要 Pydantic 基础 |
| API Schema | 项目已有类似方案 |
server/src/prompts/ 目录,分离 Prompt 模板Storyboard 数据模型用于视频生成状态追踪| 设计模式 | 源文件 | 行数 |
|---|---|---|
| Pipeline | pixelle_video/pipelines/base.py |
117 |
| 配置单例 | pixelle_video/config/manager.py |
182 |
| 任务管理 | api/tasks/manager.py |
270 |
| Core 聚合 | pixelle_video/service.py |
316 |
| LLM 服务 | pixelle_video/services/llm_service.py |
340 |
| 数据模型 | pixelle_video/models/storyboard.py |
144 |
| Prompt 模板 | pixelle_video/prompts/title_generation.py |
85 |
| API Schema | api/schemas/video.py |
117 |