Embedding an Agent in an Existing App

7 min read

H17
Playbook · Agent UX & Human Interaction

Embedding an agent in an existing app.

The chat panel bolted to the right edge of your product is the cheapest thing you can ship and the reason most in-app agents get used twice and abandoned — it knows nothing about the screen the user is looking at, so every request starts with the user re-describing their own application to it. What decides whether an embedded agent earns a place in the workflow is read access to the current view and write access through the same code path the UI already uses; and the one decision you cannot retrofit is where the agent's state lives.

STEP 1

Pick the surface from the task, not from the sidebar template.

There are three shapes an in-app agent can take, and they solve different problems. Shipping the first one and calling it done is the standard mistake.

  • The panel. A persistent conversation alongside the app. Right for open-ended work with no obvious anchor — "why did revenue drop in EMEA" — and wrong for anything the user is already pointing at. Cheapest to build, hardest to make indispensable.
  • Inline, anchored to an object. The agent invoked on a row, a document, a selection, a failing test. The anchor supplies most of the context for free and the result lands where the user is already looking. This is where the value usually is, and it needs no chat history at all.
  • Ambient. No invocation — the agent watches state and surfaces a suggestion when a condition holds. Highest value per interaction and highest annoyance risk; ration it against the notification budget described in async & away.

Count how many of your top ten user tasks have a natural anchor — a selected row, an open record, a highlighted range. If most of them do, the panel is the wrong first surface and you will learn that six months late from an engagement chart.

STEP 2

Give the agent the view, as structured context.

An agent that cannot see what the user can see forces every conversation to open with a paragraph of orientation, and users stop paying that toll quickly. The fix is to pass the current view as part of the request — but as data, not as pixels.

  • Send identifiers and state, not a screenshot. Route, entity IDs, current filters, sort order, selection, and the visible time range. A screenshot costs vision tokens, arrives without IDs the agent can act on, and turns a lookup into an OCR problem.
  • Resolve on the server. The client sends invoice_id; the server fetches the invoice under the user's own permissions and puts it in context. Never let the client hand over records it merely happens to have in memory — that is how an agent ends up reading data the user's session was not entitled to fetch again.
  • Budget it. View context is re-sent on every turn and grows with the page. Cap it, prefer references over payloads, and keep the stable part first so it caches — the arithmetic in agent cost control.
  • Make staleness explicit. The user changes a filter mid-conversation. Either re-send the view each turn and let the agent see it move, or snapshot it once and say so. Silently doing the first while the transcript implies the second produces answers about a screen that no longer exists.
STEP 3

Write through the code path the UI already uses.

The tempting shortcut is to give the agent a fast lane — a thin internal endpoint that skips the validation, the permission check and the audit write that the human path performs. It will work in the demo and it will produce your first incident.

  • One enforcement point. If the UI cannot archive a closed account, the agent's tool must not be able to either, and the reason must be the same check, not a second copy of it. Two copies diverge, and the agent's copy is the one nobody remembers to update.
  • Same audit record, different actor. Every write records the human principal and the fact that an agent performed it. An action log that cannot distinguish the two makes attribution impossible after the fact — the failure that ends pilots, per shared & multi-user agents.
  • Return a revert handle. Each mutating tool returns enough to undo itself. That is what makes it affordable to drop a confirmation dialog later; see undo & reversibility.
  • Confirm on consequence, not on novelty. Reversible writes flow; irreversible or outward-facing ones gate. The tiering is in approval & confirmation UX.
STEP 4

Decide where agent state lives — this is the one you cannot retrofit.

Conversation history, pending tool calls, plan progress and partial results have to live somewhere. There are two honest answers and the choice propagates into everything you build afterwards.

  • Client-held. State lives in the app's own store. Fast, trivially consistent with the UI, no session infrastructure. It dies on refresh, cannot be resumed on another device, and cannot support a run that outlives the tab.
  • Server-held. A durable session keyed by conversation, with the client subscribing to it. Survives refresh, resumes on mobile, and lets a long task keep running while the user closes the laptop — the property that durable state & resumability is about.

The rule that decides it: if any task can outlive the page, state must be server-held — and in practice something always can, because the first genuinely useful agent task in a business app takes longer than a user will sit still for. Migrating from client to server later means rewriting streaming, reconnection and every surface that consumes the conversation, so pay it at the start.

The second surface is the test. If a Slack notification, a mobile view or an email digest of the same run would require re-implementing the agent rather than subscribing to it, your state is in the wrong place.

STEP 5

Reconcile with a UI that is also changing.

A chat window is a page with one writer. An embedded agent is a second writer to a document the user is editing at the same time, and the collisions are real.

  • Stream into a container, not into the document. Render partial output in a review surface the user can accept, not directly into the record. Anything else means a rejected suggestion has already dirtied the data — the reason streaming is a presentation decision, not just a transport one.
  • Never overwrite a human edit. If the underlying object changed after the agent read it, stop and show the conflict. An agent that silently reverts a fix a person just made loses trust permanently, and it is the exact failure named in interruption, steering & handoff.
  • Make interruption cheap and non-destructive. A stop control that leaves the app in a valid intermediate state, with completed steps kept and the plan visible.
  • Decide what a generated surface may do. If the agent renders components rather than prose, it selects from a catalogue you own and never decides anything on its own — the discipline in generative UI patterns.
STEP 6

Instrument the thing you are actually trying to move.

Message counts and session length measure how much talking happened, which is the opposite of the goal. An embedded agent succeeds by removing steps from a workflow that already existed, so the metrics have to be anchored to that workflow.

  • Task completion inside the app — the invoice reconciled, the ticket resolved — attributed to runs that involved the agent, compared against the same task done manually.
  • Acceptance rate on proposed writes, split by tool. A tool below fifty per cent acceptance is producing review work, not saving it; fix it or remove it.
  • Edit distance after acceptance. A suggestion the user accepts and then rewrites scored as a success in your funnel and as a failure in their afternoon.
  • Re-invocation on the same object — the user asking again about the same record is the cleanest signal that the first answer missed the context you thought you were passing.

Before building the panel, ship one inline action on the single object your users touch most, wired through the existing write path, with server-held state from day one. It is a week of work, it produces a real acceptance-rate number, and it tells you whether an agent belongs in this product at all — which is the question a chat panel is very good at not answering.

Related: waiting & latency UX for what to show while it works, first run & onboarding for calibrating expectations on the first use, and agent UX patterns for the concept-level map.