Technical Explainer Video
Three checkpoints — each requires the user to explicitly say "OK" before moving to the next. The user's global setting "go ahead without confirmation" does NOT apply to these three checkpoints; this is a special review process the user requested for this skill. If the user says "don't voice over yet / don't do it yet", stop at the current stage.
Defaults (use if the user doesn't specify, write into script.md front matter):
- Audience: college students who know Python but have basically forgotten the relevant course. Write following the
references/kepu-style.mdapproach: concrete before abstract, "if you were to design it", a single physical diagram running through the entire episode, no more than 6 new terms per episode; registers, source-level details go into the "Advanced" chapter at the end of each episode. - Goal: viewers can write it in PyTorch after watching.
- Structure: three parts, math principle → PyTorch tools needed → unified coding.
- Within each episode: "overview–detail–summary": begin with the questions the episode answers and a section map, unfold each section in the body (with a route map in the corner highlighting the current section), end with one-sentence conclusions per section and a teaser for the next episode.
- Duration: 8–12 minutes per episode (user changed on 2026-10-24: fewer episodes, fewer uploads, less chance of hitting platform limits), a topic typically has 2 episodes, at most 3.
- Analogies: allowed, but only for one point: return to the main topic right after the one-sentence analogy, at most one analogy per concept (kepu-style.md rule 5).
- Voice:
voice: volc(Volcengine preset voice zh_female_vv_uranus_bigtts); if credentials are missing from~/.volc_tts.env, tts.py automatically falls back to edge-tts Xiaoyi with a hint.
Stage 0: Gather Materials
If the user mentions notes (e.g., Obsidian), first locate and read them thoroughly. Use the structure, conclusions, and numbers from the notes as the authoritative source.
Stage 1: Outline (given in the chat)
First line: write a one-sentence project statement: "This episode will make viewers of X able to Y." Then for each episode provide a one-line cover hook + right-side visual (see references/cover-guide.md) — review together with the outline.
Write a short table following references/outline-template.md: the problem each chapter solves, new concepts, code that runs, duration, plus the episode splitting plan and what won't be covered.
First read references/kepu-style.md. Design opening, pacing, terminology, and ending according to the "opening formula", "pacing", "terminology and difficulty", and "ending formula" in references/script-guide.md; in the outline, mark where each climax point falls in a chapter.
When writing math, first give the calculation target (e.g., out_i = Σⱼ aᵢⱼ vⱼ), then derive each component, so that dot product, softmax, scaling all appear "because they are needed".
Stage 2: Code → Script → Check → Annotate → Finalize
Script writing principles: First explain the design motivation, then the mechanism, then the results. Prioritize clarifying "what problem existed → what the designer wanted to solve → why this approach was chosen → how it works". Allow for adding steps, examples, and necessary precision, but only introduce new concepts that are essential for understanding the current principle; when a new term first appears, explain it using existing knowledge or concrete examples. Adjust the Advanced chapter based on the knowledge foundation assumed for that chapter.
- Write tutorial code
py/tutorial.pyand run it for real. Useshow(key, value)to exportpy/values.json. All numbers, shapes, True/False shown on screen come from here.- When a small example has an interpretable meaning, manually set the weights and comment in both code and narration that "manually set, real models learn through training".
- When demonstrating "why", use real comparisons: e.g., allclose of associativity with/without softmax, softmax Jacobian norm before/after scaling.
- Following
references/kepu-style.mdandreferences/script-guide.md, writescript/script.md(format below). Go through both self-check lists. For each "Draw:" line, write clearly what the viewer should see change, and what understanding that drawing helps achieve; first determine the expression goal, without locking in the tool. Visuals can be realized with web canvas, Remotion, Manim, Blender, or a more suitable tool — choose per shot after finalization. Scenes that need numbers, code, or shapes must still be consistent withpy/values.json,py/tutorial.py. Check episode duration by the adjusted total: numbering lines word count ÷ 4.5 ÷ 60, plus about 0.5 minutes for chapter cards and pauses. If it exceeds 12 minutes, adjust the episode split at this stage (don't wait until after dubbing to discover it's too long). - After the first draft is complete, perform in order: zero-knowledge check, fact check, and language polishing:
3b. Zero-knowledge entry barrier check (required): Start another agent, give it only script.md and one prompt: "You can write Python, and you've basically forgotten this topic's course." Do NOT give it code or notes. Have it mark line by line: ① words or reasoning leaps that are unclear; ② places where too many new things are introduced in one sentence, requiring rewinding; ③ mismatches between visual descriptions and narration.
Require it to point out exactly which step of explanation is missing, especially check if it can follow the flow "problem → design motivation → mechanism → result". It may suggest adding steps, examples, or necessary precision, but must not introduce new concepts unrelated to the main thread just to add detail. Modify each issue, then recheck with the same conditions until there are no type-① or type-② marks; type-③ marks must also be fixed. Record the modification log and give it to the user along with the final submission. Adjust the check for the Advanced chapter based on its assumed knowledge foundation.
3c. Fact check (required): Start another agent, give it script.md and the notes. Only mark factual errors or statements that could lead to wrong understanding, and explain the basis; do not require additional knowledge points, edge cases, or extra details. Allow pedagogical simplifications; if viewers might mistake a simplified statement for a strict definition, briefly note in the narration "this is a simplification". When fixing, prioritize equally simple but accurate wording, do not pile up qualifiers. When in conflict with 3b, find an expression that is both accurate and easy to understand; do not retain factual errors, and do not let precision overshadow the teaching thread. If fact corrections affect understanding or visuals, re-run the relevant 3b check.
3d. Use the
humanizer-zhskill to polish line-by-line on the numbering lines and "Read:" lines (remove AI flavor). Preserve the meaning of numbers, terms, code, and "Draw:" lines — do not add or remove knowledge points without authorization. After polishing, verify that code results, visual descriptions, and narration are consistent, and recalculate the duration for each episode. - Send the file to the user (SendUserFile), asking them to write comments below each sentence starting with
>(Obsidian's> [!comment]is also fine). If they want to annotate in Obsidian, copy the file to their vault, then read it back after changes. - Process annotations: modify each one → delete processed annotation lines → list in the chat how each was handled → ask the user to review again, until they say it's finalized.
- Do not do voiceover or produce formal visuals before finalization. To verify whether a complex shot can be realized, you can make a short mockup; mockups do not replace script review.
script.md Format
---
title: Attention → MHA → GQA
subtitle: From Math Principles to PyTorch Implementation
audience: College students with some CS background
voice: volc
volc_speaker: zh_female_vv_uranus_bigtts
volc_resource: seed-tts-2.0
episodes: ch0,ch1,ch2,ep1_end | ep2_start,ch3,ch4,ep2_end | ep3_start,ch5,ch6
episode_titles: Episode 1 Title | Episode 2 Title | Episode 3 Title
---
## ch0 | Opening
1. Subtitle original text, one sentence per visual beat.
- Read: TTS pronunciation (write only if different from subtitle; write homophones like "háng" for the character "行" as "háng")
- Draw: What appears on screen during this sentence (required, the visual agent implements it)
> Comment: User writes here
## ep1_end | Next Episode Preview
1. Next episode covers…
- Draw: EP1 end card
- Chapter ids:
ch0, ch1, …; episode intro/outro useepK_start/epK_end, visuals are auto-generated by the generic EpCard; newly added sentences must also be reviewed by the user. - Overview–detail–summary:
epK_startwrites 2–3 sentences: ① the question this episode answers ② "This episode covers N things: …" (one-to-one with the episode's chapters);epK_endwrites 2–3 sentences: one-sentence conclusion per chapter + next episode teaser. Episode 1's opening chapter (ch0) must also include the episode map. The front matterepisodesdetermines which sections appear in the map; section names are taken from chapter titles. - Subtitles don't need manual line breaking; tts.py will split by punctuation into short strips of ≤22 character width.
Stage 3: Generate Video
For each shot, choose the production method that best explains the principle: 2D relationships, code, and data can use web canvas, Remotion, or Manim; spatial structures and camera motion can use 3D tools like Blender. Also, newer more suitable tools are allowed; do not increase complexity just to use a particular tool. The existing template/ is the Remotion composition and delivery pipeline; shots produced with other tools should first output video or image assets, verify they can be integrated into this pipeline while maintaining subtitle, voiceover, and beat synchronization, then be used in the formal chapter. references/visual-guide.md and references/agent-brief.md components, paths, and commands only apply to Remotion chapters; other tools follow their own layout, color scheme, real data, and visual self-check principles.
- Copy
template/to the user-specified directory (default~/Videos/<topic>, ask first), and placepy/andscript/inside it. Install dependencies only once: For a series (multiple projects in the same parent directory, e.g.,~/Videos/nudgecode-algorithms/<chapter>/), installnode_modulesonce in the parent directory (copy the template's package.json and runnpm installthere), then each projectln -s ../node_modules node_modules; for a single project, install inside the project. Only run onenpm installat a time; concurrent installs will corrupt the packages. After installation, verify thatnode_modules/react-dom/index.jsexists (this package has been known to be broken in npm cache; if missing, copy the same version from another project). - Run
python3 tools/md2json.py(will reject if there are unprocessed annotations) →python3 tools/scaffold.py→python3 tools/tts.py. Generatespublic/audio/*,src/timeline.json; voiceover is cached, only re-synthesizes changed sentences. - First produce the opening and Chapter 1 to establish the visual style (tackle the hardest shot first; for pacing and transitions, refer to
references/plotome-lessons.md). For Remotion shots, usenode tools/stills.mjs ch1 && tools/sheet.sh ch1to check; for shots made with external tools, check the original assets and the composited frames after integration, then send a preview to the user. If the visual style has already been confirmed by the user in a series (e.g., the first project of the same series), don't ask for review again — continue directly.stills.mjsreusesout/bundle(generated viatools/bundle.mjs, only rebuilds if source files changed), no longer creating a new ~90 MB bundle directory in$TMPDIReach time. - Once the user approves, distribute the remaining chapters among multiple agents launched simultaneously in a single message (each covering 1–2 chapters):
- For Remotion chapters: fill in
references/agent-brief.mdwith the project's details and save it asAGENT_BRIEF.mdin the project root, and copyreferences/visual-guide.mdintoVISUAL_GUIDE.md. For external tool shots, write a short task description, agreeing on asset format, duration, file location, and integration responsibility with Remotion; do not force the restriction of only modifyingChN.tsx. - If narration changes, send a message to the relevant agent specifying which sentences changed and that the timeline has been updated.
- For Remotion chapters: fill in
- After all chapters return, the main session checks composited frames for each chapter: overlaps, subtitle conflicts, consistency between visuals and "Draw:" lines, whether numbers come from values.json; for external assets, also check the imported duration and beat.
- After
npx tscpasses, runtools/render.shin the background: outputsout/epK.mp4+out/epK.srt+out/covers/epK.jpgper episode, normalizes to -16 LUFS. Roughly 1 minute of rendering per minute of video. Do not modify audio or code during rendering: the mixer reads audio only in the final step; overwriting mid-render will mix old and new audio together.render.shuses a machine-wide lock (lockf /tmp/remotion-render.lock) to guarantee only one episode renders at a time: multiple projects rendering simultaneously won't be faster (CPU is already saturated), only consume more memory and disk. Multiple projects can startrender.shsimultaneously; they will queue automatically. - Covers: Following
references/cover-guide.md, for each episode writesrc/covers/CoverEpK.tsxand register it insrc/covers/index.ts(black background, hook in large font + yellow highlight, large visual on the right);render.shwill automatically outputout/covers/epK.jpg. Episodes not registered use a fallback. Collage all covers into a single image and send to the user for review. To re-render a single cover:npx remotion still out/bundle cover-epK out/covers/epK.jpg. - Delivery: Send the user the mp4, srt, cover, and
py/tutorial.pyfor each episode via SendUserFile. Ask the user to read through the srt themselves — this often reveals issues. - When publishing is needed, switch to the
video-publishskill. Before publishing, go through the compliance checklist inreferences/plotome-lessons.md(AI labeling, music licensing, attribution).
Batch Production (Multiple Projects in Parallel)
- Keep concurrently open sessions at 3–4: opening too many will quickly hit usage limits, and Volc TTS will also report concurrency overrun (tts.py already has backoff retry and concurrency of 2).
- Only parallelize script writing and visual production; rendering goes through the render.sh machine-wide lock for queuing.
- Disk: Each chapter's
out/bundleis ~90 MB, screenshotsout/checka few tens of MB, final video ~10+ MB per episode. Before starting a new batch, checkdf -h.$TMPDIR/remotion-webpack-bundle-*are leftover temp bundles from old scripts; they can be cleaned. - When the user agrees to "render a batch → upload directly → delete final video", see the "batch pipeline" in
video-publish.
Main Session Scheduling Pipeline (Knowledge base 2026-10-30 ~ 11-03 ran successfully, two articles per batch)
- Script stage agent (one per article, two simultaneously): Outline → run tutorial for real, export values.json → full script → zero-knowledge check (start another agent, at most 8 rounds, then fix based on the last round) → fact check (start another agent against notes) → humanizer → adjust episode durations → copy template, symlink node_modules → md2json / scaffold / tts → write AGENT_BRIEF.md, VISUAL_GUIDE.md, shared physical diagram component
src/lib/<name>.tsx(first define layout constants) → produce ch0, ch1. In the report, list "discrepancies between notes and actual measurements". - Main session reviews ch0/ch1 collage; if the visual style is fine, continue without waiting for the user.
- Visual fan-out: Fill in
references/agent-brief.mdas a shared brief and write it to/tmp/claude-501/brief_<article>.txt(for the second article, use sed to change paths/component names/lock names then append "supplements for this project"). Each agent's prompt is only one sentence: "First use Read to fully read the brief and strictly follow it. You are responsible for chX, chY." Each covers 2–3 chapters; the cover is assigned to the last agent. Launch simultaneously in a single message. - Collect known issues: When each visual agent returns, note down its reported "known issues / numbers not in values.json / changes not re-reviewed".
- Full-video review agent (one per article, template
references/review-brief.md): Write the issues collected in step 4 into "known issues to fix". - Rendering: Both articles start
tools/render.shin the background; the machine-wide lock queues automatically. Use a background until loop to wait forout/ep3.mp4to appear. - Spot check (main session does it itself, don't trust reports): For each episode, run
ffmpeg -af volumedetect(normal mean ≈ −19 dB, max ≤ −1.2 dB); for one episode per article, run-vf "fps=1/60,scale=480:-1,tile=4x3"to create a grid and use Read to inspect; confirm all three covers exist inout/covers/. - Upload: Hard link
out/parts/P<k> <hook>:<topic>.mp4+out/upload_meta.md(including a supplementary description paragraph), then queue according to the "append to existing manuscript" method invideo-publish. After uploading, update PROGRESS.md and the kanban; send the description paragraph to the user.
Hitting Usage Limits / Interruption
- Hitting the usage limit will kill all running agents. After recovery, send each agent a "continue" message via SendMessage; it will pick up with context — do not start new agents (that will duplicate work and overwrite each other).
- Keep the number of concurrently running agents at ~12 or fewer (2 articles × 5–6 visual agents).
Discrepancies Between Notes and Actual Measurements
- Knowledge base notes (vault) are read-only. When actual measurements disagree with notes, the video follows the actual measurements; list each discrepancy in the report for the user to decide whether to update the notes.
Changes After Finalization
- Changing narration: modify script.md → md2json → tts (only re-synthesizes changed sentences) → check affected chapters' visuals.
- Changing the number of sentences will cause visual misalignment: for chapters where visuals are already complete, change only the wording, do not add or remove sentences; to add content, add it as a new sentence chapter (e.g., epK_start).
- Visual agents only implement based on
visual; if they have questions, report to the main session — do not change narration on their own.
Voice
- Volcengine preset voice (default,
voice: volc):zh_female_vv_uranus_bigtts, resourceseed-tts-2.0. The user selected this for the GQA episode; the quality is significantly better than edge-tts. If front matter doesn't specifyvolc_speaker, this voice is used. Credentials are in~/.volc_tts.env(already configured); onlyVOLC_APPID/VOLC_TOKENare needed. Optional:VOLC_SPEED(1.0 normal). - Changing voices: write
volc_speaker: <voice ID>in front matter. Preset voices automatically useseed-tts-2.0; voices starting withS_(cloned) automatically useseed-icl-2.0(orVOLC_RESOURCEfrom env). You can also specifyvolc_resourceexplicitly; writev1to use the old interface, in which case you can also setVOLC_CLUSTER(default volcano_icl). - The user's cloned voice (
VOLC_SPEAKER_IDin env, starting withS_) currently reportsresource ID is mismatched with speaker; first confirm the voice version, training status, and associated appid in the Volcengine console before using it — don't try until it works. - Do not print env file contents. For new projects, first synthesize a few sentences from one episode with
--onlyto preview, then do the full episode. - edge-tts (fallback):
voice: zh-CN-XiaoyiNeural; other options: YunxiNeural, YunyangNeural, XiaoxiaoNeural. When Volcengine credentials are missing, tts.py automatically uses Xiaoyi. - Changing voice only requires re-running tts.py; visuals align automatically based on beats — spot check the collage.
English Voiceover (2026-11-03)
- edge-tts
en-US-AndrewMultilingualNeural: The user selected this after listening to 9 voices. Free, no key required, but it uses an unofficial Edge TTS interface: may be rate-limited/disconnected (tts.py retries), commercial use is unclear, and the interface may change. Front matter:voice: en-US-AndrewMultilingualNeural. - Volcengine
seed-tts-2.0'sen_male_tim_uranus_bigttsanden_female_dacey_uranus_bigttsare available (fallback);seed-tts-1.0's*_mars_bigttsEnglish voices get a 403 on this account (not enabled). The Chinese voice vv can also read English but has a noticeable accent. - Preview: same ~20-second English opening, produce one mp3 per voice, then concat with ffmpeg (apad 1.2 seconds after each) into one clip and send to the user.
Bilingual Chinese-English (Pilot)
- Pilot project
~/Videos/knowledge-base/llm-13-rag-agent-en: newly written English conversational narration (not translation from Chinese), each sentence with a Chinese translation below; two-line subtitles (English on top, Chinese slightly smaller below); scene labels in English. - Specific modifications to subtitle components and md2json will be written back here and in the template after the pilot is complete.
- Do not append English versions to Chinese collections; publication destination (new Bilibili article / YouTube) is determined by the user.
File Overview (template/)
| File | Purpose |
|---|---|
tools/md2json.py | script.md → script.json (check annotations, parse episode splits) |
tools/scaffold.py | Generate chapter placeholder components and src/chapters/index.ts |
tools/tts.py | Sentence-by-sentence dubbing, split short subtitles, write timeline.json; supports edge-tts / Volcengine |
tools/stills.mjs + sheet.sh | Screenshot at 80% of each sentence and compose into 3×3 grid (SCALE=1 for full size) |
tools/render.sh | Per-episode rendering + subtitle merge + loudness normalization |
src/lib/beat.tsx | Beat synchronization (useBeat), chapter title card, subtitles |
src/lib/ui.tsx | CodePanel / Matrix / Fade / Tag / H / Tex (KaTeX formula) |
src/lib/EpCard.tsx | Episode intro/outro cards |
src/lib/Cover.tsx + src/covers/ | Cover components (CoverFrame / Hl / CodeVisual / BigNumber) + per-episode custom cover registration |
src/lib/algo.tsx | Algorithm-related components: array cells, dict, trace table, problem statement card |
tools/bundle.mjs | Bundle once, reuse out/bundle |
src/lib/library.tsx | Optional: tensor "library" analogy components (Building / Corridor) |
Reference Documents
references/script-guide.md: Script writing guide;outline-template.md: Outline table.references/visual-guide.md/agent-brief.md: Visual specifications, visual agent instructions.references/cover-guide.md: Cover specifications.references/plotome-lessons.md: Pacing, transitions, music, compliance (inspired by plotome).references/production-retro-2026-10.md: Postmortem of nudgecode 13-chapter batch production — pitfalls and countermeasures.references/production-retro-2026-11.md: Postmortem of the two-articles-per-batch scheduling pipeline for knowledge base.references/review-brief.md: Full-video review agent template.rethinkfun-style.md/cishoon-style.md: Analysis of YouTubers the user likes.
Pitfalls Encountered
- macOS
sayis too robotic; use edge-tts. - Code and symbols must be written as pronunciation in "Read:" lines; for the homophone "行" (háng), write as "航".
- Before discussing numbers of a real model, verify its architecture (e.g., Llama-2-70B itself uses GQA; if calculating based on 64 heads and saying 10 GB, you must say "assuming MHA").
- Randomly initialized attention is too uniform and meaningless: either manually set weights, or change the random seed to pick one with more contrast.
- Use
tools/stills.mjsfor screenshots (bundles only once) — much faster thanremotion still; first render will download headless Chrome. - Don't write
cat > filewithout input in bash — it will hang forever waiting for stdin. - Screenshots are taken at 80% of each sentence: animations that appear after 80% (red X, late large text) won't be captured; capture them separately or move the appearance time earlier.
- When visual agents run in parallel, syntax errors in someone else's chapter can break the bundle: wait a minute or two and retry, don't modify other people's files.
- Review agents have previously "cleaned" old screenshots: the brief must say "do not delete any files (overwriting screenshots is fine)".
- Disk: Each article project is ~0.5 GB, final video ~10+ MB per episode; running out of disk during rendering will give
No space left on device. Before starting a new batch, rundf -h; if below ~15 GB, first list cleanable groups (tool caches, conda clean, etc.) for the user to choose, and require user approval before deleting. - Chapter title cards and episode intro/outro cards add roughly 10 seconds per episode; estimate final duration as TTS measured duration + 10 seconds.
- Visual agents will register entries in
src/covers/index.tsas a side effect: this is necessary for cover generation and is allowed. - When waiting for background rendering, do NOT use
pgrep -f render.sh: the waiting command's own command line also contains that string, so pgrep will always match itself, causing idle hangs for hours. Only wait forout/epK.mp4to appear (or an error in the log).