GMT+8 SG --:-- 0000 X 0000 Y /
← 全部文章← All writing

Product

Generation owns texture, code owns fact

Our short-video line ships a batch of finished pieces every day. Two kinds of thing live inside them: the kind that has to look good, and the kind that has to be right.

Looking good is the scene, the light, the materials, the movement of the camera. Being right is the aircraft model, the tail number, the date, the route, the price, the coordinates, the numbers on a chart.

Handing both to the same system to generate was the most expensive mistake I made on this line.

The cheap error and the expensive one

Generative errors come in two shapes.

One is obviously fake: the aircraft flying backwards, landing gear growing out of a wing, a cloud layer swapping wholesale between two frames. That kind is cheap — it doesn't survive three seconds of QA, and anyone who does see it just thinks the piece is rough. They aren't misled.

The other kind is this: the tail number on the aircraft in shot, which the model rendered as a string that looks entirely plausible. Right typeface, right placement, right perspective, right weathering. Its only problem is that the aircraft doesn't exist.

The second kind is the expensive one. QA doesn't catch it, because it has none of the features of looking wrong. It gets published as information, screenshotted, quoted. Something that reads as authoritative and is false costs an order of magnitude more than something that is visibly rough.

And a generative model, with nothing structurally preventing it, will produce the second kind very willingly. That isn't a defect; it's how it works. It is fitting a distribution, and "plausible" is exactly the centre of the distribution.

So we drew the line inside the system

Generation owns texture. Code owns fact.

The model generates scenes, materials and controlled motion. Titles, dates, aircraft models, routes, prices, arrows, leader lines and captions are all composited by code onto a locked foreground layer.

Readable text is never handed to the video model.

The implementation is unglamorous: the foreground layer is rendered programmatically, its data comes from the database, and compositing happens after generation. The frame the model hands back has no text in it at all — it has no opportunity to get it wrong, because it was never asked.

Written down, this sounds like an aesthetic preference. It isn't. It removes the part that must be exactly right from the generative model's solution space entirely — the error isn't caught, it's made structurally impossible.

This is the same move as not letting a model write SQL

I've written elsewhere about our data agent: it doesn't emit SQL, only a set of typed parameters, and a function with no model in it compiles those into a query. The model never sees a table name, so it can't invent a column that doesn't exist.

Completely different media, one judgement:

The part that must be exact How it's removed
Data queries Table names, column names, join keys Model fills parameters; a function builds the SQL
Video production Model, date, price, tail number Model generates imagery; code composites the text

Neither is "make the model more careful", and neither is "add a check to catch it". Both are redrawing who is allowed to touch what.

Checks are a backstop; boundaries are the fix. An error held back only by a check will still be produced — you're just hoping to catch it every time. An error excluded by a boundary doesn't happen.

The boundary: it holds only where the two can be separated

This rule has a precondition: that texture and fact are separable in your output.

In video they separate naturally — imagery is imagery, text is an overlay, and they are physically on different layers. In data queries they separate too: semantics are semantics, SQL is SQL.

Some things don't separate. The shape of a chart is the fact — you can't have a model generate "the texture of a good-looking bar chart" and then have code fill in the heights, because the heights are the entire content. Narration doesn't separate either: the fluency of the telling and the accuracy of the claim live in the same string of words.

Where they separate, use a boundary; where they don't, you're left with verification. The costs are very far apart, which is why it's worth asking whether they can be separated first — and most of the time the answer is yes, it's just that nobody thought to ask.

A side effect

The boundary brought one benefit I hadn't anticipated: it makes "where did this go wrong" locatable.

Text is wrong — that's the data or the compositing code, go look at the database. Imagery is wrong — that's generation or the source footage, go look at the prompt and the rushes. The two paths don't cross.

Before this rule, a bad piece meant reviewing the whole chain, because any stage could have produced any kind of error. A system with clear lines of responsibility is also easier to repair when something breaks.