← Back to projects
Case study

Interactive Voice AI Agent for Portfolio

Real-time voice interactions using Gemini Live API and Web Audio.

// Role
Full-Stack / AI Engineer
// Context
Personal project embedded in this very website
// Stack
Gemini Live API, Web Audio API, WebSockets, Astro, PHP
#

Problem

A static portfolio doesn't prove what you can build. Visitors need a fast, natural way to explore my projects and experience.

The solution was letting them talk live to a voice agent that explains my experience and answers questions about my work.

#

Architecture

A real-time bidirectional audio flow connecting the browser securely to Gemini Live:

flowchart TD
User["Browser (Mic/Speaker)"] -->|"Bidirectional Audio"| VoiceClient["Frontend Client"]
VoiceClient -->|"Request Token"| TokenEndpoint["Token Endpoint"]
VoiceClient -->|"Live API (WebSocket)"| Gemini["Google Gemini Live"]
VoiceClient -->|"Beacon (start/end)"| SessionEndpoint["Observability Endpoint"]
SessionEndpoint --> SessionsLog["Metrics Storage"]

classDef default fill:#0f172a,stroke:#38bdf8,stroke-width:1px,color:#e2e8f0
classDef frontend fill:#1e1b4b,stroke:#818cf8,stroke-width:1px,color:#e0e7ff
classDef backend fill:#881337,stroke:#f43f5e,stroke-width:1px,color:#fecdd3
classDef storage fill:#022c22,stroke:#10b981,stroke-width:1px,color:#d1fae5

class User,VoiceClient frontend
class TokenEndpoint,SessionEndpoint backend
class SessionsLog storage
class Gemini default
FrontendMicrophone audio is captured with the Web Audio API and an AudioWorklet, streamed directly to Gemini, and responses play back in real time.
Ephemeral tokensA small server-side endpoint issues short-lived Gemini Live API tokens to the client. Requests are rate-limited per IP, so no API key is exposed in the browser.
ObservabilityBasic session metrics (start, end, duration) are recorded via `navigator.sendBeacon` to a server endpoint.
InfraAstro static frontend + lightweight endpoints, hosted seamlessly on Hostinger.
Key Architecture Decision

Key decision: Connecting directly to Gemini Live from the browser using ephemeral tokens to minimize latency and avoid a proxy, while keeping the main credentials secure.

#

Results

Metrics observed during launch:

Impressions
2,300+on LinkedIn on launch day
Interactions
~20people talked to the agent within the first hours
Marginal cost
Tier 1almost zero cost per session on Gemini's free tier (150K TPM)
#

What I learned / next step

  • >Ephemeral tokens to safely expose the API client-side.
  • >Bidirectional audio in the browser (Web Audio API constraints).
  • >Minimal observability with no dependencies (JSONL + navigator.sendBeacon).