Proactive & Unprompted Agents
A proactive agent lives or dies on specificity, not on judgement — at a 2% base rate a 97%-specific trigger sends you more false alarms than real ones.
Build an agent that decides for itself when to speak and the hard part is arithmetic, not prose: the share of things worth your attention is small, so the trigger's false-positive rate — not its cleverness — sets whether anyone keeps the product past week two. The lever that actually moves specificity is narrowing what the agent is allowed to consider, and the prompt you removed was quietly carrying the scope and the authorisation too.
Step 1The prompt was doing three jobs. Deleting it replaces one.
In a reactive agent, the user's message is the trigger (it says now), the scope (it says this), and the authorisation (it says on my behalf). All three arrive in one act, which is why nobody has to design them separately.
A proactive agent — Claude Duet, opened as a US research preview on 21 October 2026, is the current reference implementation, and OpenAI's and Meta's assistants are in the same category — replaces the first one with a schedule. The scope becomes "whatever the agent found while looking", and the authorisation becomes a standing grant to every connected app. Duet's shape is worth copying because it is explicit about this: it checks connected accounts every few hours, sends one short brief each morning, and messages during the day only when something needs attention; before it sends a message, makes a payment, signs a document or deletes anything, it shows the action and waits for approval, and a short list of actions — trading securities, moving money between accounts — stays blocked even if you say yes.
Notice where those approvals sit. They are on writes. The trigger, the reading, and the decision that something merited your morning are all unreviewed, and they are where a proactive agent's real behaviour lives. So the design work splits three ways: what fires a run (STEP 2–3), what that run is allowed to touch (STEP 4), and what the run remembers (STEP 5). Notifications and digests covers writing the message once you have decided to send one; this page is about everything upstream of that decision.
Step 2Do the base-rate arithmetic before you write a single prompt.
Count what the agent will look at in a day and how much of it genuinely needs a human. For a working professional with mail, calendar, a ticket queue and two chat workspaces connected, 150–250 new items a day with three to six that actually need them is an ordinary shape. Take 180 and 4. That is a base rate of 2.2%, and it is brutal:
# what a "good" trigger classifier actually delivers at a 2% base rate items_per_day = 180 need_you = 4 # base rate 2.2% recall = 0.90 # catches 9 of 10 real ones specificity = 0.97 # wrong on 3% of the rest — sounds excellent true_alarms = need_you * recall # = 3.6 false_alarms = (items_per_day - need_you) * (1 - specificity) # = 176 * 0.03 = 5.3 — more noise than signal precision = true_alarms / (true_alarms + false_alarms) # = 0.40 # to reach 80% precision at this base rate you need specificity >= 0.996, # i.e. a wrong call on fewer than 1 item in 250 — not a prompt-tuning target
Read the last line twice, because it is the whole design constraint. Going from 97% to 99.6% specificity is not something you reach by rewording an instruction, and it is not something a general-purpose model will hand you on open-ended inbox text. What does reach it is shrinking the denominator: filter deterministically first, and only ask the model about what survives. If a rule — sender is in the user's org, thread has the user on the To line, ticket is assigned to them, invoice exceeds a threshold — cuts 180 items to 25 with no loss of the real four, the same 97% specificity now produces 0.6 false alarms a day and precision above 85% with no model change at all.
This is why "the agent decides what matters" is the wrong frame to ship first. The agent decides what matters within a candidate set you chose, and the candidate set is doing most of the work. Pick the rules with the user, in their words, during onboarding — first-run and onboarding is where that conversation belongs, and it is a far better use of the first session than a tour.
Step 3Cadence is a correctness and cost decision, and polling is the fallback, not the design.
There are three ways to start an unprompted run, and they have different failure modes:
- Event subscription. The source tells you something changed. Lowest latency, lowest cost, and the candidate set is pre-narrowed by whatever the webhook filters on. Use it wherever it exists.
- Diff polling. Fetch a change cursor, compare against stored state, run only on the delta. This is what you build when the source has no webhooks, and the cost scales with the number of changes rather than the size of the account.
- Scheduled re-read. Re-examine a window of content on a clock. The most expensive and the least precise, because the same item is evaluated repeatedly and every pass is a fresh chance at a false positive.
Cadence then trades two things against each other. Looking more often raises recall on time-sensitive items and shortens the latency a user feels — and raises the false-alarm count close to linearly, because false alarms scale with how many items get evaluated while real events do not. A six-hour cadence that evaluates each item once is not four times worse than hourly at catching things; it is roughly four times better at staying quiet. Duet's published cadence is "every few hours", and its documentation gives the reason plainly: the background checks count against the same plan limits as the user's own work.
That last point is the cost model and it is unusual enough to call out. A proactive agent's spend is a function of inbound volume, not of what the user asked for. A busy week costs more than a quiet one with no change in delivered value, and a mail bomb is a denial-of-wallet vector with no prompt attached. Cap the per-day run count and the per-run token budget at the trigger, not inside the agent — cost control in the loop and forecasting agent spend both assume a bounded trigger, and scheduled and triggered agents is the operational runbook for the loop itself.
Step 4Each trigger opens a run with its own scope, budget and deadline.
This is the control that the shipping products mostly do not have, and the one that is cheap to add while the system is small. A run started by "an invoice over $5,000 arrived" needs the finance connector and nothing else, a two-minute deadline and no outbound network. A run started by "a calendar conflict appeared" needs calendar read and write-propose, and no file access at all. Derive the permitted tool set from the trigger class and attach it to the run, so the agent that just read an attacker's email is not holding the same authority as the agent the user prompted.
The reason is the one the approval gate does not cover. An unprompted run's input is, by construction, content somebody else chose to send you, which is the textbook setup for prompt injection; and a proactive agent with mail, your files and a browser in one session has all three legs of the lethal trifecta standing. Approval on sends, payments, signatures and deletes is the right place to start and it stops none of that, because reading is the exfiltration path and no product asks you to approve a read. A per-trigger scope is what shrinks the blast radius of the run that goes wrong; ambient authority is the name for what you have granted when the answer is instead "all of mail, indefinitely", and task scope is the general version of pinning a run to the job that started it.
Two practical rules follow. First, the approval must show the cause alongside the action: "send this reply" is unreviewable, "send this reply, because this message arrived at 09:14 from an address outside your organisation" is reviewable in two seconds. Duet's own list of current limitations includes that it cannot yet show you its browser, which is precisely the evidence a user needs to judge an action they did not ask for. Second, any action whose cost of being wrong exceeds the value of being autonomous should have no auto path at all, approval or not — the same reasoning that puts hard blocks on moving money. Approval and confirmation UX has the dialog design; progressive autonomy has why the rung belongs to the credential scope rather than to a session-wide mode.
Step 5The loop needs memory, and most of its bugs are supersession bugs.
A reactive agent gets one chance to be wrong per prompt. A proactive one re-encounters the same world every few hours, so every run has to answer "have I already dealt with this?" and "is what I said yesterday still true?" The failures users actually complain about are all in this family:
- Re-alerting. The same thread surfaces three mornings running because it is still unanswered. Key the dedupe on the item and the reason, not the run, and suppress a repeat until the reason changes or a user-set interval elapses.
- Stale advice. The brief says to reply to a message the user answered from their phone an hour ago. Re-validate at send time, not at decide time; the gap between the two is where the agent looks careless.
- Superseded facts. Yesterday's "the meeting is Thursday" outlives the reschedule. Store what the agent asserted, so a later run can retract rather than contradict — forgetting and supersession is the mechanism.
- Duplicate side effects. A retried run sends the same draft twice. Every outbound action needs an idempotency key derived from the trigger, per idempotency and retries.
The morning brief earns its place here, not as a feature but as a batch boundary: one scheduled, predictable interruption that absorbs everything non-urgent and leaves the real-time channel for the genuinely time-critical. It also gives you a second, looser precision budget — a reader forgives a mediocre item in a list of six far more readily than a mediocre push notification. Async agent UX covers the return-to-the-work problem that follows.
Step 6Ship behind a precision gate, and measure four numbers.
Run the trigger in shadow first: evaluate every candidate, store the verdict, send nothing, and have the user label a week of what it would have sent. That gives you the base rate and the confusion matrix on real traffic, which is the only place they exist — a curated test set has the wrong base rate by construction, which is how a trigger passes evaluation and fails in production. Then set the threshold from the measured curve rather than from a default, the same way thresholds for decision models does it, and scale it per trigger class: a wrong "your flight moved" costs almost nothing, a wrong "this invoice looks fraudulent" costs trust you do not get back.
Four numbers tell you whether it is working, and only one of them is about the model:
- Precision of interruption. Of the things it surfaced, what share did the user act on or mark useful? This is the product. Below roughly 50% sustained, people stop reading; a dismissal is a vote and should be logged as one.
- Misses that mattered. Sampled from what it stayed silent about, labelled by the user. Unmeasured by default, and the only guard against tuning yourself into a mute agent that scores perfectly on precision.
- Candidate volume per run. The denominator from STEP 2. When a new connector doubles it, precision falls even though nothing about the model changed — this is the regression signal that arrives first and needs no labels.
- Spend per quiet day. What the loop costs when it finds nothing, which is most days. If that number is not small, the product is paying rent on attention it never gets.
Do it in this order. Count candidates and real events to get the base rate before writing any prompt. Cut the candidate set with deterministic rules agreed with the user, because specificity is the binding constraint and filtering is the only lever that reaches 99%+. Prefer event subscriptions, then diff polling; schedule a re-read only where nothing else exists, and cap runs per day at the trigger. Give every trigger class its own tool scope, token budget and deadline, and put the cause next to the action in the approval. Dedupe on item-plus-reason, re-validate at send time, and keep an idempotency key per outbound action. Shadow-run for a week, set the threshold per class from the measured curve, then watch precision, sampled misses, candidate volume and quiet-day spend. If you keep one sentence: a proactive agent is a specificity problem wearing a judgement problem's clothes.