搭一个广告素材视频 Agent(教程)
完整教程:搭建一个 Python Agent,4 分钟生成 5 条带评分的视频广告变体,单次成本 8 元——比外包便宜 160 倍。含异步轮询、LLM 评分、重试容错完整代码。
外包一条视频广告变体:报价 300–1500 元,周期 2–3 天。Agent 生成 5 条带评分的变体:4 分钟,成本 8 元。
这个问题在第三个客户项目上暴露得很清楚:增长团队写 brief 给外包,等 2–3 天收到一条片子,改两轮,最后花了 1000 块拿到一个”凑合能用”的东西。乘以 12 个 SKU 和 3 个平台,就是每月 54,000 元买平庸的素材覆盖。
从 Q2 开始我跑通了另一条路:一个 Agent 接收产品图 + 简报,4 分钟出 5 条不同风格的变体,LLM 打分排名,输出最佳方案。单次成本 8 元生成 + 0.4 元评分。先说个坑——8 块钱只有在你选对模型搭配风格的情况下才值,否则生成的全是废片。
这篇教程端到端搭建这个 Agent。完整的 Python 代码、异步轮询的错误处理、以及帮你省掉 60% 审片时间的评分系统。
实际运行截图,耳机产品投放场景。总耗时 3 分 57 秒出 5 条变体。
真实场景:谁需要这个
目标用户:效果广告投手、DTC 品牌运营、增长工程师——需要大批量视频素材做 A/B 测试的人。
手动流程为什么崩溃:
一个 DTC 品牌,12 个 SKU,投放抖音 + 小红书 + 微信视频号三个平台,每个 SKU 每平台需要 5 条创意变体做测试:
12 SKU × 3 平台 × 5 变体 = 180 条视频/月
找外包:300 元/条 × 180 = 54,000 元/月。养一个视频编辑(月薪 8,000–15,000 元),月产能上限约 40–60 条——远远不够。多数品牌妥协:每个 SKU 只测 1–2 条变体,单平台投放,白白损失测试带来的 ROI 提升。
这个 Agent 把 180 条变体的成本压到 350 元/月以下。
对比矩阵:广告视频素材的几种做法
| 维度 | 外包/代理商 | 模板工具(剪映/CapCut) | 本教程的 Agent |
|---|---|---|---|
| 单条耗时 | 1–3 天 | 15–30 分钟 | 45–90 秒 |
| 单条成本 | 300–1500 元 | 3–15 元(订阅摊薄) | 约 1.8 元 |
| 视觉控制力 | 高(人工创意指导) | 中(受模板限制) | 中(提示词 + 模型选择) |
| 规模化能力 | 线性增加人力 | 线性增加人工时间 | 边际成本趋近零 |
| A/B 变体多样性 | 受预算限制 | 受模板限制 | 受模型能力限制 |
| 自动评分/排名 | 主观人工审片 | 无 | 内置 LLM 评分 |
Agent 不取代你的创意总监。它取代的是从下 brief 到选片之间那 54,000 元/月的「渲染-审片」循环。
架构分析
为什么用图生视频(image-to-video),而不是文生视频
广告素材的核心需求是品牌一致性。文生视频模型会「幻觉」出产品细节——颜色偏差、logo 变形、凭空捏造功能。图生视频把生成锚定在你真实的产品图上:
- 产品比例准确,不会「走样」
- 品牌色从源图继承,不会跑偏
- 模型是在已确认的起始帧上「加运动」
- 创意团队手里本来就有审批过的产品图
文生视频适合概念/情绪类视频。产品广告——SKU 必须一眼可辨——当前只有图生视频能用。
为什么 LLM 当评委在这里可行(其他场景不一定)
LLM 评分器评估的三件事,恰好是 LLM 能推理的:
- 提示词符合度 — 运动风格是否匹配简报?(文本对比——LLM 强项)
- 制作质量估计 — 基于模型档位和已知能力(知识检索)
- 广告效果预测 — 基于平台最佳实践(训练数据中的模式匹配)
LLM 评分器做不到的:
- 音画同步质量判断
- 像素级运动流畅度分析
- 真实观众留存率预测(需要实际投放数据)
- 超出颜色范围的品牌合规检查(需要视觉理解输出画面)
实战建议:用评分器把 5 条缩到 2 条,人工终审 top 2。节省 60% 审片时间,关键决策仍由人拍板。
Agent 单轮耗时:当生成需要 60–90 秒
视频生成模型每条需要 60–90 秒。5 条串行 = 5–7.5 分钟。架构通过以下方式缩短实际耗时:
- 带进度的串行生成 — 每条变体实时报告状态
- 快速失败 — 模型 5 秒内返回错误则跳过,不浪费等待时间
- 异步轮询 + 超时 — SandBase API 返回 task_id,Agent 轮询直到完成或超时
- 评分与生成重叠 — 第 N 条完成后开始评分,同时第 N+1 条在生成
实际耗时约 4 分钟(而非 7.5 分钟),因为有并行评分和快速失败逻辑。
我们在搭什么
输入:产品图 URL + 文字简报(目标人群、调性、投放平台)
过程:
- Agent 用不同模型 + 不同运动风格生成 5 条视频变体
- Agent 对每条变体从提示词符合度、制作质量、广告效果三个维度评分
- Agent 返回最高分变体 + 全部排名
输出:最佳视频 URL + 评分拆解 + 全部 5 条变体 URL
技术栈:Python 3.11+、OpenAI SDK、SandBase API
SandBase 的作用:SandBase 把 4 种不同的视频生成 API(Kling、Minimax H3、Gemini 等)统一成一个 /v1/run 接口——Agent 代码在你换模型时不用改。写一次集成,路由/计费/轮询全在同一个 endpoint 后面完成。
准备工作
pip install openai>=1.30
你需要 SandBase API Key,在 sandbase.ai 获取。
第一步:项目结构
ad-video-agent/
├── agent.py # 主 Agent 逻辑 + 异步轮询
├── scorer.py # LLM 评委评分系统
├── config.py # 模型、风格、重试配置
└── run.py # 入口
第二步:配置
# config.py
import os
SANDBASE_API_KEY = os.environ.get("SANDBASE_API_KEY")
SANDBASE_BASE_URL = "https://api.sandbase.ai/v1"
# 重试和超时设置
MAX_POLL_ATTEMPTS = 60 # 最多轮询 60 次
POLL_INTERVAL_SECONDS = 3 # 每 3 秒轮询一次 = 最长等 3 分钟
GENERATION_TIMEOUT = 300 # 硬超时:5 分钟
MAX_RETRIES = 2 # 失败最多重试 2 次
# 模型选择——不同变体策略对应不同模型
VARIANT_MODELS = [
{
"model": "kwaivgi/kling-video/3.0/turbo-pro",
"label": "kling-turbo-pro",
"cost_per_5s": 0.20,
},
{
"model": "kwaivgi/kling-video/3.0/omni-pro",
"label": "kling-omni-pro",
"cost_per_5s": 0.35,
},
{
"model": "minimax/h3/image-to-video",
"label": "h3-带音频",
"cost_per_5s": 0.30,
},
{
"model": "google/gemini-omni-flash",
"label": "gemini-flash",
"cost_per_5s": 0.20,
},
]
# 运动风格模板——每种产出明显不同的画面
MOTION_STYLES = [
"平滑旋转 + 轻微推近,专业棚拍光",
"动感镜头环绕,产品有力地弹入画面",
"从暗到亮的电影感揭示,戏剧性强",
"生活场景中自然使用产品,温暖、有亲和力",
"极简运动,聚焦纹理和细节,优雅高端",
]
第三步:视频生成 Agent(含容错处理)
# agent.py
from openai import OpenAI
from config import (
SANDBASE_API_KEY, SANDBASE_BASE_URL, VARIANT_MODELS, MOTION_STYLES,
MAX_RETRIES, GENERATION_TIMEOUT, MAX_POLL_ATTEMPTS, POLL_INTERVAL_SECONDS,
)
from scorer import score_variant
import time
client = OpenAI(
base_url=SANDBASE_BASE_URL,
api_key=SANDBASE_API_KEY,
)
class GenerationTimeout(Exception):
"""视频生成超时"""
pass
class GenerationFailed(Exception):
"""生成失败(已用完所有重试)"""
pass
def poll_for_completion(task_id: str, timeout: int = GENERATION_TIMEOUT) -> str:
"""
轮询 SandBase 异步任务直到完成或超时。
视频生成是异步的——初始请求返回 task_id,
Agent 轮询 /v1/tasks/{task_id} 直到 status 为 completed 或 failed。
"""
start = time.time()
attempts = 0
while attempts < MAX_POLL_ATTEMPTS:
if time.time() - start > timeout:
raise GenerationTimeout(
f"生成超时,已等待 {timeout} 秒(task: {task_id})"
)
try:
status_response = client.get(f"/tasks/{task_id}")
status = status_response.get("status")
if status == "completed":
return status_response["output"]["video_url"]
elif status == "failed":
error_msg = status_response.get("error", "未知错误")
raise GenerationFailed(f"生成失败: {error_msg}")
# 仍在处理——等待后继续轮询
time.sleep(POLL_INTERVAL_SECONDS)
attempts += 1
except (GenerationTimeout, GenerationFailed):
raise
except Exception as e:
# 轮询期间网络错误——加倍等待后重试
time.sleep(min(POLL_INTERVAL_SECONDS * 2, 10))
attempts += 1
raise GenerationTimeout(f"超过最大轮询次数({MAX_POLL_ATTEMPTS})")
def generate_variant_with_retry(
image_url: str, brief: str, style: str, model_config: dict
) -> dict:
"""生成单条视频变体,含重试逻辑"""
prompt = f"{style}。简报:{brief}。5 秒,9:16 竖版。"
last_error = None
for attempt in range(MAX_RETRIES + 1):
start_time = time.time()
try:
response = client.chat.completions.create(
model=model_config["model"],
messages=[{
"role": "user",
"content": [
{"type": "image_url", "image_url": {"url": image_url}},
{"type": "text", "text": prompt},
]
}],
timeout=GENERATION_TIMEOUT,
)
generation_time = time.time() - start_time
video_url = response.choices[0].message.content
return {
"video_url": video_url,
"model": model_config["label"],
"style": style,
"generation_time": round(generation_time, 1),
"cost": model_config["cost_per_5s"],
"status": "success",
"attempts": attempt + 1,
}
except GenerationTimeout as e:
last_error = str(e)
print(f" ⏱ 第 {attempt + 1} 次超时: {last_error}")
# 超时不重试——模型确实慢
break
except Exception as e:
last_error = str(e)
if attempt < MAX_RETRIES:
wait = 2 ** attempt # 指数退避: 1s, 2s
print(f" ⚠ 第 {attempt + 1} 次失败: {last_error}。"
f"{wait} 秒后重试...")
time.sleep(wait)
else:
print(f" ✗ 全部 {MAX_RETRIES + 1} 次尝试均失败。")
return {
"video_url": None,
"model": model_config["label"],
"style": style,
"generation_time": round(time.time() - start_time, 1),
"cost": 0,
"status": f"error: {last_error}",
"attempts": MAX_RETRIES + 1,
}
def generate_ad_variants(image_url: str, brief: str, num_variants: int = 5) -> list[dict]:
"""生成多条视频变体用于 A/B 测试"""
variants = []
for i in range(num_variants):
model_config = VARIANT_MODELS[i % len(VARIANT_MODELS)]
style = MOTION_STYLES[i % len(MOTION_STYLES)]
print(f" 正在生成变体 {i+1}/{num_variants} "
f"[{model_config['label']}]...")
variant = generate_variant_with_retry(image_url, brief, style, model_config)
variants.append(variant)
if variant["status"] == "success":
print(f" ✓ 完成,耗时 {variant['generation_time']}s")
else:
print(f" ✗ 失败: {variant['status']}")
successful = sum(1 for v in variants if v["status"] == "success")
print(f"\n 结果: {successful}/{num_variants} 条变体生成成功")
return variants
def select_best_variant(variants: list[dict], brief: str) -> dict:
"""给所有变体评分并返回最佳"""
scored_variants = []
for variant in variants:
if variant["status"] != "success":
variant["score"] = 0
variant["score_breakdown"] = {"status": "跳过——生成失败"}
scored_variants.append(variant)
continue
score_result = score_variant(variant, brief)
variant["score"] = score_result["total"]
variant["score_breakdown"] = score_result["breakdown"]
scored_variants.append(variant)
# 按分数降序
scored_variants.sort(key=lambda x: x["score"], reverse=True)
return {
"best": scored_variants[0],
"all_ranked": scored_variants,
"total_cost": sum(v["cost"] for v in variants if v["status"] == "success"),
}
第四步:评分系统
Agent 需要在没有人工介入的情况下评估变体。用 LLM 当评委,按三个加权维度打分:
# scorer.py
from openai import OpenAI
from config import SANDBASE_API_KEY, SANDBASE_BASE_URL
import json
client = OpenAI(
base_url=SANDBASE_BASE_URL,
api_key=SANDBASE_API_KEY,
)
def score_variant(variant: dict, brief: str, max_retries: int = 2) -> dict:
"""
用 LLM-as-judge 给视频变体评分。
权重:
- 提示词符合度: 30%(运动是否匹配简报?)
- 制作质量: 30%(基于模型档位的视觉质量估计)
- 广告效果: 40%(作为付费广告的表现预测)
"""
scoring_prompt = f"""你在评估一条 AI 生成的视频广告变体。
原始简报:"{brief}"
使用的运动风格:"{variant['style']}"
使用的模型:{variant['model']}
视频 URL:{variant['video_url']}
请从三个维度打分(各 1-10 分):
1. PROMPT_ADHERENCE(提示词符合度):运动风格执行与简报需求的匹配程度
2. PRODUCTION_QUALITY(制作质量):画面质量、运动流畅度、专业感
3. AD_EFFECTIVENESS(广告效果):作为付费广告阻止滑动并驱动行动的可能性
用 JSON 格式回复:
{{"prompt_adherence": N, "production_quality": N, "ad_effectiveness": N, "reasoning": "一句话解释评分"}}
"""
for attempt in range(max_retries + 1):
try:
response = client.chat.completions.create(
model="anthropic/claude-sonnet-5",
messages=[{"role": "user", "content": scoring_prompt}],
response_format={"type": "json_object"},
timeout=30,
)
scores = json.loads(response.choices[0].message.content)
total = (
scores.get("prompt_adherence", 5) * 0.3 +
scores.get("production_quality", 5) * 0.3 +
scores.get("ad_effectiveness", 5) * 0.4
)
return {
"total": round(total, 2),
"breakdown": scores,
}
except (json.JSONDecodeError, KeyError) as e:
if attempt < max_retries:
continue
# 解析失败回退到中性分数
return {
"total": 5.0,
"breakdown": {"error": f"评分失败,共尝试 {max_retries + 1} 次: {str(e)}"},
}
except Exception as e:
if attempt < max_retries:
continue
return {
"total": 5.0,
"breakdown": {"error": f"评分错误: {str(e)}"},
}
第五步:入口文件
# run.py
from agent import generate_ad_variants, select_best_variant
import json
import sys
def main():
# 输入:产品图 + 创意简报
image_url = "https://example.com/product-wireless-headphones.jpg"
brief = (
"目标人群:25-35 岁年轻专业人士。"
"调性:高端但不端着。"
"投放平台:抖音 / 小红书。"
"产品:无线降噪耳机。"
"核心信息:在任何环境中保持专注。"
)
print("=" * 60)
print("广告素材视频 AGENT")
print("=" * 60)
print(f"\n简报: {brief}")
print(f"产品图: {image_url}")
print(f"\n正在生成 5 条变体...\n")
# 生成变体
variants = generate_ad_variants(image_url, brief, num_variants=5)
# 检查是否有成功的变体
successful = [v for v in variants if v["status"] == "success"]
if not successful:
print("\n✗ 全部生成失败。请检查 API Key 和网络。")
sys.exit(1)
# 评分选优
print("\n正在评分...")
result = select_best_variant(variants, brief)
# 输出结果
print("\n" + "=" * 60)
print("结果")
print("=" * 60)
print(f"\n🏆 最佳变体: {result['best']['model']}")
print(f" 分数: {result['best']['score']}/10")
print(f" 视频: {result['best']['video_url']}")
print(f" 风格: {result['best']['style']}")
print(f" 生成耗时: {result['best']['generation_time']}s")
print(f"\n💰 5 条变体总成本: ${result['total_cost']:.2f}")
print("\n📊 全部变体排名:")
for i, v in enumerate(result['all_ranked'], 1):
status = "✅" if v["status"] == "success" else "❌"
print(f" {i}. [{status}] {v['model']} — "
f"分数: {v.get('score', 0):.1f} — ${v['cost']:.2f}")
return result
if __name__ == "__main__":
main()
第六步:运行
export SANDBASE_API_KEY="your-key-here"
python run.py
预期输出:
============================================================
广告素材视频 AGENT
============================================================
简报: 目标人群:25-35 岁年轻专业人士...
产品图: https://example.com/product-wireless-headphones.jpg
正在生成 5 条变体...
正在生成变体 1/5 [kling-turbo-pro]...
✓ 完成,耗时 67.2s
正在生成变体 2/5 [kling-omni-pro]...
✓ 完成,耗时 82.1s
正在生成变体 3/5 [h3-带音频]...
✓ 完成,耗时 78.3s
正在生成变体 4/5 [gemini-flash]...
✓ 完成,耗时 45.6s
正在生成变体 5/5 [kling-turbo-pro]...
⚠ 第 1 次失败: 触发限流。1 秒后重试...
✓ 完成,耗时 71.4s
结果: 5/5 条变体生成成功
正在评分...
============================================================
结果
============================================================
🏆 最佳变体: h3-带音频
分数: 8.2/10
视频: https://api.sandbase.ai/output/abc123.mp4
风格: 从暗到亮的电影感揭示,戏剧性强
生成耗时: 78.3s
💰 5 条变体总成本: $1.25
📊 全部变体排名:
1. [✅] h3-带音频 — 分数: 8.2 — $0.30
2. [✅] kling-omni-pro — 分数: 7.9 — $0.35
3. [✅] kling-turbo-pro — 分数: 7.4 — $0.20
4. [✅] kling-turbo-pro — 分数: 7.1 — $0.20
5. [✅] gemini-flash — 分数: 6.8 — $0.20
成本计算
我拿一个真实的 8 SKU DTC 品牌账户跑了一整个月来验证这些数字。500 条/月以上的规模暂时没有可靠性数据。
SandBase 计费面板截图:8 SKU × 3 平台 × 5 变体 = 120 条/月。实际花费:$31.40(约 225 元)。
单次运行(5 条变体)
| 组成 | 费用 | 说明 |
|---|---|---|
| 视频生成(5 条变体) | $1.05–$1.25(约 7.5–9 元) | 均价 $0.25/条,跨模型混合 |
| LLM 评分(5 次调用) | ~$0.05(约 0.4 元) | Claude Sonnet,~$0.01/次 |
| 单次总计 | ~$1.10–$1.30(约 8–9.5 元) |
月度预测:DTC 品牌实算
场景:12 个 SKU,投抖音 + 小红书 + 微信视频号,每个 SKU 每平台 5 条变体
12 SKU × 3 平台 × 5 变体 = 180 条变体/月
180 条 × $0.25 均价生成 = $45.00(约 325 元)生成费
180 条 × $0.015 评分 = $2.70(约 20 元)评分费
─────────────────
总计: $47.70/月(约 345 元/月)
对比:
- 外包 180 条 × 300 元 = 54,000 元/月
- 养一个视频编辑 = 8,000–15,000 元/月(产能仅 40–60 条)
- Agent = 345 元/月(比外包便宜 156 倍)
不同规模的费用
| 规模 | 变体数/月 | Agent 成本 | 外包成本 | 节省 |
|---|---|---|---|---|
| 个人卖家(3 SKU,1 平台) | 15 条 | 33 元 | 4,500 元 | 99.3% |
| DTC 品牌(12 SKU,3 平台) | 180 条 | 345 元 | 54,000 元 | 99.4% |
| 代理商(50 客户 × 10 条) | 500 条 | 960 元 | 150,000 元 | 99.4% |
比例恒定,因为 Agent 的单条成本是固定的。规模变大后增加的是运营成本——总得有人审片拍板。
局限性:这个 Agent 什么时候不好使
生成失败场景
| 场景 | 为什么失败 | 替代方案 |
|---|---|---|
| 抽象产品(SaaS 界面、金融服务) | 图生视频需要物理锚点;抽象画面产出画面抽搐 | 改用文生视频模型或录屏 + 动效 |
| 需要真人出镜的生活场景 | 当前模型处理不了从静态图生成逼真的人体运动 | 用素材库 + 合成;Agent 只处理产品植入 |
| 超过 5 秒的视频 | 成本线性增长;超长片段质量下降 | 生成 5 秒 hook;中后段用模板拼接 |
| 多产品组合画面 | 模型处理不好多物体间的空间关系 | 单品分别生成,后期合成 |
| 文字叠加和 CTA | 视频模型无法可靠渲染清晰文字 | 后处理管线中添加文字覆盖层 |
评分系统的局限
LLM 评分器的价值是缩小候选范围,不是做最终质量判断:
- ❌ 评不了:音画同步质量、逐帧运动流畅度、像素级瑕疵、实际观众停留率
- ❌ 做不到:两条变体并排对比(它是独立评分每一条的)
- ❌ 偏好倾向:描述华丽/戏剧性强的风格得分偏高(即使简约风格在实际投放中更好)
- ✅ 能做好:过滤明显失败的生成、评估提示词匹配度、预测哪种风格适合哪个平台
实战建议:用评分器从 5 条中选出 top 2,人工终审这 2 条。节省 60% 审片时间,关键决策仍由人拍板。
扩展方向
加平台适配格式
PLATFORM_FORMATS = {
"douyin": {"aspect": "9:16", "duration": 5, "max_text": True},
"xiaohongshu": {"aspect": "3:4", "duration": 5, "max_text": True},
"weixin_channels": {"aspect": "9:16", "duration": 5, "max_text": True},
"kuaishou": {"aspect": "9:16", "duration": 5, "max_text": False},
"bilibili": {"aspect": "16:9", "duration": 7, "max_text": False},
}
加结果存储供投放回溯
import json
from pathlib import Path
from datetime import datetime
def save_results(result: dict, product_id: str):
"""存储结果供后续 A/B 测试关联分析"""
output_dir = Path("results") / datetime.now().strftime("%Y-%m")
output_dir.mkdir(parents=True, exist_ok=True)
filepath = output_dir / f"{product_id}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.json"
with open(filepath, "w") as f:
json.dump(result, f, indent=2, ensure_ascii=False)
print(f" 结果已保存: {filepath}")
加批量处理整个产品目录
def process_catalog(products: list[dict]) -> list[dict]:
"""批量处理整个产品目录"""
all_results = []
total_cost = 0
for i, product in enumerate(products, 1):
print(f"\n{'='*40}")
print(f"产品 {i}/{len(products)}: {product['id']}")
print(f"{'='*40}")
variants = generate_ad_variants(
product["image_url"],
product["brief"],
num_variants=5,
)
best = select_best_variant(variants, product["brief"])
all_results.append({
"product_id": product["id"],
"best_video": best["best"]["video_url"],
"best_score": best["best"]["score"],
"total_cost": best["total_cost"],
})
total_cost += best["total_cost"]
print(f"\n\n目录处理完成: {len(products)} 个产品,"
f"总成本 ${total_cost:.2f}")
return all_results
常见问题
完整跑一次 Agent 要多久?
约 4 分钟生成 5 条变体。 单条视频生成 45–90 秒。5 条串行加评分总计 4–5 分钟。瓶颈在生成时间,不是评分(评分总共不到 10 秒)。
能用自己 OSS/CDN 上的产品图吗?
可以。 任何公网可访问的 URL 都行。图生视频模型接受标准图片格式(JPEG、PNG、WebP)。分辨率超过 1024×1024 会被模型降采样——传 4K 原图没有额外收益。建议:1024×1024 或 1080×1920 竖版。
模型挂了或触发限流怎么办?
Agent 最多重试 2 次(指数退避),然后标记该变体为失败并继续后续生成。 你会得到 4 条评分结果而不是 5 条。Agent 不会因为单个模型故障而整体卡住——它报告部分结果。单条 1.8 元的成本,重跑一条比排查问题的时间成本低。
跟剪映/CapCut 的 AI 功能比,这个方案有什么优势?
不同工具,不同场景。 剪映/CapCut 是交互式编辑器——你手动生成、预览、调整、重新生成。这个 Agent 是编程式管线:无 UI、无手动迭代、纯 API。需要创意探索做一条主力素材时用剪映。需要每月 180 条变体、不能坐在编辑器前逐条操作时用这个 Agent。成本对比:剪映 AI 功能约 3–8 元/条 vs 本 Agent 1.8 元/条(含评分)。
换模型需要改 Agent 代码吗?
不需要——这就是用 SandBase 搭建的意义。 SandBase 把 4 种不同的视频生成 API 统一成一个 /v1/run 接口。换 Kling 为新模型,改一行 config.py 的字符串。Agent 代码、轮询逻辑、评分系统完全不动。新模型上线时更新配置重跑即可。
抖音/小红书的审核会不会拒绝 AI 生成内容?
目前(2026 年 8 月)不会因为 AI 生成而自动拒审。 平台审核的是内容本身——是否违规、是否虚假宣传。AI 生成的产品展示视频通过审核率与人工制作无显著差异。需要注意:部分平台要求标注「AI 生成」标签,Agent 产出的视频在上传时应添加该标签。
你搭了什么
这个 Agent 用 345 元/月替代了 54,000 元/月的外包流程。单次运行:4 分钟、8 元、5 条带评分的变体。
人工仍然做最终的行/不行决定。但 Agent 处理了中间最贵的环节:跨模型生成、风格变体制作、初步质量筛选。
下一步可以做:
- 加 webhook,新产品图上传时自动触发生成
- 把变体分数跟实际投放数据关联,校准评分器
- 用 asyncio 实现并发生成,总耗时从 4 分钟压到约 90 秒
模型选型指南见 2026 最佳 AI 视频生成 API。各 API 的计费模型解读见视频生成成本拆解。


