Back to projects

QuestionAIr

2025

An AI questionnaire generator: upload a document and it produces questions from the content. I built it to turn course material into self-testing material without writing the questions myself, and to learn how to get reliable structured output out of a language model.

  • Python
  • LLMs
  • Document parsing
  • Parses uploaded documents and generates questions grounded in the source text.
  • Constrained decoding into a fixed schema, so downstream code never parses free-form prose.

The problem


Testing yourself on material beats re-reading it, but writing the questions is the part nobody does — by the time you have written twenty good questions about a lecture you have effectively already revised it, and the questions you write are biased toward what you already remember.

I wanted the loop to start from the material itself: hand it a set of lecture slides or a chapter and get back questions that cover what is actually on the page, including the parts I would have skipped.

How it works


  • Upload step accepts a document and extracts its text, keeping enough structure to know where one section ends and the next begins.
  • The text is chunked so each request to the model covers a coherent piece of material rather than an arbitrary slice.
  • Each chunk is sent with a prompt that asks for questions grounded strictly in the passage, returned in a fixed schema.
  • The response is validated against that schema before anything downstream touches it — a malformed generation is retried, not parsed by hand.

What I learned


Most of the work was not prompting, it was the contract around the prompt. Asking a model for prose and then regexing it apart is fragile; asking for a declared schema and validating on the way out turns an unreliable component into one that either succeeds or fails loudly.

The other lesson was scope of context. Questions generated from a whole document drift toward the introduction; questions generated per section stay specific, and specificity is the whole value of the tool.