Understanding the Two-Stage Generation Pipeline in OpenMAIC: From Raw Material to Interactive Lessons

OpenMAIC converts PDFs, Word documents, and multimedia files into structured lessons using a two-stage generation pipeline that first creates a pedagogical outline via LLM planning, then renders each section into interactive scenes with quizzes, simulations, and voice-overs.

The OpenMAIC platform transforms static learning materials into dynamic, AI-generated courses through a sophisticated two-stage generation pipeline. This architecture cleanly separates high-level instructional planning from low-level content production, enabling modular customization and scalable lesson creation. By leveraging large language models for both pedagogical structure and scene composition, the pipeline delivers complete interactive lessons according to the THU-MAIC/OpenMAIC source code.

How the Two-Stage Generation Pipeline Works

The pipeline processes raw educational content through five distinct phases, orchestrated by the @openmaic/sdk package and executed asynchronously.

  1. Input Extraction – The @openmaic/storage package handles file ingestion, using specialized extractors to convert PDFs, PowerPoints, Word documents, images, and audio/video into plain text or structured data for downstream processing.

  2. Outline Generation – An LLM-driven planner analyzes the extracted content and produces a hierarchical teaching flow (chapters → sections → topics) stored as a structured lesson outline.

  3. Scene Generation – Each node in the outline expands into a concrete "scene"—whether a slide, quiz, interactive simulation, or project-based-learning (PBL) activity—complete with UI assets and narration scripts.

  4. Asset Rendering – Generated media (images, audio, video) are stored via @openmaic/storage HTTP contracts and linked to their respective scenes.

  5. Async Job & Polling – The entire process runs as a background job. Clients poll the job status until the complete lesson (outline + scenes) becomes available.

The high-level description of this workflow appears in README.md at lines 708-715.

Stage 1: Outline Generation

The first stage focuses on pedagogical planning. The system feeds extracted text into a planner prompt defined in packages/@openmaic/generation/prompts-pbl/planner-system.md. This LLM prompt instructs the model to analyze the source material, identify logical teaching progressions, and output a hierarchical outline.

The outline serves as the architectural blueprint for the lesson, determining chapter boundaries, section ordering, and topic depth. By isolating planning from production, developers can swap planner models or fine-tune the system prompt in planner-system.md without affecting scene rendering logic.

Stage 2: Scene Generation

The second stage handles UI material creation. For every node in the outline generated during Stage 1, the pipeline invokes specialized scene prompts (e.g., slide-content, quiz-content, simulation-content) located in packages/@openmaic/generation/templates/.

For example, the template at packages/@openmaic/generation/templates/slide-content/user.md drives the expansion of outline topics into concrete slide decks, including markdown content, whiteboard drawings, and voice-over narration scripts. This stage produces the interactive elements students actually see, from multiple-choice quizzes to hands-on PBL simulations.

Implementation: Using the OpenMAIC SDK

You can trigger both stages programmatically via the TypeScript SDK or CLI. The generateLesson method in packages/@openmaic/sdk/src/client.ts orchestrates the full two-stage pipeline asynchronously.

// 1️⃣ Load the SDK
import { OpenMAIC } from '@openmaic/sdk';

// 2️⃣ Create a client
const client = new OpenMAIC({
  baseURL: 'http://localhost:3000', // self-hosted server
  apiKey: 'sk-YourAccessToken',      // Store in .env.local
});

// 3️⃣ Submit a generation job (runs both stages)
const job = await client.generateLesson({
  files: ['./materials/physics.pdf'],
  // Optional: force only outline or only scenes
  // stage: 'outline' | 'scenes'
});

// 4️⃣ Poll until completion
while (!job.done) {
  await new Promise(r => setTimeout(r, 2000));
  await job.refresh();
}

// 5️⃣ Access results
console.log('Outline:', job.result.outline);
console.log('Scenes:', job.result.scenes);

For command-line usage, the @openmaic/sdk package provides a CLI wrapper that handles authentication, file upload, and job polling automatically:


# Using the CLI

npx openmaic generate \
  --files ./materials/biology.docx \
  --output lesson.json

Both interfaces abstract the underlying asynchronous job mechanics, returning finalized lesson structures containing both the pedagogical outline and rendered scene assets.

Architecture Benefits of the Two-Stage Design

Separating outline planning from scene generation delivers specific engineering advantages:

  • Modular LLM Integration – Developers can replace the planner model or scene generators independently by modifying planner-system.md or scene templates without cross-stage dependencies.

  • Custom Extractor Support – The @openmaic/storage package accepts plugins for new file formats, allowing the pipeline to ingest proprietary content types without altering generation logic.

  • Granular Caching – Because outlines and scenes are distinct artifacts, the system can cache generated outlines and re-render only specific scenes when UI templates update.

  • Async Scalability – The job-based execution model supports long-running generation tasks (video rendering, complex simulations) without blocking client requests.

Summary

  • The two-stage generation pipeline in OpenMAIC separates pedagogical planning from content production through distinct Outline and Scene stages.
  • Stage 1 uses the planner prompt at packages/@openmaic/generation/prompts-pbl/planner-system.md to generate hierarchical lesson structures from extracted text.
  • Stage 2 expands each outline node into interactive scenes using templates like packages/@openmaic/generation/templates/slide-content/user.md.
  • The generateLesson method in packages/@openmaic/sdk/src/client.ts orchestrates both stages as an async job, while @openmaic/storage handles file extraction and asset persistence.
  • This architecture enables independent customization of planners, scene types, and extractors while maintaining clean separation of concerns.

Frequently Asked Questions

What file formats does the OpenMAIC two-stage generation pipeline support?

The pipeline accepts PDFs, Word documents (DOCX), PowerPoint presentations (PPTX), images, audio, and video files. The @openmaic/storage package converts these into structured text via specialized extractors before feeding them into the outline generation stage.

How does the Outline stage differ from the Scene stage?

The Outline stage performs high-level pedagogical planning using the planner prompt in packages/@openmaic/generation/prompts-pbl/planner-system.md to create chapter and section hierarchies. The Scene stage handles low-level UI material creation, transforming each outline node into concrete interactive elements like slides or quizzes using scene-specific templates.

Can I customize the LLM prompts used in the generation pipeline?

Yes. Developers can modify the system prompts located in packages/@openmaic/generation/prompts-pbl/ for the outline stage or templates in packages/@openmaic/generation/templates/ for scene generation. This allows fine-tuning of teaching style, output format, and interaction types without changing the underlying SDK code.

Is the two-stage pipeline synchronous or asynchronous?

The pipeline runs asynchronously. When you invoke client.generateLesson(), the SDK returns a job object that you poll until completion. This design accommodates long-running operations like video generation and complex simulation rendering without blocking the client application.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →