A compiler intermediate representation sits in an interesting middle ground. It is more structured than source code, but more expressive than the machine instructions it eventually becomes. The IR is useful because it preserves the parts of the program that still matter while removing details that no longer do.
Machine learning systems have a similar problem. A research idea starts with a rich description: a model, a dataset, a training recipe, a metric, and an environment. By the time that idea reaches a production service, most of those details have been compressed into an interface. The question is what gets lost in the compression.
Good boundaries do not erase complexity. They put it somewhere deliberate.
That is why I keep coming back to compiler work when thinking about ML infrastructure. A useful interface should make the common path simple while keeping the information needed for optimization, debugging, and correctness visible to the layer that owns it.
The practical lesson is small: when designing an ML component, write down what the next layer needs to know. If the answer is only a tensor shape and a callback, that may be enough. If it needs provenance, timing, constraints, or uncertainty, make those first-class too.