Designing for an Audience of Agents
5 min read
The busiest user of the thing I build has no screen. It never opens the dashboard — it can't, it doesn't have eyes. It's an AI agent, and the interface it actually touches is a set of tools it calls over MCP: store_memory, query_memory, and a dozen or so more. Claude Code, Cursor, Windsurf, some custom agent a stranger wired up last week — they all drop in over the same protocol and share one persistent memory. No bespoke integration. Just tools on a wire.
So the product-design question flips. Not "what does this look like" — nobody's looking. It's "what is good UX when your user is a language model?"
The answer is still a design answer.
An agent reads your API the way a human reads your buttons
When I designed a checkout flow, a badly-named button cost a tap, a hesitation, sometimes the sale. The label was the affordance.
For an agent, the tool schema is the label. A model decides whether to call query_memory by reading its name, its description, its parameters — the same way a shopper decides whether a button is the one they want. Vague schema, wrong call. So I name tools and shape their inputs with exactly the fussiness I used to spend on microcopy, because the schema is the microcopy now. Both readers punish ambiguity.
Latency is the experience
Here's the thing about an agent: it has no patience, and nothing to look at while it waits.
A human tolerates a spinner — they glance away. An agent called your tool in the middle of reasoning, and every millisecond you take is a millisecond the whole conversation stalls. So full-text search in Coquina returns in under two milliseconds. Not because I like the number. Because for an agent querying its own memory mid-thought, latency isn't a metric sitting next to the experience. Latency is the experience — the same way it was when a screen had to feel instant under a thumb.
The best retrieval returns words you never typed
The hardest part of the job-to-be-done is that the agent often doesn't know the words it's looking for.
It stored something three sessions ago in language it no longer remembers, and now it's asking a differently-worded question about the same idea. Keyword matching alone fails that user. So a query fans out three ways in parallel — keyword, semantic, and graph traversal across linked memories — and the results merge. I'd rather spend the compute running all three than make the agent guess the magic phrase. Good retrieval finds what you meant, not what you said. That was true for search boxes built for people; it's truer for a user that can't get frustrated and rephrase.
Taste is admission control
The decision I'm proudest of is the one that says no.
Every write to Coquina is scored on several signals of information density before it's allowed in. A-MAC — the admission controller — is deliberately choosy. It rejects garbage, near-duplicates, and low-signal noise instead of hoarding everything an agent tries to shove in. That's not infrastructure dressed up as taste; it's editorial taste implemented as infrastructure. It's the same instinct that clears a cluttered screen: what actually deserves to be here? A memory system that keeps everything is a junk drawer. The 25-plus typed categories underneath are just information architecture — filing, so the right thing surfaces later.
The honest cost is real: a gate strict enough to reject junk will sometimes reject something that turned out to matter. Choosiness has a false-negative rate, and I won't pretend it's zero. I'd still rather tune a system that's occasionally too strict than dig through a junk drawer — but "too strict" is a real failure mode, not a slogan, so I watch what it throws away.
Design has always been mostly subtraction. That doesn't change when the user is a model.
The name is the spec
Coquina is a sedimentary stone — many small shells bonded into one soft rock. The old Spanish fort in St. Augustine is built of it, and it absorbed cannonballs instead of shattering, because the force distributed across all those bonds rather than cracking one slab.
That's the architecture, not just the branding. A brittle, monolithic memory store fails all at once under load. Coquina is many small memories bonded by auto-linked relationships, so the load spreads. The name is the spec: a product whose failure mode is "bends," not "shatters."
A context window is the wrong shape
Strip it back and this is a plain product call. A model's context window is session-scoped — gone when the session ends — and it degrades as it fills. It's working memory pretending to be long-term memory. Coquina is permanent, shared across every tool and project, and it gets better as the graph gets denser — the exact opposite behavior.
The product exists because the context window is the wrong shape for the job. Not too small. Wrong shape.
Know your user, define the job, sweat the latency and the naming — none of that changed when the user stopped looking and started reading. My busiest user can't see a thing I make, and I've never designed more carefully in my life.