Optimasi Latensi untuk Agen Suara
TTS streaming, pemecahan respons, dan minimisasi latensi kata pertama.
Optimasi Latensi untuk Agen Suara adalah pelajaran AI Agents gratis di CoddyKit. Ini adalah pelajaran 4 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar AI Agents, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus AI Agents mencakup 4 pelajaran total.
Mengapa Latensi Penting untuk Suara
Dalam percakapan teks, jeda 3 detik masih dapat diterima. Dalam percakapan suara, jeda lebih dari 1,5 detik terasa tidak alami dan mengganggu alur percakapan.
Latensi suara memiliki tiga komponen utama: waktu transkripsi (STT), waktu pemrosesan LLM (TTFT + pembuatan), dan waktu sintesis TTS. Mengoptimalkan setiap komponen akan menghasilkan peningkatan pengalaman pengguna yang jauh lebih baik.
Mengukur Anggaran Latensi
Sebelum melakukan pengoptimalan, ukur setiap komponen. Tambahkan pemanggilan pengukuran waktu ke dalam siklus agar Anda mengetahui bagian yang benar-benar menghabiskan waktu.
import time
def voice_loop_timed():
timing = {}
# 1. Record
t0 = time.perf_counter()
audio, sr = record_until_silence()
timing['record'] = time.perf_counter() - t0
# 2. Transcribe
t0 = time.perf_counter()
audio_path = audio_to_file(audio, sr)
user_text = transcribe_file(audio_path)
timing['transcription'] = time.perf_counter() - t0
# 3. LLM
t0 = time.perf_counter()
agent_text = agent.respond(user_text)
timing['llm'] = time.perf_counter() - t0
# 4. TTS
t0 = time.perf_counter()
say(agent_text)
timing['tts'] = time.perf_counter() - t0
print('Latency breakdown:')
total = sum(timing.values())
for step, duration in timing.items():
print(f' {step:15} {duration*1000:.0f}ms ({duration/total*100:.0f}%)')TTS melalui Penstriman: Putar Sambil Membuat Audio
Peningkatan latensi tunggal terbesar berasal dari TTS melalui penstriman. Alih-alih menunggu seluruh audio selesai disintesis, mulai putar bagian audio pertama dalam waktu sekitar 200ms sementara bagian lainnya dibuat secara bersamaan.
import threading
import queue
import sounddevice as sd
import numpy as np
import io
def stream_tts_and_play(text, voice='nova'):
audio_queue = queue.Queue()
def synthesize():
from openai import OpenAI
import os
client = OpenAI(api_key=os.getenv('OPENAI_API_KEY'))
with client.audio.speech.with_streaming_response.create(
model='tts-1', voice=voice, input=text
) as response:
for chunk in response.iter_bytes(chunk_size=4096):
audio_queue.put(chunk)
audio_queue.put(None) # sentinel
synth_thread = threading.Thread(target=synthesize, daemon=True)
synth_thread.start()
# Collect and play (buffering first 2 chunks for smooth start)
audio_buffer = b''
min_buffer = 8192
import pygame
pygame.mixer.init()
while True:
chunk = audio_queue.get()
if chunk is None:
break
audio_buffer += chunk
if len(audio_buffer) >= min_buffer:
# play buffer ...
pass # simplified — real impl streams to sounddevice
synth_thread.join()TTS melalui Penstriman per Kalimat
Pendekatan penstriman yang paling praktis: bagi respons LLM menjadi beberapa kalimat, lalu sintesis dan putar setiap kalimat satu per satu. Kalimat pertama mulai diputar dalam waktu sekitar 300ms.
import re
import concurrent.futures
def split_sentences(text):
return [s.strip() for s in re.split(r'(?<=[.!?])\s+', text) if s.strip()]
def tts_and_play_streaming(text, voice='nova'):
sentences = split_sentences(text)
if not sentences:
return
# Prefetch next sentence while current is playing
executor = concurrent.futures.ThreadPoolExecutor(max_workers=2)
# Kick off synthesis of first sentence
futures = []
for sentence in sentences:
futures.append(executor.submit(cached_tts, sentence, voice))
# Play each sentence as soon as it's ready
for future in futures:
audio_path = future.result(timeout=10)
play_audio_file(audio_path)
executor.shutdown(wait=False)
# Key insight: while sentence 1 plays (~2 seconds), sentence 2 is being synthesized in parallelTTFT: Pengoptimalan Waktu ke Token Pertama
TTFT (Time to First Token) adalah jeda antara pengiriman permintaan LLM dan penerimaan token pertama respons. Mengoptimalkan TTFT berarti pengguna dapat mendengar awal jawaban lebih cepat.
Gunakan respons LLM melalui penstriman dan alirkan token ke TTS segera setelah batas kalimat terdeteksi.
import openai
import os
client = openai.OpenAI(api_key=os.getenv('OPENAI_API_KEY'))
def stream_llm_to_tts(user_text, conversation_history, voice='nova'):
buffer = ''
stream = client.chat.completions.create(
model='gpt-4o-mini',
messages=conversation_history + [{'role': 'user', 'content': user_text}],
stream=True # streaming enabled
)
for chunk in stream:
delta = chunk.choices[0].delta.content or ''
buffer += delta
# Check if a sentence is complete
if buffer.endswith(('.', '!', '?')) and len(buffer) > 20:
sentence = buffer.strip()
print(f'Queuing TTS: {sentence[:50]}')
# Synthesize and play immediately (non-blocking)
audio_path = cached_tts(sentence, voice)
play_audio_file(audio_path)
buffer = ''
# Flush remaining buffer
if buffer.strip():
audio_path = cached_tts(buffer.strip(), voice)
play_audio_file(audio_path)Membuat Respons Umum Terlebih Dahulu
Beberapa respons agen dapat diprediksi: salam, pesan kesalahan, dan indikator sedang berpikir ("Biar saya memeriksanya untuk Anda."). Buat audio-nya terlebih dahulu saat sistem dimulai agar dapat diputar seketika tanpa latensi.
import os
PRE_GENERATED = {
'greeting': 'Hello! How can I help you today?',
'thinking': 'Let me look that up for you.',
'not_found': 'I could not find information on that. Could you rephrase?',
'error': 'Sorry, something went wrong. Please try again.',
'goodbye': 'Goodbye! Have a great day.',
'clarify': 'Could you give me a bit more detail?',
'working_on_it': 'Working on it, this may take a moment.'
}
pre_gen_cache = {}
def prewarm_responses(voice='nova'):
for key, text in PRE_GENERATED.items():
audio_path = cached_tts(text, voice=voice)
pre_gen_cache[key] = audio_path
print(f'Pre-generated {len(pre_gen_cache)} common responses')
def instant_response(key):
path = pre_gen_cache.get(key)
if path:
play_audio_file(path)
else:
say(PRE_GENERATED.get(key, ''))
# Usage: while LLM is thinking, play a stall message instantly
instant_response('thinking')Latensi TTS Lokal dibandingkan TTS Awan
TTS awan menambahkan waktu perjalanan pulang-pergi jaringan (sekitar 100–300ms). Untuk respons singkat atau frasa yang sering digunakan, mesin TTS lokal dapat lebih cepat—dengan mengorbankan kualitas suara.
pyttsx3 adalah TTS luring paling sederhana untuk Python.
import pyttsx3
import time
# Local TTS with pyttsx3
def local_tts(text, voice_index=0, rate=175):
engine = pyttsx3.init()
voices = engine.getProperty('voices')
if voice_index < len(voices):
engine.setProperty('voice', voices[voice_index].id)
engine.setProperty('rate', rate) # words per minute
t0 = time.perf_counter()
engine.say(text)
engine.runAndWait()
print(f'Local TTS latency: {(time.perf_counter()-t0)*1000:.0f}ms')
# Comparison (rough benchmarks):
# pyttsx3 (local): ~50ms start, robotic quality
# OpenAI TTS-1: ~200-400ms, good quality
# ElevenLabs turbo: ~150-250ms, excellent quality
# OpenAI TTS-1-hd: ~400-800ms, best quality
# Recommendation:
# Real-time voice agent -> OpenAI TTS-1 or ElevenLabs turbo
# Quality recording -> OpenAI TTS-1-hd or ElevenLabs standardMemilih Model LLM yang Lebih Cepat
Pilihan model sangat memengaruhi TTFT. GPT-4o-mini 5–10 kali lebih cepat daripada GPT-4o untuk sebagian besar tugas agen suara. Gunakan model terkecil yang memenuhi persyaratan kualitas.
# Model latency comparison (rough benchmarks for voice agent use case):
MODEL_BENCHMARKS = {
'gpt-4o-mini': {'ttft_ms': 300, 'quality': 'good', 'cost': 'very low'},
'gpt-4o': {'ttft_ms': 800, 'quality': 'excellent', 'cost': 'medium'},
'claude-haiku': {'ttft_ms': 250, 'quality': 'good', 'cost': 'very low'},
'claude-sonnet': {'ttft_ms': 600, 'quality': 'excellent', 'cost': 'medium'},
'llama3-8b': {'ttft_ms': 100, 'quality': 'decent', 'cost': 'free (local)'},
}
# Strategy: use fast model for simple factual queries,
# fall back to powerful model for complex reasoning
def select_model(question):
# Short, simple questions -> fast model
if len(question.split()) < 15:
return 'gpt-4o-mini'
# Complex, multi-step -> better model
if any(kw in question.lower() for kw in ['analyze', 'compare', 'explain why', 'write a']):
return 'gpt-4o'
return 'gpt-4o-mini'
if __name__ == '__main__':
for q in ['What time is it in Tokyo?', 'Analyze why sales dropped last quarter and compare to competitors']:
print(f'{select_model(q)!r} chosen for: "{q}"')
Penyimpanan Cache untuk Pertanyaan Berulang
Pengguna sering mengajukan pertanyaan yang sama atau serupa berulang kali. Simpan respons LLM + TTS di cache untuk kueri yang identik agar dapat disajikan seketika saat ditanyakan kembali.
import hashlib
import json
RESPONSE_CACHE = {} # in production: use Redis with TTL
def get_cache_key(user_text):
# Normalize: lowercase, strip punctuation
import re
normalized = re.sub(r'[^a-z0-9 ]', '', user_text.lower()).strip()
return hashlib.md5(normalized.encode()).hexdigest()
def cached_agent_respond(user_text, voice='nova'):
key = get_cache_key(user_text)
if key in RESPONSE_CACHE:
print('Response cache hit!')
entry = RESPONSE_CACHE[key]
play_audio_file(entry['audio_path'])
return entry['text']
# Cache miss
text = agent.respond(user_text)
audio_path = cached_tts(text, voice=voice)
RESPONSE_CACHE[key] = {'text': text, 'audio_path': audio_path}
play_audio_file(audio_path)
return textTarget Latensi Ujung ke Ujung
Dengan semua pengoptimalan diterapkan, agen suara yang dirancang dengan baik seharusnya mencapai waktu kurang dari 1 detik sejak pengguna selesai berbicara hingga respons agen mulai terdengar.
# Target latency budget breakdown (1000ms total):
LATENCY_BUDGET = {
'silence_detection_end': 0, # user stops speaking
'audio_processing': 50, # RMS check, noise gate
'transcription_whisper': 400, # STT API call
'llm_ttft': 300, # time to first token (gpt-4o-mini)
'tts_first_sentence': 200, # first sentence synthesized
'playback_start': 1000 # TOTAL: user hears response within 1 second
}
# Optimizations applied:
# - Streaming LLM responses (saves 200-500ms vs waiting for full response)
# - Sentence-by-sentence TTS (play while rest generates)
# - gpt-4o-mini instead of gpt-4o (saves 500ms TTFT)
# - TTS cache for common phrases (saves 200ms on cached phrases)
# - Pre-generated stall messages ('Let me check...' plays instantly)
print('Target: < 1000ms from speech end to first audio byte played')
print('Typical with optimizations: 600-900ms')Tumpang Tindih Transkripsi Asinkron
Saat agen membuat dan mengucapkan responsnya, segera mulai rekam input pengguna berikutnya. Menjalankan tahapan alur kerja secara tumpang tindih mengurangi waktu jeda antargiliran.
import threading
import time
class PipelineOverlapAgent:
def __init__(self):
self.next_audio = None
self.recording_thread = None
def start_background_recording(self):
def record():
self.next_audio = record_until_silence()
self.recording_thread = threading.Thread(target=record, daemon=True)
self.recording_thread.start()
def get_recorded_audio(self, timeout=30):
if self.recording_thread:
self.recording_thread.join(timeout=timeout)
audio = self.next_audio
self.next_audio = None
return audio
def conversation_turn(self, audio, sr):
# Transcribe and run agent
text = transcribe_file(audio_to_file(audio, sr))
if not text.strip():
return
# Start recording NEXT turn BEFORE speaking
# (user can start speaking as soon as agent starts)
response = agent.respond(text)
# Start next recording while speaking
self.start_background_recording()
# Speak current response
speak_with_interrupt(response)
# Next audio is already being captured in background
return self.get_recorded_audio()Uji Pemahaman
Pengoptimalan tunggal mana yang biasanya memberikan pengurangan latensi terbesar untuk agen suara?
Rangkuman: Pengoptimalan Latensi untuk Agen Suara
Tumpukan pengoptimalan latensi suara: alirkan respons LLM (mulai TTS pada batas kalimat saat token tiba), pemutaran TTS kalimat demi kalimat (putar saat sintesis berlangsung), penyimpanan TTS di cache (pemutaran ulang frasa berulang secara seketika), respons umum yang telah dibuat sebelumnya (salam, frasa pengisi waktu), dan pemilihan model LLM yang cepat (gpt-4o-mini untuk kueri sederhana).
Target: kurang dari 1 detik sejak pengguna selesai berbicara hingga bait audio pertama. Ukur setiap komponen — transkripsi sering kali mencakup 40% dari total latensi. TTS lokal mengorbankan kualitas demi kecepatan; TTS cloud dengan streaming per kalimat memberikan keseimbangan yang lebih baik untuk sebagian besar agen.
Belajar AI Agents dengan tutor AI — gratis
Tulis dan jalankan kode asli di browser kamu, dapatkan bantuan instan dari tutor AI 24/7, dan lanjutkan di mana kamu tinggalkan di web atau aplikasi.
- Kursus
- 60
- Pelajaran
- 239
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Optimasi Latensi untuk Agen Suara” gratis?
Ya — teks lengkap “Optimasi Latensi untuk Agen Suara” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus AI Agents, upgrade ke CoddyKit PRO. Kursus AI Agents mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “Optimasi Latensi untuk Agen Suara”?
TTS streaming, pemecahan respons, dan minimisasi latensi kata pertama. Kamu berlatih AI Agents dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai AI Agents?
Tidak diperlukan pengalaman sebelumnya. AI Agents di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 4 dari 4.
Berapa lama pelajaran “Optimasi Latensi untuk Agen Suara” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran AI Agents ini?
Ya. Setiap pelajaran AI Agents menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Speech-to-Text dengan Whisper dan Deepgram
- Text-to-Speech dalam Respons Agen
- Membangun Putaran Percakapan Suara
- Optimasi Latensi untuk Agen Suara