Your app already talks to the model
Somebody built a vampire character chat on Vibes. Three vampires with their own backstories and ways of speaking, and you pick one and talk to it. The first version worked: type a line, the vampire answers in character, a portrait appears beside the name. A good app, made in a minute or two.
Then a gold chip appeared under the chat, offering an upgrade. "In-character chat replies need an LLM call using each vampire's persona as context." The owner tapped it. The reply moved off the page and onto a server, where it arrived a beat later by a longer road, written to the database and synced back. The upgrade made the app worse, and the interesting part is why it was offered at all.
The belief every model carries
Everywhere else on the web, calling an AI model from a browser leaks a key. The request has to carry a credential, anyone can open the developer tools and read it, and so every tutorial, every framework guide, every answer on every forum says the same thing: put the call behind a server. A model that has read the web has read that ten million times. "LLM call means server" is not an opinion it holds. It is the shape of the world as far as it knows.
On Vibes that shape is wrong. Page code here calls the model through the platform, with no server of the app's own. On the ordinary signed-in path the call is charged to the account of whoever pressed the button, the app holds no provider key because the platform keeps credentials on its side, and the result comes back to the app through the runtime. A chat, a suggestion button, a generated portrait: all of it is ordinary page code. The server exists for the things a page should not be trusted to decide alone, like moderation, a nightly digest, a summary that runs while nobody is looking.
What the agent had actually read
We went back and read the agent's own session for that app. It had never been told the second picture. Its instructions named four reasons an app might need server work: data more than one person writes, work that must happen when nobody is looking, fetching from somewhere else, notifications. Its tool schema described the backend skill as being for "server work" and ended the list of skills with "omit for a plain UI draft". And the same schema offered a field for capabilities the first build would leave for later, with a required sentence explaining why.
Get posts like this in your inbox
One email field. Real updates. No algorithm required.
Read together, by a model whose prior already says an AI call is server work, that is a complete argument. The first build is a plain draft. A plain draft has no AI. The AI parts are therefore deferred. The field is there to be filled, and the sentence it asks for practically writes itself. So the agent wrote it, the platform saved it, and half an hour later it was a gold chip with the agent's own guess printed on it as a recommendation.
Nothing in that chain was a bug. Every piece did what it was built to do. The gap was one missing fact, and a missing fact gets filled by the prior.
Teaching it without saying no
The tempting fix is a rule. "Do not use a backend for chat replies." "Never defer callAI." We do not write prompts that way, and we have written before about why: a prohibition ships the exact spelling of the mistake into every generation, with one token of sentiment stapled to the front. You wanted a guardrail; you built a beacon. It is also brittle. A rule against backends for chat says nothing about a rule against backends for suggestion buttons, or portraits, or the next thing.
So the correction is two adjacent sentences, placed exactly where the agent decides what the second wave of a build is for. The first describes what the page does:
AI the person watches happen is the page's own work: callAI answers a chat reply or a suggestion and ImgGen paints a portrait inside the page, on the account of whoever pressed the button, so a character chat, a writing helper or a portrait maker is complete as client code.
And, right after it, the case that does belong on the server, named positively too:
backend.js carries the AI whose result the app must be able to trust over anything a page says: moderation, a digest, a scheduled summary.
The new lines contain no "never", no "do not", not even an "instead of". They give the agent the fact its prior was missing and a picture of the world in which that fact is true. The bad shape is not mentioned, so it is not in the context to be continued.
Two smaller edits ride with it, in the same voice. The skill list no longer says "omit for a plain UI draft", which read as "the first build has no AI". It says a chat reply, a suggestion or an image the page asks for is part of every build, and names the skill that teaches the page's model call. And the deferral field now tells the agent that whatever it writes there will be shown to the owner as an offered upgrade. That is not a rule either. It is a consequence, stated plainly, and a model that knows its guess becomes a button on someone's screen guesses more carefully.
The part that travels
If you write instructions for an agent, the lesson is not about vampires.
An agent's mistakes are mostly not reasoning errors. They are the prior filling a hole. When the agent does something confidently wrong, the first question is not "what rule stops this" but "what fact did it never have". Then state the fact, once, where the decision is made, in the voice of what the system does. Describe the world the agent is standing in rather than fencing off the world it came from.
And read what it actually read. Every prompt, every tool description, every field with a required explanation is a question the model will answer. The schema that asked "why is the backend deferred" got an answer every time, because it asked.
Make something that talks back
Describe a character, a helper, a game. The page calls the model with no server of its own.
Start building →