DEV Community

Cover image for AI Agents Can't Watch Video. Mine Made Three Films Anyway.
Nunc
Nunc

Posted on • Originally published at hellonunc.com

AI Agents Can't Watch Video. Mine Made Three Films Anyway.

Martin Krpan is the story every Slovenian schoolchild knows: a salt smuggler meets the emperor's carriage on a snowed-in road too narrow for both, so he calmly lifts his loaded mare and carries her aside. I asked AI agents to turn it into an animated film. The catch: a language model cannot watch video, so it cannot check its own footage. I ran the experiment three times with three different AI setups. All three are live. The interesting result is not the films but what a blind director needs before you can trust its cut.

The idea comes from Andrej Karpathy's LOTR browser movie, which he rated "kind of janky but fun" and blamed on exactly this: LLMs can't perceive video, so they can't audit the worlds they build.

The rules, same for all three

  • Zero assets. No 3D models, no textures, no image, font or audio files. Geometry from Three.js primitives, sound synthesized in the browser. The one exception: narration, pre-rendered with a free tool; each film works without it.
  • Deterministic timeline. Every frame is a pure function of film time. No accumulated physics, no Math.random() at play time. Seeking to second 49.5 produces the same pixels every time, in every browser process.
  • It must be a film. Shots, hard cuts, title cards, subtitles, pacing, an ending. In Slovenian and English.

The determinism rule is the whole trick: if a frame is a pure function of time, a screenshot becomes a measurement. The agent can seek, look at the still (the one visual sense an LLM has), compare pixel hashes between runs, and export video frame by frame. Every verification idea below stands on that.

Film 1: one agent and a screenshot loop

The first run was a single Claude agent building scene 1: the road encounter, 75 seconds, 11 shots. One working day: 7.5 hours of build time, 3,505 lines of TypeScript.

The process rule that shaped it: after building, the agent must watch its own film as stills. A script seeks the timeline, captures screenshots, and the agent critiques them like a director: framing, scale, mesh intersections, poses. It found 24+ defects on its own this way, including the mare's muzzle pointing 43 degrees up (it read as antlers), the emperor's head clipping through the carriage roof, and two shots filming empty road because the carriage hadn't arrived yet.

What it never found: that the film was ugly. The four changes that most improved the result were one-sentence human comments ("the low-poly look is really ugly", "the background sound is annoying", "the narrator is robotic", "Discord says max 15 MB"). Each triggered a real engineering response: an art-direction rebuild with HDR bloom and golden-hour light, a remix measured 60 % quieter, pre-rendered neural voices, a two-pass encode to 13.4 MB.

The split was clean: self-review converged on correct. The human one-liners steered it to good.

krpan.hellonunc.com

Film 2: the full story, and a harness with teeth

The second run scaled up: the whole tale, 10 scenes, exactly 260 seconds, about 14,800 lines. This time three agents split the roles: one planned, one built, and a rival vendor's model (OpenAI Codex) attacked the plan before any code existed. Sixteen findings came back; the best one justified the setup: a dialogue line in the shot list was not in Levstik's text. The model had paraphrased the classic from memory. Codex fetched the pinned Wikisource corpus and proved it. That finding became a validator: every subtitle and narration line must be a verbatim substring of the 1858 text.

Beyond screenshots, this run made the aesthetics machine-checkable: six invariant classes asserted on every scene (palette only from named constants, prop sizes within 10 % of declared, exactly the declared lights, performance ceilings, no object jumping more than 0.5 m outside a cut). And determinism was tested, not assumed: two fresh renders of all ten scenes differed by 0.0000 % of pixels.

That check earned its keep. The sword in the duel was aimed using the giant's hand position from the previous frame, a frame-order dependency invisible to the eye. It surfaced as a 0.2 % pixel difference between playing into a moment and jumping straight to it.

Total cost: about 1.4 million tokens, roughly a cinema ticket, for a bilingual adaptation no studio would fund. The report's own conclusion: the same builder without the harness would have shipped the silhouette shot, the misaimed sword, and the paraphrased Levstik.

krpan2.hellonunc.com

Film 3: a different vendor runs it like a science fair

The third run gave the format to GPT-5.6 Codex, working interactively, and pushed verification the furthest: hypotheses with numeric pass criteria written down before evaluation. 78.000 seconds, 1,872 frames at 24 fps, and every single frame scanned for collisions between bounding boxes of every moving object.

The exhaustive scan embarrassed the still-image review. The stills looked fine while the team horses walked through Krpan for eight seconds and the carriage pole crossed the mare for fifteen. First scan: four sustained collision intervals. Final scan: 0 violations in 1,872 frames. Wheel rotation was derived from distance and radius instead of a multiplier that "looked right"; the final slip error was 1.6 × 10⁻⁷ scene units per frame, and zero frames rolled backward. The MP4 exports were decoded frame by frame: exactly 1,872 H.264 frames in each language edition.

The methodological lesson from this run: stills, continuous playback and an exhaustive numeric scan catch three disjoint classes of bugs. Any one alone lies to you.

krpan3.hellonunc.com (MP4 downloads on the page)

The scoreboard

Film 1 Film 2 Film 3
Scope scene 1, 75 s full story, 260 s scene 1 retold, 78 s
Built by one Claude agent Claude planner + builder, Codex as adversary GPT-5.6 Codex, interactive
Code 3,505 lines ~14,800 lines ~3,140 lines
Verification signature screenshot self-review 6 machine-checked invariants, 0.0000 % pixel determinism all 1,872 frames scanned, numeric pass criteria
Caught what the eye missed 24+ visual defects invented Levstik quote, frame-order bug 4 collision intervals, backward wheels

Three stills of the same moment from three AI-built films: Krpan carrying his loaded mare off a snowy road. Film 1 is warm and pastel with soft snowfall, film 2 is pale blue and cinematic with a Slovenian subtitle from Levstik, film 3 is a deeper green winter scene with the carriage horses waiting on the right

The same moment in all three films: Krpan lifting the loaded mare off the road.

What all three runs agree on

"It runs" is a weak finish line. Every version ran fine while hiding collisions, backward wheels, a phantom sword or paraphrased text. The quality came from the harness: determinism, screenshots as measurements, invariants, a rival model reading the plan.

The human contribution is taste, not code. Across all three films I never edited a line. My inputs were the story choice, the constraints, and one-sentence quality judgements. The agents handled everything else, including finding most of their own bugs.

Determinism is the keystone. One property served four masters: frame-exact scrubbing for viewers, screenshot audits for the agent, regression checks for refactors, and clean video export.

Wrapping up

A language model cannot watch video, but it does not need to. If every frame is a pure function of time, screenshots become measurements, invariants become tests, and a blind director can prove its footage is right instead of hoping. The films are the demo. The harness is the product.

Top comments (0)