Back to portfolio

Voice-first RAG

Voice AI Assistant (RAG)

Speak the question, hear the cited answer. Full voice loop in production.

Demo limits

  • ·5 questions and 3 documents per session, evicted on expiry
  • ·300 answers and 600 transcriptions per UTC day, across everyone
  • ·Kill switch that stops paid calls without a redeploy

A public AI demo is a spending endpoint. Cost control is part of what I ship.

Problem

Most "AI assistants" force the user to read walls of text. Voice-first interfaces win on accessibility and time-to-answer, but stitching mic capture, STT, retrieval, and streaming TTS without 5-second lag is non-trivial.

Approach

  • Browser captures mic via MediaRecorder (webm-opus / mp4-aac) and posts a single multipart blob, with no WebRTC complexity.
  • gpt-4o-transcribe handles speech-to-text server-side with a language hint; the transcript pre-fills a textarea so the user can edit before submitting.
  • Hybrid retrieval: pgvector HNSW + tsvector GIN fused by RRF in a single SQL round-trip, then optional cross-encoder reranking. Two relevance thresholds, one per score scale, because a fusion rank and a calibrated reranker score are not comparable numbers.
  • Embeddings run locally: FastEmbed on ONNX with paraphrase-multilingual-MiniLM-L12-v2, so ingest makes no external embedding call and answers work in the visitor's language.
  • Answer streams as PCM audio chunks over SSE directly into the Web Audio API. Sentence-pipelined TTS starts speaking sentence one while the model is still writing sentence two, which takes first-audible-word from ~1500ms down to ~600ms.

Stack

Next.js 16React 19FastAPIPostgreSQL 17 + pgvectorgpt-4o-transcribegpt-4o-mini-ttsFastEmbed (ONNX, local)DeepSeek via OpenRouter