0Pricing
AI Agents · Lektion

Eine Sprachkonversationsschleife erstellen

Zyklus aus Aufnehmen → Transkribieren → Schlussfolgern → Sprechen mit Unterbrechungsbehandlung.

Eine Sprachkonversationsschleife erstellen ist eine kostenlose AI Agents-Lektion auf CoddyKit. Dies ist Lektion 3 von 4. Du kannst die komplette Lektion unten kostenlos lesen – dann übst du sie direkt im Browser mit einem integrierten Code-Editor und einem KI-Tutor rund um die Uhr. Sie ist Teil des AI Agents-Lernpfads, und dein Fortschritt wird über Web und CoddyKit-App synchronisiert. Der AI Agents-Kurs umfasst insgesamt 4 Lektionen.

Die Sprachkonversationsschleife

Eine vollständige Sprachkonversationsschleife verbindet Mikrofoneingabe und Agentenausgabe in einem kontinuierlichen Zyklus: aufnehmen → transkribieren → Agent → TTS → abspielen → wiederholen.

Diese Lektion behandelt jede Komponente und die Herausforderungen, die Sprachschleifen von textbasierten Agenten unterscheiden: Stilleerkennung, Unterbrechungsbehandlung und Erkennung des Sprechendes.

Vom Mikrofon aufnehmen

Verwenden Sie sounddevice, um Audio vom Standardmikrofon aufzunehmen. Nehmen Sie entweder für eine feste Dauer auf oder bis Stille erkannt wird. Nehmen Sie immer in Mono mit 16 kHz auf – das ist die von Whisper erwartete Abtastrate.

Installieren Sie es mit pip install sounddevice soundfile numpy.

import sounddevice as sd
import numpy as np
import tempfile
import soundfile as sf

SAMPLE_RATE = 16000  # 16kHz mono — optimal for Whisper
DURATION = 5         # seconds

def record_audio(duration=DURATION, sample_rate=SAMPLE_RATE):
    print(f'Recording for {duration} seconds...')
    audio_data = sd.rec(
        int(duration * sample_rate),
        samplerate=sample_rate,
        channels=1,
        dtype='float32'
    )
    sd.wait()  # block until recording finishes
    print('Recording complete')
    return audio_data, sample_rate

def audio_to_file(audio_data, sample_rate, filepath='/tmp/recording.wav'):
    sf.write(filepath, audio_data, sample_rate)
    return filepath

Stilleerkennung für das Sprechende

Eine Aufnahme über eine feste Dauer ist unpraktisch: Benutzer müssen warten, selbst wenn sie nach 2 Sekunden fertig gesprochen haben. Die Stilleerkennung beendet die Aufnahme automatisch, wenn der Benutzer eine bestimmte Zeitspanne lang still war.

import sounddevice as sd
import numpy as np
from collections import deque

SAMPLE_RATE = 16000
CHUNK_SIZE = 1024         # samples per chunk
SILENCE_THRESHOLD = 0.02  # RMS volume below this = silence
SILENCE_DURATION = 1.5   # seconds of silence to end recording
MAX_DURATION = 30         # max recording length in seconds

def record_until_silence():
    chunks = []
    silent_chunks = 0
    max_silent = int(SILENCE_DURATION * SAMPLE_RATE / CHUNK_SIZE)
    max_chunks = int(MAX_DURATION * SAMPLE_RATE / CHUNK_SIZE)

    print('Listening... (speak now)')
    with sd.InputStream(samplerate=SAMPLE_RATE, channels=1,
                        blocksize=CHUNK_SIZE, dtype='float32') as stream:
        while True:
            chunk, _ = stream.read(CHUNK_SIZE)
            chunks.append(chunk.copy())

            rms = np.sqrt(np.mean(chunk**2))
            if rms < SILENCE_THRESHOLD:
                silent_chunks += 1
            else:
                silent_chunks = 0  # speech detected — reset counter

            if silent_chunks >= max_silent and len(chunks) > max_silent:
                break
            if len(chunks) >= max_chunks:
                break

    audio = np.concatenate(chunks, axis=0)
    return audio, SAMPLE_RATE

Die vollständige Sprachschleife

Verbinden Sie alle Komponenten zu einer kontinuierlichen Schleife. Starten Sie nach der Antwort des Agenten sofort wieder die Aufnahme, um ein natürliches Gespräch mit abwechselnden Sprechbeiträgen zu ermöglichen.

import openai
import os

client = openai.OpenAI(api_key=os.getenv('OPENAI_API_KEY'))

conversation_history = []

def voice_conversation_loop():
    print('Voice agent started. Say something (Ctrl+C to exit).')

    while True:
        # 1. Record user
        audio_data, sample_rate = record_until_silence()
        audio_path = audio_to_file(audio_data, sample_rate)

        # 2. Transcribe
        user_text = transcribe_file(audio_path)
        print(f'You: {user_text}')

        if not user_text.strip():
            continue  # empty — listen again

        # 3. Run agent
        conversation_history.append({'role': 'user', 'content': user_text})
        response = client.chat.completions.create(
            model='gpt-4o-mini',
            messages=[{'role': 'system', 'content': 'You are a helpful voice assistant. Keep responses concise.'}] + conversation_history[-10:]
        )
        agent_text = response.choices[0].message.content
        conversation_history.append({'role': 'assistant', 'content': agent_text})
        print(f'Agent: {agent_text}')

        # 4. TTS and play
        say(agent_text)  # speaks sentence by sentence

Konzept der Weckworterkennung

Ständiges Zuhören ist teuer (kontinuierliche Whisper-Aufrufe) und greift in die Privatsphäre ein. Die Weckworterkennung führt ein leichtgewichtiges lokales Modell aus, das die vollständige Verarbeitung nur dann auslöst, wenn eine bestimmte Phrase gehört wird (z. B. 'Hey Agent').

# Wake word detection with pvporcupine (Picovoice)
# pip install pvporcupine sounddevice

import pvporcupine
import sounddevice as sd
import numpy as np
import os

def listen_for_wake_word(wake_word='computer'):
    porcupine = pvporcupine.create(
        access_key=os.getenv('PICOVOICE_KEY'),
        keywords=[wake_word]  # built-in: computer, hey barista, hey google, jarvis...
    )

    print(f'Listening for wake word: "{wake_word}"...')

    with sd.InputStream(
        samplerate=porcupine.sample_rate,
        channels=1,
        dtype='int16',
        blocksize=porcupine.frame_length
    ) as stream:
        while True:
            frame, _ = stream.read(porcupine.frame_length)
            pcm = frame.flatten().astype('int16')
            result = porcupine.process(pcm)
            if result >= 0:
                print(f'Wake word detected!')
                porcupine.delete()
                return True

Unterbrechungsbehandlung

Benutzer sollten den Agenten während des Sprechens unterbrechen können. Implementieren Sie die Unterbrechungsbehandlung, indem Sie die Wiedergabe in einem separaten Thread ausführen und die Mikrofonlautstärke überwachen. Sobald der Benutzer zu sprechen beginnt, stoppen Sie die Wiedergabe sofort.

import threading
import sounddevice as sd
import numpy as np

interrupt_event = threading.Event()

def monitor_for_interrupt(threshold=0.03):
    def audio_callback(indata, frames, time_info, status):
        rms = np.sqrt(np.mean(indata**2))
        if rms > threshold:
            print('Interrupt detected!')
            interrupt_event.set()

    with sd.InputStream(callback=audio_callback, channels=1,
                        samplerate=16000, blocksize=1024):
        while not interrupt_event.is_set():
            sd.sleep(50)

def speak_with_interrupt(text, voice='nova'):
    interrupt_event.clear()

    # Start interrupt monitor in background
    monitor_thread = threading.Thread(target=monitor_for_interrupt, daemon=True)
    monitor_thread.start()

    # Play audio sentence by sentence
    for sentence in split_into_sentences(text):
        if interrupt_event.is_set():
            print('Playback interrupted')
            break
        audio_path = cached_tts(sentence, voice)
        play_audio_file(audio_path)

Rauschfilterung

Mikrofonaufnahmen enthalten häufig Hintergrundgeräusche: Lüfter, Tastaturklicks und Raumhall. Wenden Sie ein einfaches Noise Gate an, um Audio unterhalb eines Schwellenwerts zu unterdrücken, und verwenden Sie optional einen Sprachaktivitätsdetektor (VAD), um die Genauigkeit zu verbessern.

import numpy as np

NOISE_GATE_THRESHOLD = 0.015  # RMS threshold

def apply_noise_gate(audio_data, threshold=NOISE_GATE_THRESHOLD):
    rms = np.sqrt(np.mean(audio_data**2))
    if rms < threshold:
        return np.zeros_like(audio_data)  # silence below threshold
    return audio_data

def has_speech_content(audio_data, threshold=0.02):
    rms_values = [
        np.sqrt(np.mean(audio_data[i:i+1600]**2))
        for i in range(0, len(audio_data), 1600)
    ]
    speech_frames = sum(1 for r in rms_values if r > threshold)
    speech_ratio = speech_frames / max(len(rms_values), 1)
    return speech_ratio > 0.1  # at least 10% of frames have speech

# Use in loop before transcribing
audio, sr = record_until_silence()
if has_speech_content(audio):
    text = transcribe_file(audio_to_file(audio, sr))
else:
    print('No speech detected — listening again')

Zustandsautomat für die Konversationsschleife

Eine robuste Sprachschleife verwendet einen Zustandsautomaten, um jederzeit zu verfolgen, was der Agent gerade tut, und Race Conditions zwischen Wiedergabe und Zuhören zu verhindern.

from enum import Enum

class AgentState(Enum):
    IDLE           = 'idle'
    LISTENING      = 'listening'
    TRANSCRIBING   = 'transcribing'
    THINKING       = 'thinking'
    SPEAKING       = 'speaking'

current_state = AgentState.IDLE

def set_state(new_state):
    global current_state
    print(f'State: {current_state.value} -> {new_state.value}')
    current_state = new_state

def voice_loop_with_state():
    while True:
        set_state(AgentState.LISTENING)
        audio, sr = record_until_silence()

        if not has_speech_content(audio):
            continue

        set_state(AgentState.TRANSCRIBING)
        text = transcribe_file(audio_to_file(audio, sr))
        if not text.strip():
            continue
        print(f'You: {text}')

        set_state(AgentState.THINKING)
        agent_response = run_agent(text)
        print(f'Agent: {agent_response}')

        set_state(AgentState.SPEAKING)
        speak_with_interrupt(agent_response)

Verwaltung des Konversationskontexts

Der Sprachagent speichert den Gesprächsverlauf, damit er Anschlussfragen wie "Erzählen Sie mir mehr darüber" oder "Welchen Preis hatten Sie noch einmal genannt?" beantworten kann. Bewahren Sie den Verlauf im Arbeitsspeicher auf und beschränken Sie ihn auf die letzten N Gesprächsrunden, um einen Überlauf des Kontexts zu vermeiden.

import openai
import os

client = openai.OpenAI(api_key=os.getenv('OPENAI_API_KEY'))

MAX_HISTORY_TURNS = 10
SYSTEM_PROMPT = 'You are a concise voice assistant. Keep responses under 3 sentences unless asked for detail.'

class VoiceAgent:
    def __init__(self):
        self.history = []

    def respond(self, user_text):
        self.history.append({'role': 'user', 'content': user_text})

        # Trim history to last N turns
        recent = self.history[-(MAX_HISTORY_TURNS * 2):]

        response = client.chat.completions.create(
            model='gpt-4o-mini',
            messages=[{'role': 'system', 'content': SYSTEM_PROMPT}] + recent
        )
        agent_text = response.choices[0].message.content
        self.history.append({'role': 'assistant', 'content': agent_text})
        return agent_text

    def reset(self):
        self.history = []
        print('Conversation history cleared')

Geordnetes Beenden und Aufräumen

Behandeln Sie Ctrl+C und andere Beendigungssignale ordnungsgemäß: Stoppen Sie den Audiostream, bereinigen Sie temporäre Dateien und verabschieden Sie sich, bevor Sie das Programm beenden.

import signal
import sys
import glob
import os

TMP_DIR = '/tmp'
agent = None

def cleanup_temp_files():
    for f in glob.glob(os.path.join(TMP_DIR, 'recording_*.wav')):
        os.unlink(f)
    print('Temp files cleaned up')

def graceful_shutdown(signum, frame):
    print('\nShutting down voice agent...')
    if agent:
        say('Goodbye! Have a great day.')
    cleanup_temp_files()
    sys.exit(0)

# Register signal handler
signal.signal(signal.SIGINT, graceful_shutdown)
signal.signal(signal.SIGTERM, graceful_shutdown)

# Main entry point
agent = VoiceAgent()
print('Voice agent ready. Press Ctrl+C to exit.')
voice_loop_with_state()

Konversation protokollieren

Führen Sie ein dauerhaftes Protokoll der Konversation: Zeitstempel, transkribierter Text, Antworten des Agenten und etwaige Fehler. Das ist für die Fehlersuche bei Problemen mit Sprachagenten und für die Entwicklung von Funktionen zur Konversationsüberprüfung unerlässlich.

import json
import os
from datetime import datetime

LOG_DIR = '/tmp/voice_agent_logs'
os.makedirs(LOG_DIR, exist_ok=True)

conversation_log = []

def log_turn(speaker, text, latency_ms=None, error=None):
    entry = {
        'timestamp': datetime.now().isoformat(),
        'speaker': speaker,   # 'user' or 'agent'
        'text': text,
        'latency_ms': latency_ms
    }
    if error:
        entry['error'] = error
    conversation_log.append(entry)

def save_conversation_log(session_id=None):
    if not session_id:
        session_id = datetime.now().strftime('%Y%m%d_%H%M%S')
    log_path = os.path.join(LOG_DIR, f'session_{session_id}.json')
    with open(log_path, 'w') as f:
        json.dump({
            'session_id': session_id,
            'turns': len(conversation_log),
            'log': conversation_log
        }, f, indent=2)
    print(f'Log saved: {log_path}')
    return log_path

# Usage in voice loop
log_turn('user', transcribed_text, latency_ms=420)
log_turn('agent', agent_response, latency_ms=850)

Wissensüberprüfung

Welchen Zweck hat die Stilleerkennung in einer Sprachkonversationsschleife?

Zusammenfassung: Eine Sprachkonversationsschleife erstellen

Eine Sprachkonversationsschleife: mit Stilleerkennung über das Mikrofon aufnehmen → mit Whisper transkribieren → den Agenten mit Konversationsverlauf ausführen → TTS-Antwort Satz für Satz erzeugen → mit Überwachung auf Unterbrechungen abspielen → wiederholen.

Wichtige Komponenten sind ein Zustandsautomat zur Vermeidung von Race Conditions, Weckworterkennung für ständiges Zuhören, ein Noise Gate für die Audioqualität und die Kürzung des Konversationsverlaufs zur Kontextverwaltung. Behandeln Sie Ctrl+C ordnungsgemäß und führen Sie eine Bereinigung sowie eine Abschiedsnachricht aus.

Häufig gestellte Fragen

Ist die Lektion „Eine Sprachkonversationsschleife erstellen“ kostenlos?

Ja — der vollständige Text von „Eine Sprachkonversationsschleife erstellen“ ist hier im Web kostenlos zu lesen. Um sie interaktiv zu üben (integrierter Code-Editor und 24/7 KI-Tutor) und den Rest des AI Agents-Kurses freizuschalten, upgrade auf CoddyKit PRO. Der AI Agents-Kurs umfasst insgesamt 4 Lektionen.

Was lerne ich in „Eine Sprachkonversationsschleife erstellen“?

Zyklus aus Aufnehmen → Transkribieren → Schlussfolgern → Sprechen mit Unterbrechungsbehandlung. Du übst AI Agents mit praktischem Code, den du direkt im Browser ausführst, und ein 24/7 KI-Tutor beantwortet deine Fragen während du die Lektion bearbeitest.

Brauche ich Erfahrung, um AI Agents zu starten?

Keine Vorkenntnisse erforderlich. AI Agents auf CoddyKit ist für Anfänger bis fortgeschrittene Lernende strukturiert, sodass du hier starten oder von Anfang an beginnen und in deinem eigenen Tempo voranschreiten kannst. Dies ist Lektion 3 von 4.

Wie lange dauert die Lektion „Eine Sprachkonversationsschleife erstellen“?

Die meisten CoddyKit-Lektionen dauern etwa 5–10 Minuten. Jede ist kompakt und interaktiv, sodass du stetig Fortschritte machst und genau dort weitermachst, wo du aufgehört hast – im Web und in der App.

Kann ich in dieser AI Agents-Lektion Code schreiben und ausführen?

Ja. Jede AI Agents-Lektion enthält einen integrierten Code-Editor, sodass du echten Code direkt in deinem Browser schreibst und ausführst und sofort KI-Feedback erhältst — ohne lokale Einrichtung erforderlich.

Alle Lektionen in diesem Kurs

  1. Speech-to-Text mit Whisper und Deepgram
  2. Text-to-Speech in Agentenantworten
  3. Eine Sprachkonversationsschleife erstellen
  4. Latenzoptimierung für Sprachagenten
← Zurück zu AI Agents