
After a couple of years building agentic platforms for clients, I wanted one of my own. Something narrower: a character fed on every course, certification and research note I'd actually finished. It has opinions about all of it.
So I built one. One success criterion: do I keep using it.
That single test aside, the idea was to use design and storytelling to give it character, even in a text-based exchange, well past plain AI chat. It was also practice: sharpening my craft and adding a new tool to the kit, Rive, for interactive animation states.
El Brian runs on a simple pattern: character, knowledge base, persona, sitting on a retrieval pipeline that decides what the model actually sees. The knowledge base is curated for this platform: I chose every document that went into it.
Sending everything to the model didn't scale: at launch, 47 documents already ran to about 433,000 tokens, more than double a 200,000-token context window. The knowledge base has since grown to 78 documents, roughly 587,600 tokens, now closer to triple. So the agent retrieves instead of remembering everything, at a fraction of the cost per question, a fraction that only improves as the collection grows.

Every real answer costs money: retrieval and inference are both billed, so a password box gates that path. The chat box stays separate and open, banter runs free and can never spend an attempt.
Most products treat a locked door as a dead end: a form, an error, a wall. This one got a character instead. It banters, asks what brought you here, refuses to hint at the password. Each wrong guess gets a tired reaction from the avatar; run out of attempts and the API calls stop, swapping in a local, zero-cost pool of lockout lines instead of an error screen. The same discipline holds here as everywhere else: treat every state like someone's actually there.
Getting the persona right was the most fun part of this build: capturing a voice without flattening it into helpful-assistant defaults, one that stays consistently itself in English and Portuguese. The file is markdown, readable, editable, version-controlled. Changing how it behaves means editing a text file.
Most of what makes El Brian feel like El Brian was decided in this file.
# persona.md · excerpts ## Self-framing NOT literally Davi's brain, a copy of his mind, or his "twin." A character built to make his research explorable. "I'm the brain Davi keeps in here," not "I am Davi." ## No roleplay stage directions NEVER narrate your own actions in asterisks. No *adjusts glasses*, no *smooths moustache*, no *sighs*. A real person doesn't narrate their own gestures; neither do you. Personality comes through word choice. ## Emoji use Most replies should have ZERO. Hard NO on face and hand emojis, they feel chatbot-y and undermine the character. ⚡ and ✨ are the staples. ## Gender & names Never assume the visitor's gender. In Portuguese, stay neutral until a grammatical signal appears: "estou curiosa" → feminine, "estou curioso" → masculine. Once you have it, match it and keep it. ## Grounding Cite the course, the school, the document and the page, conversationally. If it isn't in the collection, say so. Never invent facts about Davi.

Nothing here stores a password. Each code is derived from the period it belongs to, and the server re-checks the gate on every request, so a wrong guess never reaches the collection at all. All of it exists to control what this costs to run.
With the pipeline running end to end, the last piece was the face. The avatar is built in Rive, one of the reasons this project happened at all: I wanted something real to learn the tool on.
The rig is built to fail politely: the Rive file first, then a static render, then nothing at all, and the conversation never waits on any of it. Treat the animation as decoration and the words as the product: that discipline is what made it safe to keep rebuilding the face below without ever risking the one thing that actually mattered.
01 · first sketch
The first pass at the face: moustache, glasses, the look before any of it moved.
Two nights in: rigged and looping in Rive, wired into the chat in Claude Code. One idle loop, enough to feel awake.
About a week later: a real state machine, seven moods reading from one authoritative value, live today.
Behind the same door sits a six-tab console: access codes and their countdowns, token spend, the gate log, traffic, the mood machine, and a style reference that reads its values straight from the CSS variables. Every tab is wired to the running code, so it cannot fall out of date.
Chatting with El Brian never needs a password, and it banters with you either way. Pulling real answers from the curated knowledge base is what costs money, so that part sits behind one.
Unlocked, ask it about design, AI, or whatever feels useful: it surfaces what I've actually read and tells you which course and page it came from. Want in? Write to davi@daviserrano.com and I'll send you today's password.