Uptempo’s marketing-planning product has a wizard where a user creates a marketing activity by filling in a dozen dropdowns by hand. The mandate I got was the fuzzy kind every team is getting right now: add AI to it. It became the company’s first AI-enabled feature - as you fill the form, the system reads the surrounding context and proposes a value for each field.

A model that guesses at those values gets a fair number of them wrong, and in an enterprise tool that isn’t a cheap mistake. A confident wrong answer costs the user the time to notice it and undo it, plus a little of their trust in whatever the system suggests next. So what I actually set out to build was narrower than “add AI”: a layer the biggest customers could switch on without it spending that trust, proven as a working prototype rather than a spec I’d hand to someone else.

Discovery

Nearly all of that came down to a single case - what the feature does when the model is wrong - and two decisions fell out of working it through. One was about when the feature should speak at all. It had to defer to the model’s confidence rather than to the bare fact that it had produced a suggestion, since an answer offered confidently and wrong is worse than no answer. The other was easy to miss in the excitement: the product’s analytics were click-level and couldn’t say whether a suggestion had actually helped, so measuring that needed to be part of the feature from the start, not something added a year later when someone finally asks why it was never measurable.

Prototype

I built the working version myself with an AI-assisted workflow, then walked it through with the design and engineering teams. The confidence decision showed up right in the interface: high and medium confidence surfaced a value with a short note on why, and low confidence surfaced nothing at all, so an uncertain field just looked like an ordinary one. Underneath, the AI layer sat on top of the existing wizard instead of inside it, which meant a slow or failing suggestion service changed nothing a user could see - the form behaved exactly as it always had, no error, because the creation path never ran through the model. The telemetry went in with that same first commit, so acceptance by confidence tier was there from day one rather than arriving as an afterthought. All of it rolled out behind a flag, a little at a time.

Build

Raising a prototype as a pull request isn’t a normal move for a PM, so I set the terms with engineering before I opened it: the outcome was theirs, anywhere from shipping it as written to deleting all of it and starting over. I’d left the code short of production quality on purpose. I wanted the team to own something they understood and could maintain, not to inherit a polished-looking draft that would feel awkward to rewrite.

They rebuilt most of it in their own architecture, and the parts I’d designed to survive, the API contract and the accept/reject telemetry model, came through nearly unchanged. That was what the prototype had been for: to settle the feature and its defensive patterns, then get out of the way so the people who would keep it running actually owned it.

What shipped

It launched with some of the product’s largest customers on it, and the defensive design held up in front of them - a confident wrong answer never reached a user, and a bad day from the model never took the wizard down with it. The measurement is the part I’d point to first, though. Because it shipped in that first commit, we could watch how the suggestions were landing, tier by tier, from the first week - not the usual version of this, where a feature goes out, nobody can quite say whether it’s working, and the telemetry turns up a year later once the question gets urgent.

Go deeper

If you want the design reasoning in full - the confidence tiers, the fallback, the telemetry model, and why the handoff was set up the way it was - I wrote it up on its own: Defensive design for a product’s first AI feature.