Small Models, Bounded Jobs: Building Lesson Agent for the Hugging Face Build Small Hackathon

Community Article
Published June 15, 2026

Backyard AI track — local MiniCPM5-1B, no cloud LLM API.

Lesson Agent — Slides generation in the Studio UI

TL;DR

Lesson Agent turns a topic and a grade level into a researched, sourced, downloadable PowerPoint — plus a voice practice session and a full agent trace — running entirely on a 1-billion-parameter local model (openbmb/MiniCPM5-1B). No OpenAI key. No cloud LLM call. Built for the Hugging Face Build Small Hackathon, Backyard AI track.


The problem

A teacher has one topic, one grade level, and a blank slide deck due tomorrow. Building a focused 5-slide lesson — researching the topic, structuring it for the right grade, formatting it into slides — takes 30+ minutes even when you know the material cold.

That's the entire brief I gave myself for Build Small: build something that turns "topic + grade" into a real .pptx, using a model small enough to run locally, on modest hardware, with no cloud LLM key.

The solution

Lesson Agent answers that brief with a bounded job, not a bigger model. Give it a topic and a grade level, and openbmb/MiniCPM5-1B — a 1-billion-parameter model — drafts, grounds, and assembles a real lesson deck entirely on your own machine. No OpenAI key. No cloud LLM call. Nothing leaves the building.

I've been building with AI since 2019, and the pattern I keep seeing with "AI agent" demos is the same: impressive chat, then a quiet dependency on someone else's frontier model and someone else's API key. That's fine for a demo. It's a liability for a classroom — teacher notes, student work, and lesson context end up leaving the building. So "runs locally" wasn't a limitation for this build, it was the actual design goal. The same "local-first" pattern that keeps a classroom's data inside the school also works for personal notes, private memory, or an internal "company-brain" — anywhere sending context to a third-party model isn't an option.

The trade-off is obvious: a 1B model is not a frontier reasoning engine. So Lesson Agent doesn't ask it to be one. It surrounds the model with four pieces that carry the weight: sources to ground its answers in real material, skills to structure its output into a lesson, tools to build the actual .pptx file, and traces so nothing it claims has to be taken on faith. Ground it, structure it, build it, show it. A 1B local model gets real work done when the system — not the model — carries the weight of "general intelligence."

The rest of this post is the technical walkthrough of how those four pieces fit together.

Under the hood: sources, skills, tools, traces

Four pieces make up the actual architecture of Lesson Agent:

Piece What it does Why it matters for a 1B model
Sources ResearchMind ingests URLs/PDFs/docs, chunks + embeds them (all-MiniLM-L6-v2), and retrieves passages with [n] citations via a local SQLite MemRAG store The model doesn't have to know the topic — it has to summarize verified material in front of it. Grounding compensates for a small model's thin world knowledge.
Skills An education-pptx skill shapes the raw model output into a grade-appropriate lesson structure (titles, bullets, speaker notes) The model doesn't reinvent "what does a lesson plan look like" on every call — the skill encodes that structure once.
Tools A deterministic tool (create_pptx, via python-pptx) turns the JSON outline into a real, downloadable .pptx The model's job ends at "draft the outline." Artifact creation is deterministic code, not another model call — no risk of the model "almost" producing a valid file.
Traces Every run logs the model preset, the skill steps invoked, and the tool calls made, written to outputs/traces/*.json You don't have to take the model's word for what happened. Open the trace, see the actual steps, in order.

Walkthrough: the Studio

The Space ships a custom Studio UI (Gradio 6 Server mode) with five surfaces: Research, Slides, Voice, Coach, and Debug/trace. Here's the flow, screen by screen.

1. Research — grounding with RAG

ResearchMind ingestion view — RAG Active badge

The teacher pastes a URL (Wikipedia, a curriculum page, a PDF). ResearchMind scrapes it, chunks it, embeds it, and indexes it locally. Once the RAG Active badge lights up, anything generated downstream can cite back to this material — [1], [2], etc. — so a teacher can verify where a slide bullet actually came from.

2. Slides — the money shot

Slides generation — outline preview and download

Topic, grade, and slide count go in. Click Generate. The local model drafts a JSON outline, the education-pptx skill shapes it for the grade level, and create_pptx produces a real .pptx — downloadable, opens cleanly in PowerPoint or LibreOffice. If RAG sources are indexed, the outline draws from (and cites) them.

3. Voice — TeacherVoice

TeacherVoice — back-and-forth voice practice

The lesson becomes a spoken, multi-turn conversation. Ask "what are the three main inputs for photosynthesis?" and get a spoken reply (Piper TTS), grounded in the same RAG index if documents are loaded. This is the tutor mode — back-and-forth, not one-shot.

4. Coach — EchoCoach

EchoCoach — pace, filler words, and rewrite feedback

Record up to ~30 seconds of yourself explaining the lesson. EchoCoach runs ASR, analyzes pace and filler words, charts it, and offers a rewrite — then reads the summary back via VoiceOut TTS. One-shot pitch analysis, as a contrast to TeacherVoice's ongoing tutor mode.

5. Debug — the trust layer

Agent trace — model preset, skill steps, tool calls

This is the real hackathon story. Expand the trace and you see: which model preset ran (minicpm5-1b), which skill steps fired, which tools were called (create_pptx), and in what order. Every badge the system claims — local, agent, bounded — is checkable here, not just asserted.

Settings & Classic tabs

Settings — model preset and runtime config

Settings expose the active model preset and runtime config directly — useful for judges or anyone forking the repo to swap in a different local backend (transformers or llama.cpp, via libs/inference/).

A Classic Gradio tab set (/classic) mirrors the same backends for anyone who prefers the default Gradio chrome:

Classic Gradio UI — overview

Implementation details

For anyone forking the repo or judging the architecture:

  • Skill loop: skills/education-pptx/SKILL.md → local LLM produces a JSON slide outline → create_pptx (python-pptx) turns it into a .pptx.
  • ResearchMind: ingest → chunk + embed (all-MiniLM-L6-v2) → SQLite MemRAG → retrieval with [n] citations, usable in chat and as slide grounding.
  • Inference: swappable local backends in libs/inference/; default preset minicpm5-1b in models.yaml, running on ZeroGPU via @spaces.GPU.
  • EchoCoach / TeacherVoice: ASR → analysis → coach LLM → TTS, all local.
  • Traces: every run writes outputs/traces/*.json — skill steps, tool calls, model preset — uploadable via scripts/upload_trace.py for the "Sharing is Caring" badge.
Topic + grade → skill agent (local LLM) → JSON slide outline → create_pptx → .pptx
                     ↑ optional: ResearchMind RAG / web ingest
                     ↓ trace JSON → outputs/traces/ (Sharing is Caring)

Hackathon badges this targets

Backyard AI · Tiny Titan (≤4B — MiniCPM5-1B clears this with room to spare) · OpenBMB · Off-the-Grid (fully local inference) · Sharing is Caring (trace upload) · Well-Tuned (optional LoRA fine-tune, in research/).

The takeaway

Lesson Agent isn't a demo of a 1B model being smart. It's a demo of a system being trustworthy: sources ground the facts, skills shape the output, tools create the artifact, and traces make every step inspectable. That's the actual unlock for small local models — and honestly, it's the same pattern that should back any "agent" claim, regardless of model size. Don't trust the model's word for what it did. Open the trace, verify it.

Try it

  • Space: build-small-hackathon/lesson-agent — set a topic and grade, ingest a source, generate a deck, expand the trace.
  • Demo video: YouTube
  • Repo: [REPO LINK] — fork it, swap in your own bounded job, run locally with uv sync --all-packages.

Build Small Hackathon, Backyard AI track. Experiment, improve, iterate. 🫡

Community

Sign up or log in to comment