research
Video Engine
One sentence in, a narrated animated maths video out, with nothing drawn by hand.

This is the system behind the videos on my home page. You give it a sentence and it gives you back a narrated, animated explainer. No part of the output is drawn by a person.
How it is put together
A Director plans the video shot by shot. A Scriptwriter writes the narration for each shot. An Animator writes the Manim code that draws it. Then two things stand between that code and the render:
An AST reviewer parses the generated code and applies more than fifteen static rules — objects off-screen, labels overlapping, a scene whose declared runtime does not match its animations. It uses no model at all. It is a linter, and it catches a whole class of failure faster and more reliably than asking another model to look.
A three-tier debugger handles what the reviewer flags: deterministic fixes first, then an AI repair pass, then a retry. Failures are written to an error-learning database, so a mistake made once informs the next run.
Code generation is grounded in RAG over the Manim documentation, indexed in Qdrant with Vertex AI reranking. Ungrounded, the models invent API that does not exist, confidently, in a library whose surface changes between versions.
What twenty-two runs showed
I treated each pipeline change as a hypothesis with a scorecard rather than a guess, which is the only reason I can say anything precise about it.
- 0.37 → 0.89
- mean review scoreacross 22 dated runs
- $0.33 → $0.16
- cost per videoroughly halved
- 0
- failed shots in the final runfive videos, 875s wall clock
The final sweep produced five videos in 875 seconds at 720p30, mean review score 0.81, at about $0.21 each. Earlier runs were 480p at 15fps, so the quality improvement is real rather than a scoring artefact.
Per video, the numbers are unglamorous and specific: the Pythagoras video is 5 shots and 93 seconds at $0.23; conditional probability is 6 shots and 119 seconds at $0.19 and scored highest at 0.888.
The bug I would not have found by reading code
Audio and video drifted apart. Not dramatically — about a third of a second per shot, which across a twenty-shot video is nearly six seconds by the end, enough that the narration describes something that left the screen.
The cause was that the video track was assembled with xfade, which overlaps
clips, while the audio track was assembled with concat, which butt-joins them.
Every transition therefore lost a fraction of a second on one track and not the
other, and the error accumulated.
The fix was to stop letting two tools each decide timing. A single computed
timeline became the source of truth, audio is placed against it with adelay and
mixed without normalisation, shots whose narration failed get generated silence
so the offsets still hold, and every shot’s duration is validated from both sides
before it renders.

What I would change
The reviewer scores geometry and layout well and has almost nothing to say about whether an explanation is any good. A video can score 0.89 and still teach badly. Fixing that means a rubric a teacher would recognise, and I have not built it.