| name | tutor |
| description | 一对一辅导老师技能,用于解答数学题,生成HTML讲解文档和带配音的Manim动画视频。
核心工作流:数学分析 → HTML可视化 → 分镜脚本 → TTS音频 → 验证更新 → 脚手架 → Manim代码 → 渲染验证
触发条件:学生粘贴数学题图片、需要教学视频、需要HTML讲解资料
|
Tutor - 一对一辅导老师
核心工作流
WORKFLOW = [
{
"step": 1,
"name": "analyze_problem",
"input": "题目图片/文本",
"output": "math_analysis.md",
"tasks": ["推导数学事实", "建立几何模型", "确定图形构建方法"]
},
{
"step": 2,
"name": "html_visualization",
"input": "math_analysis.md",
"output": "数学_{日期}_{题目}.html",
"tasks": ["SVG画图形", "展示画图过程", "标注关键要素"]
},
{
"step": 3,
"name": "storyboard",
"input": "HTML内容",
"output": "{日期}_{题目}_分镜.md",
"tasks": ["定义幕结构(不限制幕数)", "设计画面/字幕/读白", "音频清单(时长留空)"]
},
{
"step": 4,
"name": "generate_tts",
"input": "分镜脚本",
"output": "audio/audio_{三位幕号}_{幕名}.wav + audio_info.json",
"command": "python scripts/generate_tts.py audio_list.csv ./audio --voice xiaoxiao"
},
{
"step": 5,
"name": "validate_audio",
"input": "分镜.md + audio/",
"output": "更新后的分镜.md(填充时长) + audio_info.json",
"command": "python scripts/validate_audio.py 分镜.md ./audio",
"check": ["音频存在性", "时长>0", "数量匹配"]
},
{
"step": 6,
"name": "scaffold",
"input": "分镜.md + audio_info.json",
"output": "script.py (伪代码框架)",
"template": "templates/script_scaffold.py",
"must_include": [
"calculate_geometry() - 几何建模",
"assert_geometry() - 几何验证(题目条件+精度) + 画布范围检查(边界+中心)",
"COLORS - 颜色定义",
"SCENES[] - 幕信息数组(从audio_info.json加载时长)",
]
},
{
"step": 7,
"name": "implement",
"input": "script.py脚手架 + 分镜.md + audio_info.json",
"output": "完整的script.py",
"rules": [
"根据分镜实现每幕动画",
"读白提到什么就高亮什么",
"画面时长 >= 音频时长",
"calculate_geometry()必须完整实现"
]
},
{
"step": 8,
"name": "check_and_render",
"input": "script.py",
"output": "视频文件 + 关键帧截图",
"command": "python scripts/render.py",
"check": ["代码结构检查(check.py)", "几何正确性", "高亮同步", "字幕清晰", "动画流畅"],
"on_fail": "回到步骤7修改代码"
}
]
步骤1:分析题目,推导数学事实
目标:建立正确的数学计算方法和流程,形成画出符合数学的图形的方法。
输出格式
## 数学事实分析
### 已知条件
- 条件1:...
- 条件2:...
### 推导的事实
1. **事实名称**: 描述
- 计算过程: ...
- 数学表达: ...
### 图形构建方法
- 点的坐标: ...
- 边的关系: ...
- 圆/弧的定义: ...
### 需要证明的结论
- 结论1: ...
注意:所有证明题需要证明的结论,在分镜中都可以作为已确立的事实来使用。
步骤2:HTML + SVG 可视化
目标:用 HTML + SVG 画出图形,展示画图过程和解答流程,为分镜做规划。
补充:如果用户已经提供了准确的HTML文件,描述了画图过程,可以按文件名要求复制一份,跳过生成文件。
输出要求
- 文件命名:
数学_{日期}_{题目简述}.html
- 包含:题目陈述、SVG 图形、分步解答、关键要素标注
- SVG 需要展示画图过程(如:先画三角形 → 再画圆 → 标注点)
步骤3:生成分镜脚本
目标:定义视频结构,不限制幕数,结尾预留音频文件名(时长为空)。
文件命名
{日期}_{题目}_分镜.md
分镜脚本结构
# 分镜脚本 - {题目名称}
## 分镜设计
### 第1幕:{幕名}
**画面**: ...
**字幕**: ...(简洁,≤20字)
**读白**: ...(详细,口语化)
**动画**: ...
**目的**: ...
---
## 音频生成清单(步骤4填写)
| 幕号 | 文件名 | 读白文本 | 时长 | 说话人 | 情感 |
|------|--------|----------|------|--------|------|
| 1 | audio_001_{幕名}.wav | "读白文本" | | xiaoxiao | 热情 |
| 2 | audio_002_{幕名}.wav | "读白文本" | | xiaoxiao | 平和 |
关键规范
- 幕号从1开始连续编号
- 文件名格式:
audio_{三位幕号}_{幕名}.wav
- 时长列为空,由步骤5填充
- 不限制幕数,根据内容需要决定
字幕退场约定(重要)
为了避免动画中文字忘记退场,在分镜的动画部分使用以下约定指定退场时机:
**动画**:
- 0.0s: 字幕"勾股定理"淡入
- 2.0s: → 字幕退场(或:字幕淡出)
- 3.0s: 图形高亮
退场标记方式(三选一):
→ 箭头符号表示退场(推荐,最简洁)
退场: 或 淡出: 显式标记
持续X秒 指定显示时长
示例:
**动画**:
- 字幕"正方形性质"淡入,持续3秒 → 自动退场
- 0.0s: 标题淡入 | 3.0s: →
- 公式分步显示,第5秒全部退场
参考示例
见 references/storyboard_sample.md - 第九十九题:证明四点共圆
步骤4:TTS 生成语音文件
使用脚本:scripts/generate_tts.py(Edge TTS 推荐)
执行命令
python scripts/generate_tts.py 分镜.md ./audio --voice xiaoxiao
输出文件
audio/
├── audio_001_开场.wav
├── audio_002_展示图形.wav
├── audio_003_定理证明.wav
├── ...
└── audio_info.json
audio_info.json 格式
{
"files": [
{"scene": 1, "file": "audio_001_开场.wav", "duration": 8.5},
{"scene": 2, "file": "audio_002_展示图形.wav", "duration": 15.2}
]
}
步骤5:验证并更新分镜时长
使用脚本:scripts/validate_audio.py
功能
- 读取
audio/audio_info.json 获取音频时长
- 验证所有音频文件存在且时长正常(>0秒)
- 更新分镜脚本的"音频生成清单"中的时长列
- 如果缺少音频或时长异常,报错提醒
执行命令
python scripts/validate_audio.py 分镜.md ./audio
验证失败情况
- 缺少音频文件 → 报错:"缺少第X幕音频文件"
- 时长为0或异常 → 报错:"第X幕音频时长异常,请检查格式"
- 分镜与音频数量不匹配 → 报错:"分镜X幕,音频Y个,数量不匹配"
步骤6:生成 script.py 脚手架
使用模板:templates/script_scaffold.py
输出:script.py(肯定 build 不过的伪代码框架)
脚手架必须包含的部分
from manim import *
import json
import os
class MathScene(Scene):
"""
数学教学视频场景 - 脚手架
根据分镜脚本和音频信息生成完整动画
"""
COLORS = {
'background': '#1a1a2e',
'primary': '#4ecca3',
'secondary': '#e94560',
'highlight': '#ffc107',
'text': '#ffffff',
'grid': '#2a2a4e',
}
SCENES = [
(1, "开场", "audio_001_开场.wav", None),
(2, "展示图形", "audio_002_展示图形.wav", None),
]
def __init__(self, **kwargs):
super().__init__(**kwargs)
self.audio_timings = self._load_audio_timings()
def _load_audio_timings(self):
"""从 audio_info.json 加载音频时长"""
pass
def calculate_geometry(self):
"""
计算所有几何元素的位置和属性
从步骤2的HTML画图中提取信息,建立数学模型:
- 所有点的坐标 (x, y) - ⚠️ 始终使用2D,z坐标始终为0
- 边的长度和方程
- 圆/弧的圆心和半径
- 交点计算
- 切线、法线等辅助线
返回: dict 包含所有几何对象的数据
"""
geometry = {
'points': {},
'lines': {},
'circles': {},
'arcs': {},
}
return geometry
def assert_geometry(self, geometry):
"""
验证几何计算的正确性(最小验证原则)
验证内容:
1. 题目给定的事实(如:两条边相等,谁是谁的一半)
2. 精度问题:使用相对误差比较,而非绝对相等
3. 画布范围检查:确保图形在可视区域内
4. 错误提示:所有assert必须用中文描述问题,包含具体数值和修复建议
=== 几何条件验证 ===
基于题目给定的条件,编写最小但关键的验证:
- 如果题目说 AB = BC,验证 |AB - BC| < epsilon
- 如果题目说 E 是中点,验证 AE = EB(考虑浮点误差)
- 如果题目说某角是直角,验证向量点积接近0
- 如果题目给具体数值(如边长为5),验证计算结果匹配
精度建议:
- 相对误差:1e-6 或绝对误差 1e-4
- 示例:assert abs(len_AB - len_BC) < 1e-4, "中文错误提示:AB长度不等于BC长度"
=== 画布范围验证算法 ===
目标:确保整个图形在画布内,且位于视觉中心区域
算法步骤(AI需要根据几何数据实现):
1. 计算所有几何元素的外接矩形 bounding_box
- 遍历所有点、线、圆的边界点
- 取最小x, 最大x, 最小y, 最大y
2. 验证矩形在画布范围内(考虑边距)
- 画布默认范围:FRAME_WIDTH=14.2, FRAME_HEIGHT=8
- 建议边距:四周各留 0.5-1.0 单位
- 验证:min_x > -7+margin 且 max_x < 7-margin
min_y > -4+margin 且 max_y < 4-margin
3. 验证矩形中心在视觉中心区域
- 画布中心:(0, 0)
- 视觉中心区域:中心 ±20%(即 x∈[-1.4, 1.4], y∈[-0.8, 0.8])
- 计算矩形中心:(center_x, center_y) = ((min_x+max_x)/2, (min_y+max_y)/2)
- 验证:center_x ∈ [-1.4, 1.4] 且 center_y ∈ [-0.8, 0.8]
4. 如果图形超出范围,AI需要调整几何计算的缩放或平移
"""