Most of your AI feature should not be AI
The fastest way to make an "AI feature" worse is to make all of it AI. The good ones are mostly boring deterministic code with a small, expensive model doing only the part that genuinely needs judgment.
I learned this building a tool that turns design files into specs. The naive version was "feed the whole thing to a model, ask for a spec." It was slow, it cost real money per run, and it was non-deterministic: ask twice, get two different documents, each missing different things.
The version that worked split the job in two.
The algorithm is the floor
A surprising amount of what looks like "understanding" is just structured data you have not bothered to read. A design file is not a picture, it is a tree: named layers, components, positions, text, links. From that tree alone, with plain code and zero model calls, I could pull thousands of fields, their types, their defaults, the navigation between screens. Free, instant, identical every run.
That is your floor. Before reaching for a model, ask what a determined script could extract with no intelligence at all. It is almost always more than you think, and every field it nails is a field you are not paying a model to guess at, and not hoping it guesses the same way twice.
The LLM is for what the structure cannot hold
Then there is the part the structure genuinely does not contain. The validation rule a designer wrote as a tooltip. The "required" badge that is just a red dot a human knows to read. The business logic living in a sentence of prose next to a field. No amount of tree-walking gets you that, because it was never stored as data. It was stored as meaning, and meaning is what a model is for.
So the model gets a narrow job: read the unstructured bits and map them onto the fields the algorithm already laid out. It is not doing the whole task. It is filling the specific holes the deterministic pass could not reach. Small input, small output, small bill.
And code keeps the books
Here is the part people skip. Even on its narrow job, the model is inconsistent. One run it catches a max-length rule, the next run it forgets to emit it. If your output needs to be complete, you cannot trust the model to be complete.
So the model classifies, and code guarantees. After the model runs, deterministic code walks every field and, for anything still missing, emits an explicit "unknown, a human should check this" marker. The model is allowed to be flaky because the code catches what it drops and turns it into a visible gap instead of a silent one. The trust boundary is explicit, stated versus inferred versus flagged, and which is which is decided in code, not in the prompt.
Why this shape keeps winning
- Cheaper. Most of the work is free. You pay the model for a thin slice, not the whole pie.
- More reliable. The deterministic part is identical every run. Only the genuinely ambiguous slice varies, and the code fences it off.
- Honest. The output can say "here is what I know for sure, here is what I inferred, here is what I could not figure out," because each came from a different mechanism. A pure-LLM version cannot tell you which of its answers it was sure about.
- Degrades well. If the model is down or wrong, you still have the floor. The feature gets dumber, not broken.
The pitch I lead with now, whenever someone wants to "add AI" to something: show them the deterministic floor first. It is free, it is instant, and it is usually most of the value. Then the model is not the product. It is the part that fills the last, hardest slice, the part that was never going to be code. That is where the model earns its money, and nowhere else.