All projects

Case study

Grasp.ai

A web app that turns an age, a subject and a topic into a lesson plan, then a video script, then AI-drawn scenes with narration.

YHack 2024: one topic in, a lesson plan, a script and narrated scenes out

Who had the problem#

Writing lesson plans is careful, intensive work for teachers, and a lot of it repeats. One of us has parents who are both educators, and he watched them work tirelessly on lesson plans for their students. Grasp.ai started with them.

An AI model could take on some of that work. But a model writing from memory can state a wrong fact with full confidence, and a teacher who has to check every line is back to doing the work.

What I built#

A teacher enters an age (1 to 100), a subject and a topic, and Grasp.ai writes a lesson plan for that age group. One click turns the plan into a video script, and one more turns the script into the parts of a video: an AI-drawn image for each scene and a narration clip for each spoken line, with a different voice for each speaker.

The teacher stays in charge at every step. The script and video steps each open in an editable text box filled with the last stage's output, so a teacher can fix a fact or add their own material before moving on. The home page greets you with a stippled illustration drawn from 7,500 dots.

How it works#

A React frontend, with one screen per stage, posts JSON to a Python Flask server: one endpoint writes the lesson plan, one writes the script and one makes the media. GPT-3.5 Turbo does the writing at a low temperature (0.2), DALL-E 3 draws each scene at 1792x1024, and OpenAI's tts-1 model voices each line. The diagram lays out the full pipeline, from topic to narration.

The full pipeline, from topic to narrationThe React frontend posts the topic to a Flask server that grounds the lesson plan in real pages: Google results, 3 usable sources, then chunk summaries. GPT-3.5 Turbo writes the lesson plan and the script; the script splits into scene directions for DALL-E 3 and spoken lines for tts-1, and a canvas player plays them.React frontendone screen per stage100 Googleresultsdrops Google, Amazonand book links3 usablesourcesat least 5,000characters eachChunksummaries10,000-characterchunks attemperature 0Lesson planGPT-3.5 Turbo, fromonly those summariesScriptGPT-3.5 Turbo attemperature 0.2Blocksblank lines splitthe scriptDALL-E 3each scene at1792x1024tts-1the next voice foreach new speakerCanvas playermoves on wheneach clip endstopic[scenes]linesThe full pipeline, from topic to narrationThe React frontend posts the topic to a Flask server that grounds the lesson plan in real pages: Google results, 3 usable sources, then chunk summaries. GPT-3.5 Turbo writes the lesson plan and the script; the script splits into scene directions for DALL-E 3 and spoken lines for tts-1, and a canvas player plays them.Reactfrontendone screenper stage100 Googleresultsdrops Google,Amazon and booklinks3 usablesourcesat least 5,000characters eachChunksummaries10,000-characterchunks attemperature 0Lesson planGPT-3.5 Turbo, fromonly thosesummariesScriptGPT-3.5 Turbo attemperature 0.2Blocksblank lines splitthe scriptDALL-E 3each scene at1792x1024tts-1the next voice foreach new speakerCanvas playermoves on wheneach clip endstopiclines
The full pipeline, from topic to narrationDashed box: an AI model or agent
  1. The React frontend, one screen per stage, posts the topic as JSON to the Python Flask server.
  2. The server asks Google for 100 results and drops Google, Amazon and book links.
  3. It keeps fetching until it has 3 usable sources, each with at least 5,000 characters of paragraphs.
  4. Each source is cut into 10,000-character chunks and each chunk is summarized at temperature 0.
  5. GPT-3.5 Turbo writes the lesson plan from only those summaries, then the script.
  6. Blank lines split the script into blocks: a block in square brackets becomes a DALL-E 3 prompt, and a spoken line becomes narration with tts-1, each new speaker getting the next voice.
  7. In the browser, a canvas player draws each scene and moves on when its clip ends.

The lesson plan is grounded in real pages. The server asks Google for 100 results on the topic, pulls the result links out of the page, drops Google, Amazon and book links, and keeps fetching until it has 3 usable sources. A page only counts if the paragraph elements Beautiful Soup finds add up to at least 5,000 characters. Each source is cut into 10,000-character chunks (at most 10), each chunk is summarized at temperature 0, and the final prompt tells the model to use only those summaries.

The video step reads the script's own format. Blank lines split it into blocks: a block in [square brackets] is a scene direction and becomes a DALL-E 3 prompt, and a block like "Teacher: ..." becomes narration, with each new speaker getting the next voice on a list. In the browser, a canvas player draws each scene scaled to fit and moves on when its clip ends. The home page art adapts Mike Bostock's d3 Voronoi stippling example: 80 passes of weighted Voronoi relaxation run in a Web Worker, so the page stays responsive while the dots settle.

The hardest part#

Trust was the real problem. AI text was unreliable, and a lesson plan with a made-up fact is worse than no plan at all. So we scraped a Google search for the topic and only let the model use what we scraped.

That decision turned into engineering work of its own. When a site refuses the plain request, the fetch retries with a browser User-Agent. Thin pages with under 5,000 characters of paragraphs get skipped, and long pages are too big for one prompt, so each is summarized in 10,000-character pieces before the final prompt ever sees it.

The cost was speed: one lesson plan can wait on several page fetches and up to 30 summary calls before the real prompt runs. For a classroom tool it was the right trade, with slower answers built from real pages instead of the model's memory.

Results in numbers#

We submitted Grasp.ai to YHack 2024 on March 31, 2024 with the full pipeline in place: a topic goes in, and a lesson plan, a script, scene images and narration come out. The repo still holds narration the pipeline saved, including one set of 11 clips that adds up to just over 3 minutes of spoken lesson.

The player page plays a saved set of 10 generated scenes and 11 audio clips, because the live video output isn't wired into it yet, and the repo has no tests beyond the Create React App starter file.

The same idea shows up in my later projects: tie the model to something real. RareVerse only lets its AI pick researchers named in real PubMed papers and NIH grants, and Brownie fills a form only from passages in your own documents, showing the passage behind each value.

What's next#

If I picked Grasp.ai up today, I'd start with 2 gaps in the code. I'd wire the player to the live video output, and I'd keep the line breaks in a script the teacher edits. Right now the editor turns every newline into a space as soon as the teacher types, and the video step splits scenes on blank lines, so an edited script reaches it as one block.

Then I'd show the sources. Our Devpost listed cited references as a planned feature, and the scraper already has the address of every page it reads. After that I'd swap the scraped results page for a proper search API, add the accessibility features for people with learning disabilities that we planned, and run the beta with teachers and students that our Devpost hoped for, to find out if it really helps them.