c
hi
t
Thanks for reaching out, Arun. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
c
from datetime import datetime import json import time from dotenv import load_dotenv from livekit import api from livekit.agents import Agent, JobContext, JobProcess, WorkerOptions, cli, function_tool from livekit.agents.voice import AgentSession from livekit.plugins import silero from agents.functions.function_builder import function_builder from agents.utils import get_llm_from_config, get_stt_from_config, get_tts_from_config, inactivity_handler from agents.utils import WELCOME_MESSAGE, OUTBOUND_MESSAGE, END_CALL_PROMPT from agents.utils import get_all_metadata, get_all_instructions, substitute_variables, get_interruption_params from agents.services.call_recording import CallRecordingService from agents.api import end_call from agents.rag import get_embed_model load_dotenv() def prewarm(proc: JobProcess): proc.userdata["vad"] = silero.VAD.load() proc.userdata["embedding_model"] = get_embed_model() class VoiceAgent(Agent): def __init__(self, ctx, meta_data, variables=None, call_metadata=None): self.ctx = ctx self.rag = meta_data['rag'] super().__init__( instructions=get_all_instructions(meta_data['agent'], variables), stt=get_stt_from_config(meta_data['stt']), llm=get_llm_from_config(meta_data['llm']), tts=get_tts_from_config(meta_data['tts']), tools=function_builder(meta_data['functions'], call_metadata) ) async def on_user_turn_completed(self, turn_ctx, new_message) -> None: if not self.rag: return query = new_message.text_content if not query or len(query) < 3: return rag_content = await self.rag.query(query) if rag_content: turn_ctx.add_message( role="assistant", content=f"[Knowledge Base Context]: {rag_content}" ) @function_tool(description=f"{END_CALL_PROMPT}") async def end_call_on_user_request(self) -> str: self.ctx.shutdown() return json.dumps({"status": "session shutdown initiated"}, indent=2) async def entrypoint(ctx: JobContext): meta_data = await get_all_metadata(ctx) dial_info = meta_data.get('dial_info', {}) to_number = dial_info.get('to_number') from_number = dial_info.get('from_number') sip_trunk_id = dial_info.get('sip_trunk_id') variables = dial_info.get('variables', {}) is_outbound = bool(to_number) if is_outbound: if not sip_trunk_id: ctx.shutdown() return try: await ctx.api.sip.create_sip_participant( api.CreateSIPParticipantRequest( room_name=ctx.room.name, sip_trunk_id=sip_trunk_id, sip_call_to=to_number, participant_identity=to_number, participant_name=f"Call to {to_number}", krisp_enabled=True, wait_until_answered=True, ) ) except api.TwirpError as e: ctx.shutdown() return is_telephony = True channel = "PHONE" else: await ctx.connect() is_telephony = False for participant in ctx.room.remote_participants.values(): if hasattr(participant, 'attributes') and participant.attributes: attrs = participant.attributes sip_phone = attrs.get('sip.phoneNumber') if sip_phone: from_number = sip_phone to_number = attrs.get('sip.trunkPhoneNumber') is_telephony = True break channel = "PHONE" if is_telephony else "WEB" call_metadata = { "from_number": from_number if is_telephony else None, "to_number": to_number if is_telephony else None, "call_type": channel, "direction": "OUTBOUND" if is_outbound else "INBOUND" if is_telephony else None, } agent = VoiceAgent(ctx, meta_data, variables, call_metadata) agent_data = meta_data['agent'] interruption_sensitivity = agent_data.get('interruption_sensitivity', 0.5) min_interruption_duration, false_interruption_timeout = get_interruption_params(interruption_sensitivity) session = AgentSession( vad=ctx.proc.userdata.get("vad"), preemptive_generation=False, min_interruption_duration=min_interruption_duration, false_interruption_timeout=false_interruption_timeout, ) inactivity_handler(session, ctx) start_time = datetime.now() recorder = CallRecordingService() await recorder.start_recording( room_name=ctx.room.name, filename=f"{ctx.room.name}_{int(time.time())}.ogg", ) await session.start(agent=agent, room=ctx.room) if is_telephony and is_outbound: greeting = agent_data.get('greeting_message', OUTBOUND_MESSAGE) else: greeting = agent_data.get('greeting_message', WELCOME_MESSAGE) greeting = substitute_variables(greeting, variables) await session.say(greeting) async def on_session_end(): recording_url = await recorder.stop_and_wait() end_call_data = { "session_id": ctx.job.id, "started_at": start_time.isoformat(), "ended_at": datetime.now().isoformat(), "transcript": json.dumps(session.history.to_dict() if hasattr(session, "history") else {"items": []}, indent=2), "agent_id": agent_data.get('id'), "client_id": agent_data.get('client_id'), "recording_url": recording_url, "direction": "OUTBOUND" if is_outbound else "INBOUND" if is_telephony else None, "channel": channel, "from_number": from_number if is_telephony else None, "to_number": to_number if is_telephony else None, } try: await end_call(end_call_data) except Exception as e: print(f"Error logging call: {e}") try: ctx.delete_room(ctx.room.name) except Exception as e: print(f"Error deleting room: {e}") ctx.add_shutdown_callback(on_session_end) def run(): cli.run_app( WorkerOptions( entrypoint_fnc=entrypoint, prewarm_fnc=prewarm, agent_name="voice-agent", port=8082, num_idle_processes=2, ) ) if name == "__main__": run() thsi si deployed on aws vm but i fee leiktt high lentency
t
Hi — great to see you here! How can I help today? If you’re not sure where to start, here are a few things I can assist with: • Troubleshooting a LiveKit room or connection issue • SDK integration questions (Web, iOS, Android) • Token/credentials or permissions help • Performance or quality problems (audio/video) • Billing, plans, or account questions Tell me which area you’re working on and any details (project/room IDs, error messages, SDK & version) and I’ll jump in.
Hi — thanks for sharing your code and letting me know you’re seeing high latency. I’m here to help. I’ll walk through the most likely causes based on your deployment (AWS VM) and the code you posted, then ask a couple of quick questions so I can give more precise recommendations. What I’m responding to: your voice-agent code deployed on an AWS VM and the note “i fee leiktt high lentency” (high latency). Most likely causes and what you can do now • EC2 instance type (highest likelihood) ◦ If you’re on a burstable instance (t3/t4 family like t3.micro, t3.small), CPU credit exhaustion causes drastic throttling that looks like “high latency” even with low reported CPU. Check CloudWatch for
CPUCreditBalance
. If it’s at or near zero, switch to a fixed-performance instance (examples: c6i.large, m5.large, c5.large). • Local inference / heavy CPU work ◦ VAD, STT, LLM or TTS models can be CPU/memory intensive. If you run heavy models locally on a small instance, inference will be slow. Consider moving inference to a stronger instance or offloading to managed inference (see LiveKit Inference below). • Network & region mismatches ◦ If your VM is in a different region than the STT/LLM/TTS providers, network round trips add latency. Ensure your VM region is close to your provider endpoints and users. • Synchronous vs streaming model configuration ◦ If STT/LLM/TTS are used in blocking mode instead of streaming, the pipeline waits for full results, increasing turn latency. Enable streaming where available. • Session / agent configuration ◦ You currently set
preemptive_generation=False
. Enabling
preemptive_generation=True
reduces perceived latency by starting generation earlier (tradeoff: more compute spent if user interrupts). • Extra CPU load from optional features ◦ Krisp noise cancellation and other processing increase CPU usage—disable if the instance is underpowered. Quick code/config recommendations you can apply immediately 1. Enable preemptive generation:
Copy code
session = AgentSession(
    vad=ctx.proc.userdata.get("vad"),
    preemptive_generation=True,  # reduces perceived latency
    min_interruption_duration=min_interruption_duration,
    false_interruption_timeout=false_interruption_timeout,
)
1. Confirm STT/LLM/TTS are using streaming endpoints (provider-specific) so you can stream partial results rather than waiting for full responses. 2. If using Krisp and you’re on a low-powered instance, try disabling
krisp_enabled=True
in the SIP participant creation to reduce CPU load. 3. Run a simple latency test locally vs on the VM: if local is fast and VM is slow, it’s infrastructure-related (instance or network). Observability and metrics to collect (these will pinpoint where latency happens) • Measure Time-To-First-Token (TTFT) for LLM responses. • Measure Time-To-First-Byte (TTFB) for TTS audio output. • Measure VAD / turn-detection latency. • Check EC2 CloudWatch: CPU, CPUCreditBalance, network I/O, and disk I/O. • Enable Agent Observability traces so you can see per-session timing for STT → LLM → TTS. Longer-term / higher-impact options • Upgrade EC2 instance family to a non-burstable instance (c5, c6i, m5 families). • Use LiveKit Inference to co-locate inference closer to your workers and reduce public internet hops (reduces TTFT/TTFB and queuing). • If you need predictable, low-latency inference, use provisioned model capacity from a managed provider or LiveKit Inference. Helpful diagnostic questions • What EC2 instance type are you running (example: t3.small, c5.large)? • Are you using local models for STT/LLM/TTS or external hosted providers (please name them and region)? • Do you see any CloudWatch alerts or is
CPUCreditBalance
near zero? • Is the latency consistent (always high) or intermittent? • Which step feels slow: detecting end of user speech, LLM response generation, or TTS playback? If you share the instance type, your STT/LLM/TTS providers and regions, and whether
CPUCreditBalance
is low, I’ll give a precise, prioritized plan (exact instance choices, config tweaks, and tests) to reduce latency quickly. Sources: Troubleshooting Latency and Timeout Errors with Turn Detection on AWS | Streamline troubleshooting with Agent Observability | Agent session | LiveKit Documentation | How can I reduce latency in voice agents using STT, TTS and LLM? | LiveKit | Introducing LiveKit Inference: A unified model interface for voice AI
c
t3 meduis
t
Thanks — that’s a very helpful detail. A t3.medium is a burstable instance and is likely the main cause of the high latency you’re seeing. Here’s a short, prioritized plan you can follow right now to confirm and fix the issue. What I’m responding to: you’re running the voice agent on an AWS t3.medium and experiencing high latency. Why t3.medium is likely the problem • t3 instances use CPU credits. When credits run out the instance is throttled to a small fraction of a CPU, which causes long pauses even though reported CPU can look low. • This throttling commonly shows up as slow VAD/STT/LLM/TTS response times and long turn latency. Immediate checks (do these first) • Check CloudWatch for the
CPUCreditBalance
metric for your instance. If it’s near zero, the instance is being throttled. • Check CPU utilization, network I/O, and any spikes around call time to confirm load patterns. Quick fixes you can apply now 1. Temporarily scale up to a non-burstable instance to confirm the cause: ◦ Recommended: c6i.large, m5.large, or c5.large (start with one of these and test). 1. If you can’t change instance immediately, stop nonessential CPU-heavy features: ◦ Disable Krisp (
krisp_enabled=False
) to reduce CPU load. ◦ Set
preemptive_generation=True
in
AgentSession
to reduce perceived latency (tradeoff: more compute if interrupted). 1. Ensure STT/LLM/TTS providers are in the same region as your EC2 instance to reduce network RTT. Medium-term improvements • Move inference off the VM or use LiveKit Inference / provisioned model capacity to reduce queuing and network hops. • Run multiple worker instances on appropriately sized machines for load balancing. • Enable streaming STT/LLM/TTS so audio/text are sent/played incrementally instead of waiting for full responses. Testing checklist after changes 1. Verify
CPUCreditBalance
rises or throttling stops after switching instance. 2. Measure time breakdown: VAD → STT → LLM TTFT → TTS TTFB. 3. Compare latency on t3.medium vs upgraded instance. If latency drops significantly on the upgraded instance, the t3 throttling was the root cause. If you want, tell me: • whether you can switch instance types now, • which STT/LLM/TTS providers and regions you’re using, and I’ll recommend an exact instance size and a short test plan to validate the fix.
c
even in lcola alos slow ahat sod i do to amke fast ets
t
Thanks — I hear your frustration. You said it’s slow even locally. Let’s narrow down where the delay is and fix it step‑by‑step. I’ll give a short diagnostic checklist you can run now, plus quick fixes to try immediately. What I’m responding to: your agent is high-latency both on t3.medium (AWS) and when running locally. Quick diagnostic checks (run these first) 1. Time each pipeline stage with simple logs: ◦ Log timestamps for: VAD end detection, STT request start/end, LLM request start/end (TTFT), TTS request start/end (TTFB), and audio playback start. ◦ This tells you whether latency is in VAD, STT, LLM, TTS, or network. 1. Test a minimal local loop: ◦ Replace real STT/LLM/TTS with a stub that immediately returns a small response. If this is fast, the external providers are the bottleneck. 1. Network RTT test: ◦ From your machine and from the VM, ping/traceroute the STT/LLM/TTS endpoints and measure round-trip time. 1. Resource check (local & VM): ◦ CPU, RAM, disk I/O while running a call. On AWS, check CloudWatch
CPUCreditBalance
. ◦ If local device is CPU-starved (e.g., laptop fan ramps up), that will slow inference. Immediate, high-impact fixes to try now • Enable streaming for STT/LLM/TTS if available so you get incremental results instead of waiting for full outputs. • Set
preemptive_generation=True
in
AgentSession
to reduce perceived response time. • Disable optional CPU-heavy features while testing (e.g., Krisp noise cancellation). • If local machine is weak, test on a stronger machine or a non-burstable cloud VM (c5/c6i/m5) to compare. If logs show LLM or TTS is slow • Use a provider endpoint in the same region as your agent. • Consider switching to LiveKit Inference or a provisioned model endpoint to reduce queuing and network hops. If logs show STT or VAD delays • Ensure VAD is tuned correctly (not waiting too long for end of speech). • Use streaming STT and verify packet sizes / buffer settings aren’t adding artificial delay. Short tests you can run (5–10 minutes) 1. Local stub test: Run the agent but stub STT/LLM/TTS. If latency disappears, external providers are the issue. 2. Cloud vs local compare: Run the same test on a c5.large or m5.large VM for comparison. If cloud is faster, your local device is the limit. 3. Single-step timing: Make a call that causes exactly one STT->LLM->TTS cycle and inspect the timestamps. Data I need from you to give exact next steps • When local is slow, what machine are you using? (CPU model, RAM) • Which STT / LLM / TTS providers are you using and which regions? (e.g., OpenAI us-east-1, Deepgram eu-west-1) • From your timestamp logs (if you can add a few) which step had the highest delay? If you haven’t instrumented yet, I can show exactly where to add 3-4 logging lines in your code. • Do you have the agent running with
preemptive_generation=False
now? (I saw False in your code) If you want, I can: • Provide the exact logging snippets to insert around VAD/STT/LLM/TTS calls. • Recommend an EC2 instance size based on your provider choices and expected concurrency. • Give a short test script to simulate a call and produce the timing breakdown automatically. Pick one: share the provider/region details or say “send logging snippets” and I’ll give the minimal code to time the pipeline. Sources: How can I reduce latency in voice agents using STT, TTS and LLM? | LiveKit | Introducing LiveKit Inference: A unified model interface for voice AI | Troubleshooting Latency and Timeout Errors with Turn Detection on AWS | examples/frontdesk | livekit/livekit_composite | DeepWiki | Playing Audio | LiveKit Documentation