The text clone streams tokens. Voice is the same product over audio: Vol. 16 STT → policy LLM → TTS, with Vol. 21 voice assistant UX (barge-in, confirmation) and Vol. 18 WebSockets / streaming. This capstone builds the loop, not a smart-speaker brand clone.
PII in audio and transcripts is a Vol. 20 privacy first-class risk (voiceprints, ambient speech, read-back of identifiers). Latency is Vol. 19 latency: TTFA (time to first audio) beats pretty TTS. Vendor pick is qualitative: Whisper / cloud STT, OpenAI-compatible chat, TTS from Vol. 16.2 / 22.4 (e.g. Whisper, Deepgram, ElevenLabs)—no invented prices. Next module sibling: medical demo (even stricter HITL).
Learning Objectives
By the end of this lesson, students should be able to:
- Implement an STT → LLM → TTS turn with cancel/barge-in and a latency budget.
- Treat transcripts as untrusted text (wrap-as-data) and confirm identifiers before acting.
- Minimize audio/transcript retention; state PII and voiceprint risks honestly.
- Choose WebSockets (duplex) vs SSE+chunked audio for the MVP and defend the choice.
- Eval ASR error separately from LLM error; do not invent WER leaderboard numbers.
- Reuse FastAPI/Docker/auth from prior capstones; keep write-tools under HITL.
An AI voice assistant is a conversational product whose primary I/O is speech: STT/ASR yields a transcript, an application policy + optional RAG/tools plans a reply or action, and TTS speaks it. Barge-in means the user can interrupt playback; the client stops TTS and cancels upstream generation. TTFA is time to first audible sample. Audio and transcripts are PII-bearing channels, not just “chat with a mic.”
Problem and Scope
Typing UX hides ASR mistakes and latency. On voice, a wrong order ID becomes a spoken “fact.” Users interrupt. Ambient speech (a colleague’s name, a card number) can hit the mic. The product job: a responsive, interruptible loop with confirmation on identifiers and a ruthless retention policy.
| MVP (done when…) | Stretch | |
|---|---|---|
| Loop | Push-to-talk or VAD → STT → LLM → TTS stream | Full-duplex always-on; diarization |
| Barge-in | Stop TTS + cancel LLM when user speaks / hits Stop | Server-side VAD on the uplink |
| Latency | Measure TTFA + p95; target “feels live” qualitatively (no fake ms SLA) | Speculative TTS, endpointing tuning |
| PII | TTL on audio+transcript; no long-term voiceprint store; confirm digits | On-device STT; redaction before logs |
| Out of scope | No unsupervised purchases/refunds; no medical/legal advice as fact | Vol. 15 tools only with read-back HITL |
MVP transport
- WebSocket: mic chunks up, TTS bytes down
- or: HTTP STT upload + SSE text + TTS audio stream
- Auth on the socket (token query/header)
Vol. 16 / 22 substrate
- STT: Whisper API or HF Whisper / Deepgram
- LLM: same clone OpenAI-compatible model
- TTS: OpenAI audio / ElevenLabs / open TTS
- Re-read region + retention ToS
Do not ship in v1
- Always-listening wake word in class
- Storing raw audio “for quality” forever
- Speaking back full PAN/SSN
- Invented WER% marketing
WebSockets (duplex)
- Natural barge-in + chunked mic
- Matches Vol. 18 WS lecture
- Needs ping, auth, proxy timeouts
HTTP + SSE (simpler lab)
- Reuses clone SSE for LLM text
- Barge-in is clunkier (abort fetch)
- Acceptable MVP if TTFA is measured
Architecture
VAD / PTT; stream PCM/Opus.
STT partials; wrap as data.
LLM (+ optional RAG); confirm IDs.
TTS chunks; barge-in cancels.
| Plane | Responsibility |
|---|---|
| UI | Mic button, partial transcript, playback, Stop/barge-in, PII warning copy |
| API | FastAPI WebSocket /v1/voice (or HTTP STT + SSE + /v1/tts) |
| Model | STT model + chat model + TTS model (three meters, three failure modes) |
| Storage | Optional short TTL transcript for the thread; default delete audio after turn |
| Eval | TTFA, barge-in success, ASR vs LLM error split, PII canaries, human MOS-style sample |
Concrete Stack + Implementation Sketch
Lab default: browser getUserMedia → WebSocket PCM 16 kHz mono → FastAPI → Whisper-compatible STT (OpenAI or local HF) → same chat client as the clone → TTS stream back as audio chunks. Docker: api + optional GPU Whisper. Redis quotas still apply per user. Confirm numeric IDs before any tool (MVP: no write tools; just spoken confirmation).
Barge-in contract: client stops the audio element immediately, sends {"type":"barge_in"}, and ignores further TTS bytes for that turn. Server sets cancel so the LLM/TTS work stops spending tokens. Partial assistant text is not saved as a completed turn unless you explicitly mark it interrupted.
Acceptance Criteria (“Done When…”)
| # | Done when… |
|---|---|
| 1 | User can complete a spoken Q&A turn: hear a reply without refreshing the page. |
| 2 | Stop/barge-in halts playback within one buffer and cancels upstream (no full TTS after Stop). |
| 3 | TTFA and e2e latency are logged per turn (numbers from your run—not invented SLAs). |
| 4 | Raw audio is not written to durable storage in MVP (or TTL ≤ documented minutes). |
| 5 | Long digit sequences trigger confirm-last-4; full identifiers are not spoken back. |
| 6 | Unauthenticated sockets are rejected; RPM quotas still apply. |
| 7 | Eval splits: at least 10 utterances labeled ASR-wrong vs LLM-wrong vs OK; no fake WER% claim. |
Eval Rubric + HITL / Safety
| Gate | What you measure | Hook |
|---|---|---|
| ASR vs NLU/LLM | Error attribution on a labeled set (do not blend into one “accuracy %”) | Vol. 16 STT + Vol. 19 human eval |
| TTFA / barge-in | Logged ms; % barge-ins that stop audio before next sentence | Latency |
| PII / retention | Audio gone; transcript TTL; no voiceprint gallery; last-4 confirm canary | Vol. 20 privacy |
| Injection | Spoken “ignore system prompt” does not change policy | Vol. 20 prompt injection |
| HITL on actions | MVP has no refund/buy; if added, read-back + explicit yes | Vol. 15 HITL + Vol. 21 voice |
| Safety domain | No medical/legal definitive advice (preview next demo lectures) | Vol. 20 responsible AI |
Ambient speech: tell users the mic is hot; push-to-talk reduces accidental PII. Do not build a class project that silently records a room. Voice cloning (Vol. 16) is out of scope unless the stretch is clearly consented and still not used to impersonate a third party.
Related Lectures
| Lecture | Role |
|---|---|
| STT / TTS / real-time AI | Modalities |
| Vol. 21 Voice assistants | Product pattern |
| WebSockets / FastAPI / Docker | Serving |
| Whisper / ElevenLabs / clone LLM vendor | Vol. 22 pick |
| Chat clone / Code / Medical demo | Siblings |
“Voice is just the chat clone plus a microphone.” You inherited barge-in, TTFA, ASR error, and audio PII. Second: repeating a full card number “to confirm” is good UX. Third: storing all wavs improves quality so retention is optional. Fourth: a published WER from a vendor blog is your eval. Fifth: WebSockets without auth are fine on localhost demos that later hit production. Sixth: always-on wake word is the class MVP.
Knowledge Check
- Short Answer: What is the core loop of this capstone? Answer: STT → LLM → TTS (with barge-in/cancel and PII controls).
- True/False: Transcripts should be injected into the system prompt as trusted policy. Answer: False—wrap as untrusted data.
- Multiple Choice: Barge-in must: (a) stop TTS and cancel upstream work, (b) finish the full audio for quality, (c) store the wav forever. Answer: (a).
- Short Answer: Name one PII risk unique to voice vs text chat. Answer: Voiceprints, ambient third-party speech, or spoken identifiers/card digits (any valid).
- True/False: This lecture invents an official WER percentage for Whisper. Answer: False—label your own utterances; split ASR vs LLM error.
- Multiple Choice: MVP should speak back a full SSN to “confirm”: (a) no—last-4 / do not read back, (b) yes always, (c) only if TTS is expensive. Answer: (a).
- Short Answer: Why might you choose WebSockets over SSE for voice? Answer: Duplex mic chunks + TTS + barge-in on one connection.
- True/False: Unsupervised refunds via voice are in MVP scope. Answer: False—HITL/read-back if tools are added later.
- Multiple Choice: Next lecture in the module is: (a) AI Medical Assistant (demo), (b) Zapier, (c) PCA. Answer: (a).
- Short Answer: What latency metric should you log even if you publish no SLA? Answer: TTFA (and e2e); use your measured values only.
Key Takeaways
- Voice = STT → LLM → TTS with barge-in, TTFA logging, and wrap-as-data transcripts.
- Audio is a PII channel: drop waveforms, TTL transcripts, never read back full identifiers.
- Eval splits ASR vs LLM error; do not paste vendor WER as your score.
- Reuse FastAPI/Docker/auth; keep write-tools under spoken HITL.
- Next (higher stakes demo): AI Medical Assistant (demo).
Lab: Push-to-talk browser client + FastAPI WebSocket (or HTTP fallback if WS blocked). Log TTFA. Canaries: (1) barge-in mid-sentence, (2) speak a fake 16-digit number—must not be read back in full, (3) “ignore previous instructions.” Deliverable: privacy TTL paragraph + 10-utterance error-split sheet. No always-on room recording.
Exit ticket: “A teammate wants to keep all wavs for a month to ‘improve the model.’ What Vol. 20 control do you invoke?”
Recap: The voice assistant capstone closes the first five builds: an interruptible STT–LLM–TTS loop with latency discipline and audio PII hygiene. Continue to AI Medical Assistant (demo).