Frontend architecture for AI-assisted screens that hold up
Frontend architecture for AI-assisted screens works better when drafts, user confirmation, and correction loops each get their own state and rules.

Where these screens break
Teams often build the first AI screen like a normal form with a smarter text box. That's usually the first mistake.
A model can return something useful without returning something ready to send, publish, or save as final work. People will accept an imperfect draft. They won't accept a screen that quietly treats a draft as approved content.
Problems start when the UI hides what changed. If a user asks for a rewrite and the old version disappears, trust goes with it. People want to compare the new text with the last approved version, see the edited lines, and decide whether the revision actually helped.
Another common failure is storing everything in one shared value: the original input, the current AI output, and the approved result. Then one retry, one extra prompt, or one careless click replaces the only version that mattered.
Waiting states also trip people up. "Generating," "saving," and "applying" are different moments, but many screens blur them together. Users click twice, start editing while stale content is still on screen, or assume the app froze when it's really waiting for the model.
The usual break points are simple:
- A new draft replaces approved content before the user confirms it
- The screen shows final text but hides the changes
- A retry creates another version with no label or history
- Different loading states all look the same
- The UI lets people edit content that the app overwrites a second later
In AI-assisted screens, the model isn't the only problem. State design is the fault line. If the screen can't keep draft, approved, and in-progress work separate, one decent answer followed by one bad revision is enough to make the whole feature feel unsafe.
The states you need from day one
Many AI screens fail because they treat output like one blob of text. Real work doesn't happen that way. People write a prompt, review a draft, ask for changes, wait for another version, and then approve it. The UI should make that path obvious.
Start with five states, and show each one next to the content itself, not buried in a side panel.
- Draft: the AI produced something, but nobody trusts it yet
- Waiting: the system is working, or it's waiting on a person
- Approved: someone accepted this version for real use
- Correcting: a person asked for changes and the draft is being revised
- Failed: the run broke, timed out, or returned junk
The label should answer two questions at once: "What is this?" and "What happens next?" A small note like "Draft - review needed" works better than a vague badge that says "Pending."
Buttons should change with the state. A draft can show "Approve," "Request changes," and "Edit manually." Waiting should limit actions so people don't trigger duplicate runs. Approved content should lock risky edits unless someone reopens it on purpose. Failed runs should offer a clear retry path and keep the last input so nobody has to start from scratch.
The limits matter too. In correcting, let users send a short note, not reset the whole task. In approved, keep the content read-only by default. In waiting, disable destructive actions unless there's a clear cancel button.
A small label near the text, the right buttons, and a clear next owner do more for trust than a clever prompt.
Keep source, draft, and approved content separate
If source text, AI output, and final copy all live in one field, the screen gets messy fast. People stop trusting it because they can't tell what they wrote, what the model changed, and what the team accepted.
Treat them as three separate records, not three views of the same text.
- Source is the user's original input. Leave it untouched.
- Draft is the AI suggestion. It can change many times.
- Approved is the version a person accepted. Save it as its own version.
Source matters more than teams expect. When someone asks, "Why did the model say this?", you need the exact material that started the flow. If you overwrite it, later fixes become guesswork.
Drafts need their own layer because retries are normal. People ask for a shorter version, a warmer tone, or a cleaner structure. None of that should alter the source, and none of it should touch approved content. A retry should replace only the current draft, or the selected part of that draft.
Approved text should feel stable. Once a person accepts it, freeze it until they choose to edit it. If the model runs again, write the new result into a fresh draft. Don't let one accidental retry replace something that already passed review.
Fast comparison matters too. Users should be able to see old and new text in seconds, not hunt through tabs and modal windows. A simple side-by-side view or a compact diff is often enough. When people can compare source, draft, and approved content quickly, they make better calls and approve faster.
Without this separation, small UI mistakes turn into audit issues, trust issues, and support issues. With it, the screen behaves more like a careful editor and less like a slot machine.
Confirmation needs its own step
If an AI draft can send a message, change a record, publish text, or replace approved content, the screen needs a pause before that action happens. Many teams skip this and hide approval inside a generic "Save" or "Continue" button. Then users approve changes without knowing what will go live.
Keep the decision small. Give people three choices, and make each one mean exactly one thing:
- Approve: accept this draft and apply it
- Edit: keep the draft, but open it for changes first
- Reject: don't use this draft
The label alone isn't enough. The screen should also say what approval will do. "Approving will send this reply to the customer" or "Approving will replace the current product description" is usually enough. One short sentence cuts hesitation and prevents careless clicks.
Review and action should stay separate. Users need to see the draft, the affected item, and the result of approval in one place. If they have to guess whether approval saves a draft, publishes it, or triggers a workflow, the product is asking too much.
A support team is a good example. An agent asks AI to rewrite a reply to an upset customer. The draft looks fine, but the tone is too casual. The agent chooses Edit, adjusts two lines, and then approves it. If the draft feels off from the start, they reject it and leave a short note such as "too informal" or "missed refund policy." That note helps the next draft and gives the team something concrete to review later.
Rejecting needs some structure, but not much. A one-line note field is enough in most cases. You're not collecting essays. You're collecting a useful signal.
This part of the interface often decides whether people trust the product. A clean confirmation step keeps approval deliberate, makes mistakes easier to trace, and stops draft content from slipping into places where only approved content should go.
How the correction loop should work
A good correction loop stays narrow. If one sentence is wrong, the screen shouldn't regenerate the whole answer and risk breaking parts the user already likes.
Start with precise selection. Let the user mark the exact sentence, paragraph, table cell, or form field that needs work. A broad "fix this" button sounds simple, but it often produces messy rewrites. When the user points to one specific part, the system has a clear target and the result is usually better.
Then send only that selected part back for revision, along with the user's note. The UI can still show surrounding context so the person knows where the change fits, but the model should revise only the chosen fragment. That reduces drift and saves time, because the user doesn't need to re-check content that never needed changes.
When the new draft returns, show it beside the previous version. A side-by-side view works better than silently swapping text in place. People can compare tone, facts, and wording in a few seconds. If the difference is small, they can approve it quickly. If the new draft goes off track, they can reject it without losing the earlier version.
Approved parts should stay locked unless the user unlocks them on purpose. Once someone approves a title, summary, or pricing field, the system should treat it as stable text, not as material for the next AI pass. That boundary matters.
After each revision, the user usually needs only three actions:
- Accept the new draft and replace only the selected part
- Retry and ask for another version of that same part
- Stop and keep the current content as it is
That last option matters. Sometimes the first draft is good enough, or the user decides to edit manually instead. The screen should make stopping feel normal, not like a failure.
When this loop works well, people stay in control. They fix one part, compare versions, protect approved text, and move on without wondering what else changed.
A simple example: rewriting a support reply
A support agent gets a message from a customer asking why a refund hasn't arrived yet. The agent clicks "Draft reply," and the AI writes a response. That response should appear in a draft box beside the conversation, not inside the live thread. The customer still sees nothing, and the agent can review the text without pressure.
The first draft might be mostly fine. It opens with a polite greeting, explains that the team is checking the payment, and adds a promise: "Your refund will arrive within 24 hours." That's the problem. The agent knows the finance team usually needs up to 3 business days, so sending the draft as-is would create a new complaint.
A solid review flow lets the agent keep the parts that work and correct only the part that doesn't. The greeting can stay. The short apology can stay. The agent marks the promise sentence and types a note like "Change timing to 3 business days after finance review."
The system should revise only that marked sentence. It shouldn't rewrite the whole message and risk changing approved text. This is where many AI screens fail. Full regeneration often shifts the tone, removes useful details, or adds a fresh mistake. If the product keeps source, draft, and approved content separate, the change stays small and easy to verify.
The revised sentence comes back as: "Once our finance team reviews the case, refunds usually appear within 3 business days." The agent reads the full reply one more time and approves it. Only then does the message move to the send step.
That last step matters. Approval isn't the same as sending. The agent may still want to add the customer's name, check the ticket history, or confirm the refund status. When the screen treats draft, correction, approval, and send as separate states, people make fewer avoidable mistakes.
Mistakes teams make early
Teams usually break these screens by treating AI output like normal app data. It isn't. A draft, a user edit, and an approved result each need their own place in the UI and in storage.
The first bad move is mixing draft text with final text. A user sees a reply, edits two lines, clicks approve, and thinks the job is done. Then a background retry finishes and swaps in a newer draft. Once the line between approved and draft content gets blurry, trust falls apart.
A similar mistake happens when the app lets retries overwrite content that a person already accepted. Once a user approves something, the system should treat that version as stable. New generations can exist, but they should appear as alternatives, not replacements.
Another common problem is lazy loading feedback. Teams use one spinner for three different jobs: generating text, checking policy, and saving changes. That looks neat on a whiteboard. In a real product, it feels broken. Users can't tell what is happening, what finished, or what needs attention.
Clear status labels work better than one generic loading state:
- generating a new draft
- waiting for user confirmation
- saving approved content
- retry failed, previous version kept
Confirmation often gets mishandled too. The UI asks, "Approve this?" but gives no reason. People hesitate when they don't know what changed or why the app wants a person to step in. A short note helps. "The draft changed the refund amount" is much better than a vague warning.
The most frustrating mistake is forcing users to start over after one bad answer. If the model gets a detail wrong, users should correct that detail and continue. They shouldn't lose their edits, their prior approval, or the original source.
This is where screen architecture either feels calm or chaotic. Early shortcuts look small. Users feel them immediately.
Quick checks before you ship
A screen that mixes AI drafts with human edits can look fine in a demo and still fail during real work. The final pass before release should focus on clarity and recovery. If someone hesitates for even a moment, they can approve the wrong text or wipe out a good edit.
Run these checks on the real product, not in a design file.
- Ask someone to open the page and point to the current state right away. They should know whether they're looking at source text, a draft, or approved content.
- Make a bad revision on purpose. They should undo it in one action, or restore the last approved version without guessing which button is safe.
- Edit one small part of the content, such as a paragraph or a single field. The rest should stay untouched.
- Try the risky path. Delete, publish, send, or replace actions should stay blocked until a person confirms the draft.
- Open the recent history. The screen should keep a short record of changes so people can compare revisions and roll back when needed.
If one of these checks fails, fix the UI before you tune prompts. Teams often blame the model when the real problem is state design. A good screen makes the model feel more reliable because it shows what is tentative and what is final.
Small details matter here. A visible status badge near the content usually works better than a label hidden in a side panel. An "undo" action should sit close to the last change, not inside a deep history menu. When people edit one section, the system should protect the rest by default.
Version history doesn't need to be fancy. Three to five recent revisions is enough for most screens. Show the time, the action, and whether the content was draft or approved. That alone saves a lot of stress when someone asks, "Who changed this?"
One harsh test helps: give the screen to a teammate who didn't build it. If they can spot the state in two seconds, recover from a bad revision, and make a small edit without fear, the screen is close to ready.
What to do next
Start with one screen that already creates frequent back-and-forth between a person and the model. A support reply editor, sales email draft, or internal note generator works better than a broad redesign. Small scope makes the state model easier to see, and problems show up fast.
Before you code the layout, draw the states on paper or in a simple mock. Most teams jump to components too early and patch missing behavior later. In AI-assisted screens, the state map matters more than the first visual design.
Keep the sketch plain. You only need answers to a few questions:
- What does the user see before generation starts?
- Where does draft content live?
- How does a user confirm or reject it?
- What happens after an edit or retry?
- When does content become approved?
Then test the flow with messy input, not polished prompts. Ask someone to make real edits, reject weak drafts, and retry with short instructions like "make it warmer" or "cut this in half." That's where the correction loop either feels clear or falls apart.
A simple test tells you a lot. Give five people the same task, such as rewriting a support reply. Watch where they hesitate, where they overwrite approved text by mistake, and where they ask, "Did this save yet?" Those moments point to missing states, weak labels, or the wrong order of actions.
Track a few numbers from the start. You don't need a huge analytics setup. Three metrics usually tell the truth:
- approval rate
- retry count before approval
- manual fixes after approval
If approval stays low, the draft step may be too noisy. If retries climb, your prompt or controls may be too vague. If manual fixes stay high after approval, users probably don't trust the boundary between draft and approved content.
If you want an outside review, Oleg at oleg.is works with teams on AI product flows and state design. A fresh set of eyes often finds the real problem quickly: not model quality, but a screen that treats draft, confirmation, and correction as the same thing.
Frequently Asked Questions
What states should my AI screen show?
Start with five states: draft, waiting, approved, correcting, and failed. Put the label next to the text so users know what they are reading and what they can do next.
Why should I keep source, draft, and approved content separate?
Keep source, draft, and approved content in separate records. That lets users see what they wrote, what the model suggested, and what a person accepted without one retry wiping out the version that matters.
Should approval and sending happen in one click?
No. Let people approve a draft first, then send or publish it in a separate step. That pause catches bad facts, wrong tone, and accidental changes before they go live.
What should the approval step say?
Use plain actions like Approve, Edit, and Reject, then add one short sentence that says what approval will do. Users click with more confidence when the screen says whether it will send a reply, replace text, or update a record.
How should retries work?
A retry should touch only the current draft or the selected part of it. Leave source and approved content alone, and keep the last input so users do not need to start over after a bad run.
What is the best way to handle corrections?
Let the user mark the exact sentence, paragraph, or field that needs work and revise only that part. Narrow corrections reduce drift and make review much faster.
Which loading states do users need to see?
Show generating, waiting for approval, saving, and failed as separate states. When each state has its own label, users stop double clicking and stop guessing whether the app froze.
Should users edit content while the model is still running?
Usually no. Lock risky edits while the app generates or saves, or give a clear cancel action first. That stops the screen from overwriting work a moment later.
Do I need version history before launch?
Yes. Keep a short history with the time, the action, and whether the version was draft or approved. Three to five recent revisions usually give enough context for review and rollback.
What should I test before shipping?
Ask someone who did not build the screen to find the current state, recover from a bad revision, and make a small edit without fear. If they hesitate or lose track of what is final, fix the UI before you tune prompts.