Most portfolios are PDFs with better typography. You read them, you skim the metrics, you move on. I wanted mine to answer back — literally. Press K, or tap the orb, and you can ask my AI concierge anything about my work, by voice, and get a spoken answer grounded in my actual career data.
This post is about how that works and why I think it was worth building.
Why a voice concierge at all
The honest answer: the medium is the proof. I position myself as a product manager who builds AI systems. A written claim about "shipping production-grade AI workflows" is easy to type. A working voice agent that knows my career, survives interruptions, and degrades gracefully when a GPU isn't available is much harder to fake. If a recruiter can talk to my work instead of reading about it, the portfolio stops being a document and becomes a demo.
Two pipelines, one conversation
The system runs on two very different voice stacks.
VAPI — the managed path
The default pipeline is VAPI, a managed voice platform. It handles speech-to-text, text-to-speech, and turn-taking, and calls back into my own LLM endpoint for the actual answers. It's reliable, always on, and costs nothing when idle. This is what every visitor gets first.
PersonaPlex — the real-time path
Behind a feature flag (NEXT_PUBLIC_PERSONAPLEX_ENABLED) sits the second pipeline: NVIDIA's PersonaPlex, a full-duplex speech-to-speech model running on a RunPod GPU pod. No cascaded STT → LLM → TTS — audio in, audio out, with natural interruptions. The browser streams 24kHz mono Opus audio over a WebSocket straight to the pod.
Full-duplex is a genuinely different experience. You can talk over it, change your mind mid-sentence, and it reacts the way a person on a call does.
The handoff problem
Starting a GPU pod takes time — sometimes minutes. Asking a visitor to wait for that before saying a single word would be a terrible first impression. So the two pipelines overlap: the moment a VAPI call starts, the app quietly warms up a PersonaPlex pod in the background. When the pod reports ready, a "Try Real-Time Voice Mode" prompt appears mid-conversation.
If the visitor accepts, the VAPI transcript — stored turn-by-turn in Upstash Redis — gets compressed into a compact context bundle (recent turns, a running summary, structured intent and interests, capped at 1,800 bytes) and handed to PersonaPlex as its persona prompt. The new voice picks up roughly where the old one left off.
If the pod never becomes ready, or real-time mode fails, the state machine just stays on VAPI. The feature gate means the whole PersonaPlex path can be switched off with one environment variable.
What I'd do differently
The dual-pipeline design is more complexity than a portfolio strictly needs. A single managed provider would cover 90% of the value at 10% of the operational surface. But the 10% — pod lifecycle, heartbeats, a self-terminating watchdog, a mid-call handoff — is exactly the kind of systems work I wanted to show. The transcript storage in Redis turned out to be the quiet hero: it made handoff, session metadata, and post-call review possible with one boring, dependable primitive.
The concierge is live on the homepage. Ask it something I didn't expect — that's when it's most interesting.