Privacy

Accept optional first-party analytics or decline. Functional journey and sound preferences stay on this device.

Read the privacy notice

Alex OS is my working proof that RAG over a fully dynamic CMS can think — and my portfolio runs on it.

The human problem

I couldn't find a creative way to show AI engineering and UX in one place. A static portfolio could list my work, but it couldn't demonstrate it.

The transformation

Alex OS became the all-in-one answer: content, colours, themes and even the assistant's tone all live in the CMS — Theme DNA styles the site, Voice DNA shapes how Alex speaks. When I want to change anything tomorrow, I edit content, not code.

One caching pass took Alex OS's heaviest data loads from 10.5s to 1.8s.

Alex OS architecture: interface, CMS content registry, FastAPI reasoning layer, pgvector semantic memory, typed output blocks
Show me systems work with real metrics
alex-osfastapireasoningretrievalproofimpactaisystem
Alex OSalex-osfastapiretrievalproof

The assembled answer with its cited sources is shown as a static final state.

A FastAPI reasoning and retrieval layer that sits between the CMS and the public site — grounded answers, journey-aware recommendations, and a relationship-graph reasoning pass, not an open-ended chatbot.

Wrong turns worth keeping

What I attempted
An animated character — a visible avatar as the face of Alex OS, answering questions on screen.
Why it initially made sense
An assistant with a face felt friendlier and more memorable than a plain chat box.
What showed it was wrong
It read as cartoonish. It undercut the seriousness of the engineering it was fronting.
What I changed
I dropped the avatar. Alex OS became an interface — the orbit, the journeys, a grounded Q&A panel — and the personality moved into Voice DNA instead of a mascot.
What improved
The system reads credible, and the character still comes through in how Alex answers rather than how it looks.
What limitation remains
Alex has no visual identity beyond the interface itself — and I've made peace with that.

Architecture

FastAPI service with distinct route groups for ask/surface/recommend/capture/synthesis/admin, a config-driven engine layer (persona resolver, model router, block composer), and a services layer for retrieval, embeddings, and relationship-graph traversal. Reads CMS content over an internal HTTP API rather than touching the CMS database directly.

Decisions

Postgres/pgvector is optional, with a keyword-scoring fallback, so retrieval degrades instead of failing outright. Personas and prompts are config — stored as data, editable without a redeploy — rather than behavior hardcoded in Python.

The retrieval layer carries the most deliberate trade-offs. Content is chunked (roughly 1,800 characters per chunk, with overlap) rather than embedded as one vector per item, and query rewriting handles conversational follow-ups. A hybrid keyword+vector fusion path (reciprocal rank fusion) ships enabled by default; whether it measurably beats plain semantic ranking on this corpus hasn't been benchmarked yet — that's a gap on the retrieval-quality list, not a settled comparison. Each ask-mode has its own minimum relevance score, because "no good answer" is a better result than a confidently irrelevant one.

One bug shaped the design more than any feature request: typing "projects" into the assistant returned exactly one project. The fix wasn't retrieving more items — it was recognizing that naming a content type is a browse intent, not a question, and switching strategy for it: widen the net, boost the named type, drop the diversity cap that Q&A mode needs.

Problem

A static portfolio site can show work, but it can't answer specific questions about it, connect related pieces, or reprioritize itself based on what a visitor actually cares about.

Content

Alex OS is a separate service, not a feature bolted onto the CMS. It reads structured content through the CMS's internal API, retrieves and ranks relevant items, and answers questions using that content as grounding — it doesn't invent facts and it doesn't have its own opinions about what a visitor should see. The three homepage threads (what I've shipped, where I've worked, what I know) influence what it prioritizes when answering, but the assistant doesn't create or control them itself.

Beyond single-item answers, it reasons over the relationship graph — two-hop traversals where the model's stated reasons are persisted, so a connection drawn once becomes a fact it can reuse — and a coach layer folds what it has learned into concrete guidance inside the admin.

Production hardening is still an open checklist item per the internal progress tracker — confirming Nginx doesn't expose the service publicly, rate limits on public AI endpoints, and secret handling are noted as unconfirmed rather than done. Synthesis of captured activity is still deterministic — there is no LLM pass over it yet.

Close out the hardening checklist; expand automated eval coverage for retrieval quality.

Grounded Q&A, journey recommendations, and content surfacing.

Built with AI assistance (Claude Code). The architecture, the decisions and the trade-offs are mine; a lot of the implementation was written in pair with the model. I work this way deliberately — it's why one person can run a system this size — and the reasoning behind every call here is documented above.

Category
AI & RAG
Tech stack
  • FastAPI
  • Python
  • Anthropic API
  • Postgres
  • pgvector
Metrics
  • Source-grounded answers
  • Per-call cost tracing
Role
Architecture + build

Why I built this

I wanted one place where my AI engineering and my UX taste could prove each other, and I couldn't find a format for it — so I built one. Nothing here is hardcoded: the content, the colours, even the way Alex answers questions comes from DNA I can edit. Being able to change everything tomorrow, without touching code — that's the point.


alex-osfastapireasoningretrievalproofimpactaisystem