This project creates two conversational AI avatars for political science education:
- Alexis de Tocqueville, grounded in Democracy in America
- Immanuel Kant, grounded in Fundamental Principles of the Metaphysic of Morals and Perpetual Peace
You speak to an avatar through your microphone. The application transcribes the question, retrieves relevant passages from that thinker's books, generates a response with a local Mistral model, speaks it aloud, and animates the avatar. The avatars can also be shown in Zoom or Google Meet through OBS.
This guide assumes no previous Python or AI experience. Follow the sections in order.
Your microphone
-> faster-whisper speech recognition
-> ChromaDB passage retrieval
-> Ollama + Mistral response generation
-> Piper text-to-speech
-> animated PyQt5 avatar
-> optional OBS Virtual Camera for Zoom or Google Meet
The standard setup is local-first. It does not require a paid API key.
You need:
- A computer with a microphone and speakers.
- An internet connection for the first installation and model downloads.
- Approximately 8–12 GB of free disk space.
- Python 3.11.
- Git.
- Ollama.
The first launch is slower because the application downloads its embedding, speech-recognition, and voice models. Later launches use the local copies.
Install Homebrew from brew.sh if it is not already installed. Then open Terminal and run:
brew install python@3.11 git portaudio libsndfile
brew install --cask ollamaStart the Ollama application once from Applications, or run ollama serve in a Terminal window.
When macOS asks, allow Terminal or Python to use the microphone.
Install:
- Python 3.11. During installation, select Add Python to PATH.
- Git for Windows.
- Ollama for Windows.
Use PowerShell for the Windows commands in this guide. Start Ollama from the Start menu before continuing.
Install Python, Git, PortAudio, libsndfile, and common Qt runtime libraries. On Ubuntu or Debian:
sudo apt update
sudo apt install python3 python3-venv python3-pip git portaudio19-dev libsndfile1 ffmpeg \
libegl1 libxkbcommon-x11-0 libxcb-xinerama0Confirm that python3 --version reports Python 3.11. Install Ollama using the instructions at ollama.com/download/linux, then start it:
ollama serveLinux ARM systems may not have a compatible PyQt5 wheel. Linux x86-64 is the supported Linux target for the desktop avatar.
Open Terminal on macOS/Linux or PowerShell on Windows.
git clone https://github.com/shahtirth07/zoom-avatar.git
cd zoom-avatarAll commands below must be run from the zoom-avatar directory.
A virtual environment keeps this project's packages separate from the rest of your computer.
python3.11 -m venv venv
source venv/bin/activateIf python3.11 is not recognized but python3 --version reports 3.11, use:
python3 -m venv venv
source venv/bin/activatepy -3.11 -m venv venv
.\venv\Scripts\Activate.ps1If PowerShell blocks the activation script, run this once in the same window and try again:
Set-ExecutionPolicy -Scope Process -ExecutionPolicy BypassWhen activation succeeds, the command prompt begins with (venv).
Run this on every platform:
python -m pip install --upgrade pip
python -m pip install -r requirements.txtInstallation can take several minutes. It installs the desktop interface, vector database, speech recognition, text-to-speech, and meeting-related Python packages.
For automated Google Meet browser launch, also install Chromium:
python -m playwright install chromiumLinux may additionally require:
python -m playwright install-deps chromiumThe example configuration uses local Ollama, local embeddings, and local Piper speech.
cp .env.example .envCopy-Item .env.example .envNo API key is needed for the standard setup. Do not place real keys in .env.example, and never commit your personal .env file.
The important defaults in .env are:
LLM_PROVIDER=ollama
OLLAMA_MODEL=mistral
EMBEDDINGS_PROVIDER=local
TTS_PROVIDER=piper
WHISPER_MODEL=baseMake sure Ollama is running, then run:
ollama pull mistralVerify the installation:
ollama listYou should see mistral in the output.
The raw books are included in data/raw/. This command cleans the texts, divides them into passages, creates embeddings, and stores them in vectordb/:
python -m src.ingest.build_corpusThe first build downloads all-MiniLM-L6-v2 and can take several minutes. A successful build reports:
tocqueville=394
kant=180
Kant's 180 passages consist of 66 passages from Fundamental Principles of the Metaphysic of Morals and 114 from Perpetual Peace.
The build is safe to run again. It synchronizes the collections instead of adding duplicate passages.
Run:
python -m src.cli doctorResolve any line marked FAIL before continuing. In particular:
- If Ollama fails, start Ollama and rerun
ollama pull mistral. - If
.envfails, repeat Step 4. - If a package fails, reactivate
venvand repeat Step 3.
Make sure the virtual environment is active and run:
python -m src.cli startThis starts the FastAPI server in the background and opens the avatar interface.
Try:
- “Hey Alexis, what is the tyranny of the majority?”
- “Hey Kant, what is the categorical imperative?”
Allow microphone access if your operating system asks. Stop the foreground avatar with Ctrl+C.
To stop the background server:
python -m src.cli stopOther useful commands:
python -m src.cli status # Show Ollama and server status
python -m src.cli server # Start only the API server
python -m src.cli voice # Start server plus voice/avatar interfaceOn macOS and Linux, ./run.sh start, ./run.sh status, and ./run.sh stop may also be used. The python -m src.cli ... commands are preferred because they work consistently across macOS, Linux, and Windows.
The application works without Rhubarb, but mouth shapes will be less precise.
Download Rhubarb Lip Sync from its release page. Put the executable somewhere on your PATH, or set its full path in .env:
RHUBARB_PATH=/full/path/to/rhubarb
ENABLE_LIP_SYNC=trueTo run without Rhubarb:
ENABLE_LIP_SYNC=falsePiper voice models are downloaded automatically into models/piper/ on first use. If Piper cannot load, the application falls back to the operating system's pyttsx3 voice.
The dependable meeting workflow is to capture the avatar window with OBS and send it to the meeting as a virtual camera. The Python meeting commands prepare the avatar application; OBS and audio routing are still configured manually.
Current limitations:
- The project does not automatically create two independent Zoom participants.
- Zoom's
--use-sdkpath is incomplete. - Google Meet Media API output is incomplete.
- Remote meeting speech is not automatically routed into the avatar's speech recognizer.
- Browser and direct virtual-camera modes are experimental.
Install:
In Audio MIDI Setup, create a Multi-Output Device containing your speakers and BlackHole. This lets you hear the avatar while the meeting receives its audio.
Install:
Route the avatar's output to the virtual cable and select that cable as the meeting microphone.
Install OBS and the virtual-camera backend:
sudo apt install obs-studio v4l2loopback-dkmsCreate a virtual audio sink/source using PipeWire or PulseAudio. Configuration varies by Linux distribution.
-
Start the avatar meeting mode:
python -m src.cli meeting
-
Open OBS.
-
Add a Window Capture source and select the avatar window.
-
Click Start Virtual Camera in OBS.
-
Join Zoom or Google Meet normally.
-
Select OBS Virtual Camera as the meeting camera.
-
Select BlackHole, VB-CABLE/VoiceMeeter, or your Linux virtual source as the meeting microphone.
-
Say “Hey Alexis” or “Hey Kant” near the computer's physical microphone.
python -m src.cli zoom-meeting MEETING_IDFor a meeting password:
python -m src.cli zoom-meeting MEETING_ID --password PASSWORDThis starts both avatars and prints/manual-guides the Zoom setup. It does not itself transmit two native Zoom participant streams. Join the meeting in the Zoom desktop client and use the OBS workflow above.
With OBS:
python -m src.cli google-meet abc-defg-hijExperimental browser launch without OBS:
python -m src.cli google-meet abc-defg-hij --no-obs --name "Philosophy Avatar"The no-OBS path launches Playwright Chromium and attempts to expose the first avatar through pyvirtualcam. A supported virtual-camera backend is still required, and the meeting host may need to admit the browser participant.
Start the server:
python -m src.cli serverOpen http://localhost:8000/docs to use FastAPI's interactive documentation.
Example request:
curl -X POST http://localhost:8000/ask \
-H "Content-Type: application/json" \
-d '{"query":"What protects liberty in a democracy?","persona":{"key":"tocqueville"}}'Use "key":"kant" to ask Kant.
Edit .env to change providers or models.
LLM_PROVIDER=openai
OPENAI_API_KEY=your_key_here
OPENAI_MODEL=gpt-4LLM_PROVIDER=anthropic
ANTHROPIC_API_KEY=your_key_here
ANTHROPIC_MODEL=claude-3-opus-20240229If transcription is slow:
WHISPER_MODEL=tinyThe base model provides a better default accuracy/speed balance.
Reinstall Python 3.11 and ensure it is added to PATH. Close and reopen Terminal or PowerShell afterward.
Activate it again:
# macOS/Linux
source venv/bin/activate# Windows
.\venv\Scripts\Activate.ps1Start Ollama:
ollama serveIn another window:
ollama pull mistralReactivate the virtual environment and run:
python -m pip install -r requirements.txtRebuild:
python -m src.ingest.build_corpus- Allow microphone access for Terminal, PowerShell, or Python.
- Confirm the correct microphone is selected as your system input.
- Speak close to the microphone.
- Close another application if it has exclusive control of the microphone.
- Confirm speakers/headphones are selected as the system output.
- Rerun the app while connected to the internet so Piper can download its model.
- The system will attempt to use
pyttsx3if Piper fails.
Install the Qt runtime packages listed in the Linux prerequisites. The application requires a graphical desktop and will not run in a headless SSH terminal.
Run:
python -m playwright install chromiumOn Linux also run:
python -m playwright install-deps chromium- Start OBS Virtual Camera before opening the meeting's device settings.
- Restart Zoom or the browser after installing OBS.
- On macOS, approve the OBS camera extension in System Settings.
- On Linux, confirm
v4l2loopbackis loaded.
The background server writes errors to:
server.log
zoom-avatar/
├── README.md
├── requirements.txt
├── .env.example
├── data/raw/ # Tracked primary-source books
├── data/processed/ # Generated cleaned texts
├── vectordb/ # Generated ChromaDB collections
├── avatar/frames/ # Tocqueville and Kant visuals
├── avatar/videos/ # Optional pre-rendered clips
├── models/piper/ # Downloaded voice models
├── src/cli.py # Cross-platform launcher
├── src/voice_interaction.py # Main voice/avatar loop
├── src/avatar_window.py # Desktop avatar interface
├── src/ingest/ # Corpus preprocessing and embedding
├── src/rag/ # Retrieval, prompts, and LLM calls
├── src/server/ # FastAPI backend
└── src/meeting_platforms/ # Zoom and Google Meet helpers
- Embedding model:
all-MiniLM-L6-v2 - Chunking: sentence-boundary groups of approximately 500 words
- Chunk overlap: none
- Normal Q&A retrieval: top 2 passages
- Debate retrieval: top 3 passages
- Tocqueville collection: 394 passages
- Kant collection: 180 passages
After the first installation, you do not repeat all setup steps.
cd zoom-avatar
source venv/bin/activate
python -m src.cli startcd zoom-avatar
.\venv\Scripts\Activate.ps1
python -m src.cli startWhen finished:
python -m src.cli stop