📊 Architektur: Die 5-Stufen-Pipeline
1
SIP-Anruf
PySIPio nimmt Anrufe via SIP an (z.B. Fritz!Box). Eingehendes Audio wird aufgezeichnet.
→
2
Whisper STT
OpenAI Whisper (lokal) transkribiert die Sprache des Anrufers in Text.
→
3
Ollama LLM
Ein lokales LLM (z.B. Llama 3) generiert die passende Antwort auf die Frage.
→
4
ElevenLabs TTS
Die Textantwort wird mit ElevenLabs in natürliche Sprache synthetisiert.
→
5
Audio-Antwort
Die generierte Sprachantwort wird über SIP an den Anrufer zurückgesendet.
💻 Echter Code aus dem Projekt
Klasse AudioAssistent – Initialisierung aller Komponenten
import whisper
from elevenlabs import generate, set_api_key
from PySIPio import SipAccount, SipCall
import sounddevice as sd
import asyncio, wave, configparser
class AudioAssistent:
def __init__(self, config_file='config.ini'):
self.config = configparser.ConfigParser()
self.config.read(config_file)
# ElevenLabs API-Key setzen
set_api_key(self.config['ElevenLabs']['api_key'])
# Whisper-Modell laden (lokal)
self.whisper_model = whisper.load_model("base")
# Audio-Parameter
self.sample_rate = int(self.config['Audio']['sample_rate'])
self.channels = int(self.config['Audio']['channels'])
SIP-Registrierung an der Fritz!Box
async def setup_sip(self):
self.sip_account = SipAccount(
username=self.config['SIP']['username'],
password=self.config['SIP']['password'],
domain=self.config['SIP']['domain'],
port=int(self.config['SIP']['port']))
@self.sip_account.on_registered
def on_registered():
self.logger.info("SIP-Konto registriert")
await self.sip_account.register()
Gesprächslogik: Whisper → Ollama → ElevenLabs
async def handle_incoming_call(self, call: SipCall):
await call.accept()
# 1. Audio aufnehmen
audio_data = sd.rec(duration * sample_rate, ...)
# 2. Whisper-Transkription
user_text = self.whisper_model.transcribe(audio_path)["text"]
# 3. Ollama-Antwort
response = requests.post(ollama_url, json={
"model": "llama3", "prompt": user_text})
assistant_text = response.json()["response"]
# 4. ElevenLabs Sprachsynthese
audio_out = generate(text=assistant_text,
voice=self.config['ElevenLabs']['voice'])
# 5. Audio zurücksenden
await call.send_audio(audio_out)
Gesprächsverlauf – vollständig archiviert
# Zeitstempel-Verzeichnis pro Anruf
timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
call_dir = f"{config['Storage']['conversation_dir']}/{timestamp}"
os.makedirs(call_dir, exist_ok=True)
# Transkript + beide Audio-Dateien speichern
# transcript.txt, caller.wav, assistant.wav
🎯 Business Value
100% lokal
Whisper + Ollama laufen lokal – Anrufdaten verlassen nie den Server. DSGVO-konform ohne Cloud.
Kostenkontrolle
Nur ElevenLabs TTS kostet (pro Zeichen). Ollama und Whisper sind kostenlos und unlimitiert.
24/7 Erreichbarkeit
Automatisierte Telefonannahme – kein verpasster Anruf, keine Warteschleife.