AI EngineeringProduct Engineering

The Model Is Usually the Easy Part

What changed in how I think about AI product engineering once model output had to become real application behavior.

7 min read

When I first started building AI features into real products, I assumed the model would be the difficult part.

Which model should I use?

How should I prompt it?

How do I get more consistent answers?

Those questions mattered, but they stopped being the questions that consumed most of my time.

Getting a model to produce an impressive answer turned out to be relatively easy.

Building software that could safely do something with that answer was much harder.

That distinction changed the way I think about AI product engineering.

An impressive response is not a product

A demo has a very forgiving definition of success.

You give the model some context, it produces something convincing, and everyone in the room sees the potential.

That moment is useful. It proves that something may be possible.

But a user does not interact with potential.

They interact with a product.

And a product has to deal with everything that happens after the impressive response.

What if the output is valid but inappropriate for the user's situation?

What if it contradicts something the application already knows?

What if the model understood the request correctly but made a decision the product should never allow it to make?

What if nothing technically failed, but the result was still wrong?

Traditional software trained me to think heavily about failure paths.

A request fails.

A database operation throws an error.

A dependency times out.

A queue backs up.

Something breaks, and the system usually gives you some evidence that it broke.

AI introduced another category of failure that I initially found much more uncomfortable:

everything works, but the outcome is wrong.

The request returns successfully.

The response has the expected structure.

There is no exception.

The application stays online.

And yet, from the user's perspective, the software made a bad decision.

That is a very different engineering problem.

Model output is not application state

One mental model became particularly useful for me:

I don't treat model output as application state.

I treat it much closer to external input.

That does not mean I distrust the model or avoid letting it do meaningful work.

It means I don't confuse a plausible response with a valid product decision.

Structured outputs help a lot here.

If I ask for a particular shape and the model returns exactly that shape, I've solved an important problem.

My application can parse the response.

The fields exist.

The types are correct.

The contract between the model and the software is clearer.

But structure only tells me that the answer fits the expected shape.

It does not tell me that the answer makes sense.

A perfectly valid identifier can still refer to the wrong thing.

A perfectly valid number can still be inappropriate.

A perfectly valid action can still conflict with the current state of the product.

A perfectly formatted answer can still be a bad answer.

So there is a boundary between:

"Can my software understand this output?"

and:

"Should my software trust this output?"

The second question is where a lot of the real engineering starts.

The model should not own every decision

There is a temptation when building AI products to keep giving the model more responsibility.

The reasoning is understandable.

The model is flexible.

Adding another instruction can feel faster than building another piece of software.

A single intelligent component can replace a surprising amount of conditional logic.

And sometimes that is exactly the right decision.

But I started becoming much more deliberate about where probabilistic behavior should end.

There are decisions where flexibility is valuable.

There are other decisions where the application should simply know the answer.

Some product rules should not be suggestions inside a prompt.

Some state transitions should not depend on whether the model interprets an instruction the same way twice.

Some constraints exist because the product has already made a promise to the user.

The useful question stopped being:

"Can the model do this?"

It became:

"Should the model be responsible for this?"

Those are very different questions.

A capable model makes the first answer "yes" surprisingly often.

Good product engineering still has to answer the second.

Context became a product decision

Another thing I underestimated was context.

At first, context feels like a technical problem.

What information can fit?

What should go into the prompt?

What should be retrieved?

But once AI is part of a real product, context becomes a product decision too.

A model can only make a useful decision based on what the system allows it to know.

Too little context and the experience feels generic.

Too much context and the system becomes noisy, expensive, difficult to reason about, or unnecessarily invasive.

The interesting question is not how much information you can give the model.

It is which information actually matters for the decision being made.

That forced me to think about product state differently.

The application knows things.

The user has told us things.

Some information is current.

Some information is stale.

Some information should influence a decision.

Some information absolutely should not.

The model sits somewhere inside that system. It is not the system itself.

That sounds obvious when written down.

It was less obvious while building.

Observability changes when "wrong" is subjective

The same shift happened with observability.

For conventional systems, I was used to asking questions like:

Did the request succeed?

How long did it take?

Did a dependency fail?

Did an exception occur?

What happened to CPU, memory, database connections or queue depth?

Those questions still matter.

But they are no longer enough.

For an AI-powered feature, a successful request can produce the failure you actually care about.

So you start needing answers to different questions.

What did the system know at the time?

What kind of action was attempted?

Where did the result diverge from what the product expected?

Was this an isolated case or a recurring pattern?

Is the model behaving differently, or did the application give it the wrong context?

This is one reason I think AI observability is less about staring at another dashboard and more about making model behavior understandable inside the rest of the product.

If something surprising reaches a user, "the API returned 200" is not a particularly useful explanation.

The product is the system around the model

The more AI products I work on, the less interested I become in treating the model as the center of the architecture.

It is an extremely capable component.

Often the most flexible component.

Sometimes the component that makes the product possible in the first place.

But still a component.

The product is everything around it:

the state the application maintains,

the context the model receives,

the actions it can take,

the boundaries it cannot cross,

the way outputs are interpreted,

the way unexpected behavior is detected,

and the experience the user ultimately sees.

That is why I think the gap between an AI demo and an AI product is much larger than it first appears.

The demo proves that the model can do something impressive.

Production asks whether the entire system can do it repeatedly, under real conditions, for real users, without requiring someone to stand behind it and explain what went wrong.

That is a much higher bar.

And increasingly, I think that is where the interesting engineering work is.

Written by Miraç Akdağ · Technical Founder & Product Engineer