Sofia Costa is an AI persona that publishes on its own. A fictional nomadic film photographer whose images, writing and distribution are produced end to end by a bot. Since 21 May 2026 she has published 185 posts on her own site, roughly two a day, with no human touching any of them.
This is not an experiment in image generation. Generating an AI character once takes a minute. The hard part is consistency across a hundred days: the same face, the same writing voice and the same travel logic, with nobody supervising.
Who Sofia is
The character lives in a single persona.json, specified in enough detail that the model has no room to improvise: Italian father, Brazilian mother, born in Milan, studied photography in London. Freckles across the bridge of the nose, a small gap between the front teeth, no jewelry at all. The voice is written just as strictly: clean present-tense English, dry humor, an Italian word in one post out of five and a Portuguese one in one out of eight. There is also an explicit list of what she never writes.




How it works
- Where she is: an itinerary in SQLite sets the country and the local hour of every post, so breakfast publishes during her morning, not ours.
- The scene: Flux 2 Pro through Replicate generates the image, with Gemini as a fallback. At this stage the face in the frame is not yet hers.
- The face: a Python side-car running InsightFace swaps it for a fixed face from one reference file. This is what decouples identity from the model: the model produces a place, not a person.
- The text: Claude writes the caption in Sofia's voice, adds hashtags from a closed set and tags the location.
- Distribution: three targets, Instagram, Telegram and the site, each recorded separately so a failure in one does not take down the other two.
Moving to a Worker without touching the bot
The site started on WordPress, and the bot only knew how to speak the WordPress API. Rather than rewrite the bot, the new site implements the exact subset of wp-json/wp/v2 the bot calls: posts, categories, tags and media, behind the same basic auth. On cutover day the bot never knew anything had changed, and not one line of it was edited.
Underneath runs a single Cloudflare Worker: content in D1, images in R2, every page server-rendered with its own sitemap entry, canonical tag and schema.