Ask a general image model for a free-body diagram and you will get an image with the aesthetic of a free-body diagram: arrows of plausible length, labels that are nearly words, an angle that is nearly the one you asked for. It is convincing at a glance and it is not checkable, because nothing in the pipeline knows what the arrows mean.
We generate visuals from typed parameters instead. The tutor chooses a template and fills in values; the client draws it. The picture is therefore correct by construction in the same way a plotted function is, and it can be manipulated afterwards because the parameters still exist.
Correct by construction, and therefore interactive
Once a diagram is data rather than pixels, interaction is nearly free. A learner can drag a point on a graph, re-run a reaction, change a resistance, or reveal one anatomical label at a time. None of that is possible with a rendered image, and all of it is where the teaching actually happens — the moment a learner changes something and the picture disagrees with what they expected.
It also means the same visual can be produced by a typed question or a spoken one, because both paths end at the same structured action rather than at two different renderers.
The cost of the approach is coverage, and we state it
A template has to exist before it can be drawn. That is the honest trade: an image model will attempt anything and be unreliable; a template library will refuse anything outside it and be exact within it. We think exact-within-a-known-boundary is the right side of that trade for assessment-adjacent material, and the boundary is a real limitation rather than a rhetorical one.
Where no template fits, the tutor falls back through a declared order — interactive first, then verified static, then animated, then a flowchart — rather than silently producing something decorative.
One canvas, whichever way the question was asked
A subtler failure we had to fix: a diagram that appeared in one place when a learner typed and a different place when they spoke. Two behaviours for one product reads as a bug even when both work. Pictures now land in one region with a reference from the answer that asked for them.