The editing pass can't tell you a sentence is false
An agent drafted an article for our lodge blog about how many days to spend in the Maasai Mara, and it had argued itself into ruling out long stays altogether: six days was too many, for anyone. The draft had already been through our whole pipeline (a writer agent with live search research, an editing pass for AI habits and a critic agent), and the prose survived all three.
I have photographer friends who came for six full safari days and loved every one of them. Six is still too much for most people, and the published article says so, but the flat no was wrong in a place no amount of tightening the language reaches.
The same kind of sentence turned up twice more that day: once in an agent's reading of our Search Console data, and once on our own website, in the pages an AI reads before answering a guest. The lodge is Mara Hilltop, 2.5 km outside Sekenani Gate in Kenya, and I run it alongside SimbaStack.
Talking is faster than writing
I can answer the safari-length question on WhatsApp without thinking. Turning the same answer into fifteen hundred words is a job I'll postpone for a month, so I talk instead, into Handy, an open-source dictation app that transcribes on my own computer. The rest of the workflow runs in the cloud.
What comes out is a mess. In the duration conversation I went from the six-day photographers to taking a day off between game drives, then to the Maasai markets where people are actually trading cattle, then to the motorcycle trips through the villages into the Loita Hills. Those details change what someone books. We've had guests stay twelve days and love it, and a week or two near the Mara doesn't have to mean paying to enter the reserve every day. An agent can organise all of that, link our older posts and check the fee tables against the county's schedule. It can't know my friends stayed six days until I say so.
Around the dictation sit a shared tone guide, an editing pass we call Humanizer, an SEO research skill, a publishing script for Ghost and a translation workflow for seven more languages. The tone guide exists because a SimbaStack post reached the Hacker News front page in May and the comments, friendly as they were, said the prose read as machine-written. Humanizer catches the habits, like balanced paragraphs and the tidy summary bolted onto the end. None of it can tell that a sentence is false. Nothing runs on a timer, and nothing publishes an opinion I haven't read.
Three months of Search Console
The chart at the top covers six months of the whole site. The numbers here come from a shorter export, 19 June to 18 September: 1,697 clicks and 34,902 impressions, with the blog taking 615 clicks from 28,204 impressions. From the first fortnight to the last, impressions went from 230 a day to 442 and clicks from 14 to 20. August beat September, though, so you can tell a growth story or a decline story depending on the fortnight you pick, and I can't separate the blog from migration season.
Six topics produced 600 of the blog's 615 clicks: planning a Kenya safari without an agency, getting from Nairobi to the Mara, a Nairobi city guide, whether Nairobi is safe, sleeping inside versus outside the reserve, and a flooding update from March. Every other article, which is most of them, made seven clicks between them, and tag and author pages took the last eight.
The first analysis of the queries found a cliff, 26.7% click-through in positions one to three and under 1% below that, and built a section on it about how ranking sixth is worth nothing. That section was in the first draft of this post. A second agent, checking the draft against the CSV files, found the hole:

Google leaves rare queries out of the export, so it covers 826 of the 1,697 clicks, and about 750 of those came from people searching for the lodge by name, who were always going to click. Without them there's no cliff. It's the same mistake as last week's post, where the same kind of tooling divided correctly and then blamed the distance to Ireland.
The comparison I trust more is one article in three languages, because the advice is identical and only the competition changes:

I think it's competition. The English page is up against every tour operator selling Kenya and the Italian one against far fewer, so the same advice sits five positions higher and gets clicked twice as often. Across the blog, English pages turn 1.9% of impressions into clicks, Italian 3.7% and French 5.7%. Arabic manages 0.4%, for a reason further down.
What doesn't get clicked
Our Nairobi safety article averages position 8.2 and gets clicked on 1.4% of its impressions. The query "is nairobi safe" alone showed it 1,662 times for twelve clicks. When I searched it this week, an AI Overview answered the question at the top of the page. Pew found that American users clicked a result on 8% of Google searches showing an AI summary, against 15% without one.
"mara hilltop reviews" got 374 impressions and one click at position 7.2. Someone searching for reviews of my lodge by name has nearly decided, and we have no reviews page for Google to show them.
Why "yes please" is in our Search Console
Google's documentation says each follow-up question in an AI Mode conversation is logged as a new query, with its own impressions, position and clicks. So our export has rows like these:

There are a few dozen of them, and the only two clicks came from people asking about public transport.
What an AI would have read about the lodge
The same day, we audited marahilltop.com with one question: if Google's model or ChatGPT answers a guest from our pages, what does it read? That includes llms.txt, a plain-text summary of the site written for AI crawlers, and the schema.org markup search engines read for prices and policies. The first thing we found:

There's one schedule now, on every page and in all eight languages. The rest of the list:
| What we found | What a guest, crawler or AI assistant got | What we changed |
|---|---|---|
| Room prices | The rooms page showed "$400 / night", which matches nothing our booking engine charges | Public seasonal rates on the page, in llms.txt and in the structured data, from one config file. Agent and group rates stay off the site |
| Seven lodge pages in eight languages | English text under German, French and other language addresses. Search Console had flagged 46 of them as duplicates | Pointed Google at the English originals, then translated all seven pages a few hours later |
| Speed | Every page rendered from scratch on every request, 0.8 to 1.6 seconds to first byte | Served from Netlify's cache, 0.12 to 0.49 seconds from a server in Germany |
The speed problem was one call. Every page declared a cache lifetime, and every response still came back private, no-store, because the root layout read a request header to set the lang attribute:
// app/layout.tsx, before (simplified)
import { headers } from "next/headers";
export default function RootLayout({ children }) {
const path = headers().get("x-pathname");
const lang = localeFrom(path);
const dir = lang === "ar" ? "rtl" : "ltr";
return <html lang={lang} dir={dir}>{/* ... */}</html>;
}
Calling headers() in a layout opts every route beneath it into dynamic rendering. The fix takes the locale from the route segment instead, which Next.js can prerender:
// app/[locale]/layout.tsx, after (simplified)
export function generateStaticParams() {
return locales.map((locale) => ({ locale }));
}
export default function LocaleLayout({ children, params }) {
const { locale } = params;
setRequestLocale(locale);
const dir = locale === "ar" ? "rtl" : "ltr";
return (
<DocumentShell lang={locale} dir={dir}>
{children}
</DocumentShell>
);
}
From Kenya the gain is smaller, because a static favicon already takes 0.68 seconds to reach us.
The blog had its own list. The Arabic Nairobi guide had 1,900 impressions, fourth on the blog, and eight clicks. Since April it had been served with its language set to English and no right-to-left rule, so the Arabic ran left to right until a CSS rule fixed it on 21 September. The transport guide, our most-seen page, used to put the lodge at Aitong, 35 minutes inside the reserve, when we're 2.5 km outside Sekenani Gate. It's corrected in all eight languages. The DIY guide still says green season is January to May in one section and January to March plus November in its FAQ.
The false sentences in the first two parts of this post came from agents. These were already sitting on our own site, and no check on the prose would have found them either. A guest who lands on one of these pages can't tell which version is current, and neither can a model, which repeats whatever it read in the same even tone.
Repairs first
I'll keep publishing, since ten finished drafts are waiting. But five of the six articles that work were live before May, and each one answers a single question a traveller has before booking. So the repairs go first, starting with the DIY guide. What changed in the checking is small: every draft in the current batch ends with a list of the claims only I can confirm, and the lodge's rates and booking terms live in one config file that the rooms page, llms.txt and the structured data read from.
The number I still don't have is the one the whole thing is for. Until 21 September the blog had none of the main site's analytics, so we couldn't follow those 615 clicks past the article they landed on. Now a reader who lands on the transport guide and opens the trip planner counts as one visit. In a month I'll know what some of them do next, and it may well be nothing.
— NJ
I run SimbaStack, where we build AI agents and the systems they work in, and Mara Hilltop, the lodge in this post. If you need help getting an agent into production, tell me what you're building: nj@simbastack.com.