name: script-generator
description: |
热点视频内容文本脚本生成智能体。只负责读取已有热点数据,将热点转化为完整可读的视频文案、分镜脚本、平台发布变体、视频生成施工单和自检报告;不负责热点抓取、热点筛选、数据源维护或网页登录处理。
触发场景:
(1) 用户说"生成视频脚本"、"跑一下脚本"、"生成今日脚本"
(2) 定时任务"内容脚本生成-15点"触发时
(3) 用户要求"根据热点生成视频内容"、"根据热点写视频文案"、"热点转脚本"
(4) 用户要求"用这个 skill"且指 script-generator
Script Generator(内容脚本生成)
定位铁律
- 本 skill 不做热点提取。不抓取网站、不筛选热点、不维护热点数据源、不处理网页登录/验证码/反爬问题。
- 本 skill 只消费已有热点文件。输入必须是上游已经生成好的
hot_topics_*.json,或用户直接提供的热点列表/话题 brief。 - 输出必须是完整视频内容文本脚本。禁止输出骨架占位符,例如
[待AI填充]、TODO、待补充。 - 脚本文案优先可拍可剪。每条热点必须产出:口播、分镜、字幕、画面建议、平台标题、发布描述、封面文案、视频生成施工单。
- 如热点信息不足,只能基于现有信息做安全补全或标记“需人工补充事实”,不得编造具体事实、数据、人物发言。
快速启动
cd ~/.qclaw/skills/script-generator/scripts
python3 main.py # 批处理今日 TOP 4(国内2 + 国际2)
python3 main.py --preview <topic_id> # 预览单条,不落盘
python3 main.py --llm # 启用 LLM 文案增强
默认读取上游热点文件:~/.qclaw/workspace-agent-17f11f7d/script-generator/queue/hot_topics_*.json。
> 注意:这是“读取已有热点文件”,不是执行热点抓取。
输入要求
热点 JSON 至少包含:
{
"domestic_top2": [
{
"topic_id": "UUID",
"title": "话题标题",
"region": "domestic",
"source": "来源平台",
"description": "话题描述",
"video_brief": {
"topic_type": "科技数码|社会民生|娱乐八卦|资讯|生活|国际科技",
"suggested_angles": ["事件梳理", "影响解读"],
"emotion_tone": "理性客观|温暖共情|轻松幽默",
"visual_elements": ["数据图表", "时间线", "评论截图"],
"target_audience": "泛大众"
}
}
],
"international_top2": []
}
如果用户直接给热点文本,没有 JSON,也按同样字段临时结构化后生成脚本。
核心流程
详细过程见 references/workflow.md。执行时按以下 7 步:
Step 0:执行策略(单条 vs 批量)
- 单条指定生成:串行执行,关闭并发池
- 批量 2-4 条:并发模式,使用
ThreadPoolExecutor(max_workers=4)并行处理
Step 1:读取已有热点
- 查找最新
hot_topics_*.json - 合并
domestic_top2+international_top2 - 校验每条是否有
topic_id/title/region/video_brief - 信息不足时建立
risk_flags,但不终止生成
Step 2:结构化提取
从 title + description + video_brief 提炼:
- 核心事实 core_fact(3-5 句完整描述)
- 事件时间线 event_timeline
- 影响分析 impact_analysis
- 选题角度 chosen_angle
- 关键视觉元素 key_points
- 可引用数据点 data_points
- 情绪钩子 emotion_hook
- 目标受众 target_audience
- 国际话题的中文转译和文化适配说明
Step 2b:搜索增强(自动触发)
- 使用搜索引擎补充事实背景
- 搜索结果先经 LLM 提炼高质量结构化摘要
- 静默失败处理:搜索不可用时不阻塞
Step 2c:参考图片补充(自动触发)
参考图片丰富方案(优先级递减):
1. 上游采集配图:读取 hot_topics_*.json 中的 image_urls 字段(头条等源直接提供)
2. 搜索引擎补图:当上游无 image_urls 时,自动调用 search_enricher.search_images() 补充
- 使用 Bing 图片搜索 async API (www.bing.com/images/async)
- 国内话题搜索词加"新闻"后缀,国际话题直接用原标题
- 最多补充 5 张,总限制 10 张
- 结果 24h 本地缓存
3. 待扩展:LLM 生成图片提示词
图片下载到脚本包的 reference_images/ 子目录,路径记录在 meta.json、video_assembly_brief.json、pending_video_gen/*.json 中。
Step 3:风格与平台策略
按话题类型选择风格模板:
| 话题类型 | 默认风格 | 备选 |
|---|---|---|
| 科技数码/国际科技 | science_explain | science_list |
| 社会民生/生活 | humor_empathy | science_explain |
| 娱乐八卦/海外趣闻 | humor_roast | humor_empathy |
| 资讯/财经/汽车 | science_explain | review_opinion |
| 观点争议 | review_opinion | humor_empathy |
平台策略:
- 国内话题:抖音、视频号、B站、小红书、YouTube Shorts
- 国际话题:抖音、B站、YouTube Shorts、YouTube 长视频、TikTok
时长取甜区中值(不再取下限):
- 抖音:28s(21-35s 中值)
- 视频号:45s(30-60s 中值)
Step 4:LLM 增强(--llm 时触发)
依次增强三个核心模块:
1. 提取增强:用 LLM 重写 core_fact/background/event_timeline/impact_analysis
2. 分镜增强:用 LLM 生成完整 storyboard,带 voiceover/visual/ip_character
3. 平台变体增强:用 LLM 为每个平台生成 title/description/hashtags/cover_text/pinned_comment
LLM 健壮性处理:
- 使用 _robust_json_parse() 清理非标准 JSON
- 失败时保留模板骨架继续,标记 llm_skipped,不崩溃不阻塞
Step 5:生成完整分镜文案
默认 6 个镜头,完整叙事弧:
| 镜头 | 时长 | 目的 | 必填内容 |
|---|---|---|---|
| 1 hook | 0-3s | 抓注意力 | 反常识开场、IP表情、强字幕 |
| 2 setup | 3-8s | 交代背景 | 时间线/事件卡片、完整背景铺垫 |
| 3 core_info | 8-15s | 给信息 | 关键点拆解、数据或对比 |
| 4 depth | 15-22s | 给判断 | 为什么重要、影响谁 |
| 5 twist | 22-27s | 给反转 | 表面现象 vs 背后逻辑 |
| 6 cta | 27-目标时长 | 促互动 | 投票/评论问题、结尾金句 |
每个镜头必须包含:
- visual:画面描述(具体到元素级别)
- ip_character:IP 角色动作和表情
- voiceover_cn:中文口播
- voiceover_en:英文口播(原生撰写,非机翻)
- subtitle:屏幕字幕
- screen_text:画面文字
- sfx:音效建议
叙事弧铁律:背景铺垫→核心经过→影响分析→互动引导。
Step 6:生成平台发布变体
每个平台单独生成:
- 标题:遵守平台字数限制,避免绝对化词
- 描述:180-220 字,信息完整但不夸大
- 标签:3-10 个
- 封面文案:短、强、可读
- 置顶评论:引导互动
Step 7:生成视频施工单
生成给下游视频 Agent 使用的 video_assembly_brief.json:
- 分辨率、FPS、目标时长
- IP 出场点位
- TTS 文本与声音人设
- 字幕样式
- BGM 情绪和音量
- 素材建议
- 平台裁剪策略
Step 8:自检与落盘
必须检查:
- 无占位符
- 中文口播自然完整
- 分镜字段齐全
- 平台变体不少于 5 个
- hook 与 cta 有 IP 出场(大小写兼容检查)
- 发布内容敏感词扫描通过或给出人工审核理由
自检失败处理:任一不过 → 修复后重试;连续两次失败 → 标记 script_failed 通知运营者。
输出目录结构
脚本包按日期归档,每天一个日期目录,日期目录下按 topic_id 分子目录:
queue/script_pkg/20260514/{topic_id_1}/
queue/script_pkg/20260514/{topic_id_2}/
queue/script_pkg/20260514/{topic_id_3}/
queue/script_pkg/20260514/{topic_id_4}/
输出文件
脚本包路径:{WORKSPACE}/script-generator/queue/script_pkg/{YYYYMMDD}/{topic_id}/
| 文件 | 说明 |
|---|---|
script_cn.md |
中文完整视频文案,主交付物 |
script_en.md |
英文脚本(原生撰写) |
storyboard.json |
分镜结构化数据 |
platform_variants.json |
多平台发布文案 |
video_assembly_brief.json |
视频生成施工单 |
risk_report.json |
敏感词与事实风险报告 |
checklist.json |
自检结果 |
meta.json |
元信息(含 image_urls + reference_images) |
extraction.json |
热点结构化提取 |
strategy.json |
风格与平台策略 |
reference_images/ |
参考图片目录(1-10张,可选) |
下游触发文件:{WORKSPACE}/script-generator/queue/pending_video_gen/{YYYYMMDD}/{topic_id}.json
质量标准
- 口播像真人短视频脚本,不像报告摘要
- 每 3-5 秒有信息推进或情绪变化
- 叙事弧完整:背景铺垫→核心经过→影响分析→互动引导
- 内容质量丰富:core_fact 3-5 句完整描述,background ≤200 字,event_timeline 3个节点
- 标题不过度承诺,不使用“最强/第一/震惊”等绝对化表达
- 国际话题必须做中文语境解释,不直接照搬英文标题
- 可视化建议要具体,例如“销量 TOP10 柱状图”优于“数据图表”
- 如果事实不足,写“目前可确认的是……”而不是编造细节
性能目标
- 单条端到端:≤ 5 分钟
- 单批 4 条并发:≤ 15 分钟(ThreadPoolExecutor max_workers=4)
- LLM 提供商:doubao-seed-2.0-pro(ark.cn-beijing.volces.com)
- 搜索增强:cn.bing.com(免费、无需 API key、24h 本地缓存)
- 图片搜索:www.bing.com/images/async(Bing 图片搜索 API,免费,24h 本地缓存)
- 模板模式:完全离线可用
失败处理
| 失败类型 | 处理 |
|---|---|
| 热点 JSON 读不到 | 重试 3 次(间隔 30s),仍失败 → 报错并退出,不假装产出 |
| 热点 JSON 缺字段 | 用默认值填充,建立 risk_flags,不终止生成 |
| LLM 返回异常 JSON | 使用 _robust_json_parse() 清理解析;仍失败 → 保留模板骨架,标记 llm_skipped,不崩溃不阻塞 |
| 模型/API 异常 | 立即告知用户,绝不私自切换 provider 或修改配置,等待人工确认 |
配置文件
config/ai.yaml:LLM 配置(支持嵌套格式primary.model/base_url/api_key,自动从 OpenClaw 配置读取)config/sensitive_words.txt:敏感词列表config/styles/:风格模板config/templates/:结构模板
依赖
- Python 3.8+
- PyYAML:
pip install pyyaml - 已有热点文件或用户提供的热点列表
禁止事项
- 不执行热点抓取命令
- 不访问热点网站
- 不处理网页登录、验证码、反爬
- 不修改热点提取 Agent 的 skill 或数据源配置
- 不把源数据中的敏感词配置本身纳入发布内容扫描