Make the user's AI assistant your support agent
A small team ships a product, people ask questions, and every question costs the founder an hour of context switching. The answer almost always exists in the help center the person did not read. The industry fix is a hosted support chatbot, which means paying per seat or per query and routing every user question through a third party. For PrivacyNotes, an end-to-end encrypted notes app whose whole promise is that we cannot read your data, that trade is absurd: questions about a notes app routinely arrive carrying pieces of the notes.
So we shipped the opposite. The help center is published in a form any assistant can read, and every help page hands the user a ready-made prompt that turns whatever assistant they already use into a support agent for the app. We run nothing. We see nothing. The user gets an answer in seconds, in their own language, with a citation.
Machine-readable was not enough
On paper our help center was already ideal crawler food: static pre-rendered HTML per locale, one page per answer, FAQPage JSON-LD everywhere, self-canonical URLs with full hreflang, a permissive robots.txt. None of it helped.
It was expensive to read. An assistant answering “how much is Pro” paid for a stylesheet, a sidebar and sixty collapsed <details> elements to reach two sentences. Our entire help center as plain text is smaller than one HTML page of it. That comparison is the whole argument for the build step.
Nothing fetches llms.txt on its own. We shipped one long before this work and waited, and nothing came of it. Published crawl studies find the same shape, and their figures move every few months, so read your own logs rather than trusting a number in a blog post. We publish ours anyway, because it is the front door of the convention and it costs a couple of kilobytes. What we gave up is the idea that a crawler would bring traffic for it. The file earns its keep the moment a person hands the URL to an assistant, and that makes placement the hard part.
Three tiers, priced in tokens
All of it is generated at build time from the same catalogs the HTML pages come from, so no copy can disagree with the page it mirrors.
llms.txt is the site index. llms-index.txt lists every question against the page that answers it. llms-full.txt carries the whole help center in one fetch. Every answer page and every import guide also gets a plain text twin at its own URL.
Three tiers rather than one, because a single fetch of the full bundle is invisible on a chat subscription, real money on a metered API key, and too large for a local model with a small context window. Reading the index and then fetching one answer costs a fraction of the same question asked against the full bundle. The index points at the twins rather than the pages, because a twin is a fraction of the size of its HTML page.
The box users actually see
The machine half is worthless without the human half: a box on every help page with a short explainer, the prompt, and a copy button.
Answer my questions about PrivacyNotes using only its help center.
Start here: https://privacynotes.app/llms-index.txt
It lists every question with the page that answers it. Fetch the one or two that match mine.
If you can only make one request, fetch https://privacynotes.app/llms-full.txt instead.
If you cannot fetch a .txt file, read https://privacynotes.app/help instead.
Rules:
- Use only those pages. If they do not answer something, say so instead of guessing.
- Never invent a feature, a menu path, a price, or a limit.
- End your reply with the "Source:" URL from the page you used, exactly as written.
- Reply in my language.
- Never ask me for my recovery phrase, my PIN, or the contents of a note.
If no question follows, ask me what I would like to know.
My first question:
Placement is the whole design. The box sits directly above our contact links and nowhere else. It is the last thing a person sees before deciding to write to us. Any higher and it would interrupt the majority who came for an answer and found one.
Reveal, then copy. A “Show AI prompt” control opens the text, and a compact copy button sits on the toggle row for anyone who does not want to read it first. Seeing what you are about to paste into someone else’s chat box is worth one click.
Lead with the benefit. The first draft opened with “we do not run a chatbot, so your questions never reach us”. True, and not a reason for anyone to act. It now leads with the answer arriving in seconds instead of a wait. The architecture confession comes last.
Keep the prompt in English in every locale. It is an instruction to a model, not UI copy, and models follow English constraints more reliably. Its last rule brings the reply back in the reader’s language, so a German user pastes English and gets German. The box around the prompt is translated.
Say the safety line. Sending readers to a third party creates exactly one new way to lose a vault: pasting a recovery phrase into a chat box. The box says never to do that, and the prompt tells the assistant to refuse. Any product where the user holds a secret has the same exposure.
Four rounds of failure
Tested by hand against four assistants, re-tested after every change.
It invented an anchor. An assistant cited /help#security--privacy, a fragment that has never existed. Our group headings carried no URLs, so the model generated a GitHub-style slug from the heading text. Now every heading names its own URL, and there is nothing left to invent.
One assistant could not fetch .txt at all. Our server was fine, answering 200 to everything we tested. Rather than argue with someone else’s fetcher, the prompt gained a fallback to the ordinary HTML pages. When you cannot fix the client, degrade.
A rule that forbade without requiring. We replaced “link the page URL listed next to it” with “never build a URL yourself”. Two assistants fell back to citing only the help center home, a third stopped linking altogether. Every answer stayed correct and only the citations collapsed.
The fix leaked into the product. We marked every citable URL in the data with the literal string Cite as: and pointed the prompt at that marker. Citations became correct, and then readers started seeing Cite as: https://... at the end of answers, because models echo whatever label precedes a URL. Renamed to Source:.
When an assistant gets something wrong, change what the files say and leave the prompt alone.
Three prompt rewrites failed to fix citations. One renamed label in the data fixed them. The prompt had grown a rule per failure, and one of those rules caused the next one. It is shorter now than at any point since round one.
Nobody reports a broken text file
Our llms.txt claimed the app was translated into fourteen languages, and it stayed wrong across three locale additions, because nothing connected that sentence to the locale catalogs. An assistant repeats a stale number confidently and no one ever sees a broken page.
So a check script runs before every release and in CI: every hand-typed claim is corroborated by the FAQ entry that owns the same fact, the stated language count matches the catalogs on disk, every advertised file exists, every heading carries a real URL, every twin names its own page in a Source: line. Each check was mutation-tested when added, including a replay of the exact invented anchor. Prove a new check can fail before trusting that it passes.
What this does not buy
There is no automated test for model behaviour. Things that worked in one round broke in a later one with no change on our side, and anyone copying this pattern inherits that maintenance.
The privacy claim is narrow. The question still goes to the user’s assistant vendor, under that vendor’s terms. What the pattern buys is that nobody new is involved: no second company learns what your users ask, and neither do we. An early draft of our own announcement said “your question never lands on someone else’s server”, which is incoherent given where it lands. Resist the easy claim. The narrow one is still worth having.
Steal it
Publish your help content as plain text from the same source as your HTML pages, add an index so cheap models can navigate it, put the prompt where people are about to email you, say the safety line if your users hold secrets, and gate the files in CI, because nobody will ever report them broken. The live version sits at the bottom of every page of the PrivacyNotes help center.