Overview
User turn strategies provide fine-grained control over how user speaking turns are detected in conversations. They determine when a user’s turn starts (user begins speaking) and when it stops (user finishes speaking and expects a response). By default, Pipecat uses a combination of VAD (Voice Activity Detection) and AI-powered turn detection:- Start: VAD detection or transcription received
- Stop: AI-powered turn detection using
LocalSmartTurnAnalyzerV3
In Pipecat >=1.0.0, the
turn_analyzer must be specified in the
TurnAnalyzerUserTurnStopStrategy. See the migration
guide
for more information.How It Works
-
Turn Start Detection: When any start strategy triggers, the user aggregator:
- Marks the start of a user turn
- Optionally emits
UserStartedSpeakingFrame - Optionally emits an interruption frame (if the bot is speaking)
- During User Turn: The aggregator collects transcriptions and audio frames.
-
Turn Stop Detection: When a stop strategy triggers, the user aggregator:
- Marks the end of the user turn
- Emits
UserStoppedSpeakingFrame - Pushes the aggregated user message to the LLM context
-
Timeout Handling: If no stop strategy triggers within
user_turn_stop_timeoutseconds (default: 5.0), the turn is automatically ended. This timeout is configurable viaLLMUserAggregatorParams(see Configuration below). When the timeout fires, theon_user_turn_stop_timeoutevent is emitted.
When a user turn ends
A user turn stop strategy decides when the user is done talking and the bot should respond. You choose the strategy; the rest of the timing follows from it. If you want to adjust how long the bot waits before responding, do it in the stop strategy — that’s the knob built for it. Whatever the strategy, closing a turn takes two ingredients:- A transcript. Every stop strategy waits for the STT service to transcribe what the user said (
wait_for_transcript, on by default). This is usually the largest and most variable part of the delay, and it’s dominated by your STT provider’s latency — see the STT benchmark to compare services. - The strategy’s own end-of-turn criteria. Once the transcript is in, the strategy applies its logic to decide whether the turn is actually complete.
Choosing a strategy
This is also where you tune responsiveness. For example, raise or lower
user_speech_timeout on SpeechTimeoutUserTurnStopStrategy to give users more or less time to resume before the bot replies.
Where the latency comes from
Before any strategy can act, two things have to happen:- VAD silence (
stop_secs): The VAD waits a short, fixed interval (default0.2s) after audio goes quiet before reporting that the user stopped speaking. This is a low-level detection threshold — leave it alone. To change wait time, use the stop strategy, notstop_secs. - Transcription: STT returns a transcript. Latency here is mostly your STT provider’s; strategies use the provider’s reported p99 latency as a fallback timer and short-circuit it the moment a finalized transcript arrives.
These don’t stack. The fallback timer is an absolute deadline — the end of the
user’s speech plus the STT service’s
ttfs_p99_latency — so the VAD’s
stop_secs and the time a turn model spends on inference both fall inside
that budget rather than extending it. What a user notices is the deadline
itself, or a finalized transcript arriving sooner.If your STT service is slow to return transcripts, that delay shows up in
every turn regardless of which strategy you use. Adjust responsiveness in the
stop strategy, and check the STT
benchmark if transcription is
the bottleneck.user_turn_stop_timeout (default 5.0s, on LLMUserAggregatorParams) is a backstop, not part of normal timing: if a turn somehow never finalizes, it forces the turn to end so the bot isn’t stuck waiting.
Configuration
User turn strategies are configured viaLLMUserAggregatorParams when creating an LLMContextAggregatorPair:
Additional Parameters
In addition touser_turn_strategies, LLMUserAggregatorParams accepts these turn-related parameters:
float
default:"5.0"
Safety-net timeout in seconds. If a user turn starts but no stop strategy
triggers within this duration, the turn is automatically ended and the
on_user_turn_stop_timeout
event is emitted.VADAnalyzer
default:"None"
The Voice Activity Detection analyzer instance used to produce VAD signals for
turn detection. In Pipecat 1.x, VAD is configured on the aggregator rather
than the transport. This is separate from
VADUserTurnStartStrategy: the
analyzer produces the VAD signals; the start strategy decides what to do
with them.Start Strategies
Start strategies determine when a user’s turn begins. Multiple strategies can be provided, and the first one to trigger will signal the start of a user turn.Base Parameters
All start strategies inherit these parameters:bool
default:"True"
If True, the user aggregator will emit an interruption frame when the user
turn starts, allowing the user to interrupt the bot.
bool
default:"True"
deprecated
If True, the user aggregator will emit frames indicating when the user starts
speaking. Disable this if another component (e.g., an STT service) already
generates these frames. Deprecated in v1.8.0. Whether a turn is announced is
a per-turn decision: pass
enable_user_speaking_frames to
trigger_user_turn_started() where the strategy decides the turn. Will be
removed in v2.0.0.VADUserTurnStartStrategy
Triggers a user turn start based on Voice Activity Detection. This is the most responsive strategy, detecting speech as soon as the VAD indicates the user has started speaking.TranscriptionUserTurnStartStrategy
Triggers a user turn start when a transcription is received. This serves as a fallback for scenarios where VAD-based detection fails (e.g., when the user speaks very softly) but the STT service still produces transcriptions.bool
default:"True"
Whether to trigger on interim (partial) transcription frames for earlier
detection.
MinWordsUserTurnStartStrategy
Requires the user to speak a minimum number of words before triggering a turn start. This is useful for preventing brief utterances like “okay” or “yeah” from triggering responses.int
required
Minimum number of spoken words required to trigger the start of a user turn.
bool
default:"True"
Whether to consider interim transcription frames for earlier detection.
When the bot is not speaking, this strategy will trigger after just 1 word.
The
min_words threshold only applies when the bot is actively speaking,
preventing short affirmations from interrupting the bot.WakePhraseUserTurnStartStrategy
Requires a wake phrase to be detected before allowing interaction. This strategy blocks subsequent strategies until a wake phrase is detected in a transcription, then allows interaction for a configurable timeout period.List[str]
required
List of wake phrases to detect (e.g.,
["hey pipecat", "ok pipecat"]).float
default:"10.0"
Inactivity timeout in seconds before returning to IDLE state. In timeout mode,
the timer resets on activity. In single activation mode, acts as a keepalive
window after wake phrase detection.
bool
default:"False"
If True, the wake phrase is required before every turn. The strategy returns
to IDLE after each turn completes.
This strategy should be placed first in the start strategies list to
properly gate all subsequent strategies. Use
default_user_turn_start_strategies() to extend the defaults with wake phrase
detection.KrispVivaIPUserTurnStartStrategy
Uses Krisp’s Interruption Prediction (IP) model to distinguish genuine user interruptions from backchannels (e.g., “uh-huh”, “yeah”). When VAD detects user speech, this strategy feeds audio frames into the Krisp VIVA IP model, which outputs a probability indicating whether the speech is a genuine interruption. A user turn is triggered only when this probability exceeds the configured threshold. This strategy is designed to work alongside other start strategies (e.g.,TranscriptionUserTurnStartStrategy as a fallback).
Optional[str]
default:"None"
Path to the Krisp VIVA IP model file (.kef extension). If None, uses the
KRISP_VIVA_IP_MODEL_PATH environment variable.float
default:"0.5"
IP probability threshold (0.0 to 1.0). When the model’s output exceeds this
value, the speech is classified as a genuine interruption.
int
default:"20"
Frame duration in milliseconds for IP processing. Supported values: 10, 15,
20, 30, 32.
str
default:"\"\""
Krisp SDK API key. If empty, falls back to the
KRISP_VIVA_API_KEY
environment variable.Requires the Krisp Python SDK. See the Krisp VIVA
guide for installation instructions.
ExternalUserTurnStartStrategy
Delegates turn start detection to another component in the pipeline. It handles two signals, which differ in how much the emitter has already done:ProposedUserStartedSpeakingFrame: a service with its own turn detection proposing a turn boundary. This strategy makes the decision, emitting theUserStartedSpeakingFrameand broadcasting the interruption itself. Subclass it to adjust when, or whether, a proposal opens a turn.UserStartedSpeakingFrame: the turn was already decided and announced elsewhere, typically by a sharedUserTurnProcessorfanning turns out to several aggregators. This strategy adopts that decision and emits nothing, so the turn isn’t announced twice.
bool
default:"True"
Whether to broadcast an interruption when a proposal opens a turn.
Turn-detecting services route their
should_interrupt setting here. Ignored
when a UserStartedSpeakingFrame drives the turn, since the emitter has
already broadcast one.Stop Strategies
Stop strategies determine when a user’s turn ends and the bot should respond.Base Parameters
All stop strategies inherit these parameters:bool
default:"True"
deprecated
If True, the aggregator will emit frames indicating when the user stops
speaking. Disable this if another component already generates these frames.
Deprecated in v1.8.0. Whether a turn is announced is a per-turn decision:
pass
enable_user_speaking_frames to trigger_user_turn_stopped() where the
strategy decides the turn. Will be removed in v2.0.0.SpeechTimeoutUserTurnStopStrategy
Signals the end of a user turn using two independent timers after VAD detects silence. The user turn stop is triggered only when both timers have finished and at least one transcript has been received:- user_speech_timeout: Policy floor — the window in which the user may resume speaking after a pause. Always runs to completion.
- stt_timeout: Safety net for STT latency — the P99 time for the STT service to return a final transcript after VAD stop. Short-circuited when the STT service emits a finalized transcript (
TranscriptionFrame.finalized=True), since finalization means STT has nothing more to send.
user_speech_timeout elapses after VAD stop, rather than waiting for both timers. Support varies by service and can be conditional — see TranscriptionFrame.finalized for how a service reports it, and the service’s own page for whether it does.
float
default:"0.6"
How long to wait (in seconds) after VAD detects silence before finalizing the
user turn. This is the minimum wait time and always runs to completion.
bool
default:"True"
When
True (default), turn-stop signaling waits for a transcript to arrive
after VAD silence. When False, the strategy signals turn-stop as soon as its
timing requirements are met, without waiting for transcripts — useful when
local turn detection drives a realtime (speech-to-speech) service, where
waiting for transcripts is unnecessary latency.
LLMContextAggregatorPair
flips this to False for you when realtime_service_mode=True.Built-in STT P99 latency values assume
VADParams.stop_secs=0.2 (the
recommended default). If you change stop_secs, the strategy will log a
warning suggesting you re-run the
stt-benchmark with your VAD
settings and pass the measured TTFS P99 latency to your STT service
constructor via ttfs_p99_latency. The strategy will also warn if `stop_secs= STT p99 latency`, which collapses the STT wait timeout to 0s and may cause delayed turn detection.
TurnAnalyzerUserTurnStopStrategy
Uses an AI-powered turn detection model to determine when the user has finished speaking. This provides more intelligent end-of-turn detection that can understand conversational context.BaseTurnAnalyzer
required
The turn detection analyzer instance to use for end-of-turn detection.
bool
default:"True"
When
True (default), turn-stop signaling waits for a transcript to arrive
after the analyzer reports end-of-speech. When False, the strategy signals
turn-stop as soon as the analyzer fires, without waiting for transcripts —
useful when local turn detection drives a realtime (speech-to-speech) service.
LLMContextAggregatorPair
flips this to False for you when realtime_service_mode=True.Built-in STT P99 latency values assume
VADParams.stop_secs=0.2 (the
recommended default). If you change stop_secs, the strategy will log a
warning suggesting you re-run the
stt-benchmark with your VAD
settings and pass the measured TTFS P99 latency to your STT service
constructor via ttfs_p99_latency. The strategy will also warn if `stop_secs= STT p99 latency`, which collapses the STT wait timeout to 0s and may cause delayed turn detection.
ExternalUserTurnStopStrategy
Delegates turn stop detection to another component in the pipeline. The end-of-turn counterpart toExternalUserTurnStartStrategy, taking the same two signals:
ProposedUserStoppedSpeakingFrame: a service proposing that the turn has ended. This strategy decides, and emits theUserStoppedSpeakingFrameitself. It may also hold the turn open past the proposal, which is whatwait_for_transcriptdoes.UserStoppedSpeakingFrame: the turn end was already decided and announced elsewhere, typically by a sharedUserTurnProcessor. This strategy adopts that decision and emits nothing.
trigger_user_turn_stopped(), which both paths reach once they decide the turn is over.
float
default:"0.5"
A short delay in seconds used to handle consecutive or slightly delayed
transcriptions.
bool
default:"True"
When
True (default), turn-stop signaling waits for a transcript to arrive
after the external stop signal. When False, the strategy signals turn-stop
as soon as that signal arrives, independent of transcripts — useful when local
turn detection drives a realtime (speech-to-speech) service.
LLMContextAggregatorPair
flips this to False for you when realtime_service_mode=True.ExternalUserTurnCompletionStopStrategy
Finalizes the user turn whenever aUserTurnInferenceCompletedFrame arrives, regardless of which component produced it. Use this when an external component — an LLM with completion markers, an STT service with built-in turn detection, a dedicated end-of-turn classifier, or custom code — decides when a turn is semantically complete and emits that frame.
Pair it with one or more detector strategies wrapped in deferred(...), which drive inference but leave finalization to this strategy:
If the producer never emits
UserTurnInferenceCompletedFrame, the
user_turn_stop_timeout watchdog finalizes the turn after no activity. Tune
that timeout if your producer can take longer than the default to respond.LLMTurnCompletionUserTurnStopStrategy
A subclass ofExternalUserTurnCompletionStopStrategy that adds the LLM-specific setup for the marker-based completion protocol. On StartFrame it enables turn-completion filtering on the LLM; finalization then happens when the LLM emits a ● marker. This is the finalizer used by FilterIncompleteUserTurnStrategies.
UserTurnCompletionConfig
default:"None"
Configuration applied to the LLM (turn-completion instructions,
incomplete-turn timeouts, and re-prompts). Defaults to
UserTurnCompletionConfig().Deferring finalization
Some stop strategies should trigger LLM inference without ending the turn — finalization is owned by another strategy in the chain (such as the two above). Wrap a detector strategy withdeferred(...) to suppress its on_user_turn_stopped event while keeping its on_user_turn_inference_triggered trigger:
Helper Functions
Pipecat provides helper functions to compose custom strategy lists that extend the defaults.default_user_turn_start_strategies()
Returns the default user turn start strategies:[VADUserTurnStartStrategy, TranscriptionUserTurnStartStrategy].
Useful when building a custom strategy list that extends the defaults, such as adding wake phrase detection before the standard strategies.
default_user_turn_stop_strategies()
Returns the default user turn stop strategies:[TurnAnalyzerUserTurnStopStrategy(LocalSmartTurnAnalyzerV3)].
Useful when building a custom strategy list that extends or replaces the defaults.
UserTurnStrategies
Container for configuring user turn start and stop strategies.List[BaseUserTurnStartStrategy]
default:"[VADUser...(), TranscriptionUser...()]"
List of strategies used to detect when the user starts speaking. The first
strategy to trigger will signal the start of the user’s turn.
List[BaseUserTurnStopStrategy]
List of strategies used to detect when the user stops speaking and expects a
response. Defaults to AI-powered turn detection using
LocalSmartTurnAnalyzerV3.ExternalUserTurnStrategies
A convenience class that preconfiguresUserTurnStrategies with external strategies for both start and stop detection. Use this when an external processor (such as a speech-to-speech service) controls turn management.
What these strategies emit depends on which frame drives the turn:
- A proposal (
ProposedUserStartedSpeakingFrame/ProposedUserStoppedSpeakingFrame, sent by a turn-detecting STT service): the decision is left to these strategies, so they pushUserStartedSpeakingFrame/UserStoppedSpeakingFrameand broadcast the interruption themselves. - A real turn frame (
UserStartedSpeakingFrame/UserStoppedSpeakingFrame, sent by a sharedUserTurnProcessoror a third-party service): the turn was already announced, so these strategies emit nothing andenable_interruptionsdoes not apply.
Constructor Parameters
bool
default:"True"
Whether to broadcast an interruption when a proposal starts a turn. This is
where a turn-detecting STT service sends its
should_interrupt setting, so
the two are the same knob. Set it to False to stop the bot being interrupted
when the user starts speaking. Ignored when a real turn frame drives the turn.When an STT service acts as the turn controller, you can optionally include a
VAD (such as
SileroVADAnalyzer) in your transport. The VAD is not required
for core turn management functionality, but it does enable useful STT metrics.
Omit it if you don’t need those metrics.FilterIncompleteUserTurnStrategies
A convenience class that preconfiguresUserTurnStrategies for LLM-gated turn completion. It wraps your detector chain with deferred(...) and appends an LLMTurnCompletionUserTurnStopStrategy, so the public on_user_turn_stopped event fires only when the LLM confirms the turn is complete (●). Detector strategies still drive LLM inference via on_user_turn_inference_triggered.
UserTurnCompletionConfig
default:"None"
Optional turn-completion configuration (instructions, incomplete-turn
timeouts, and re-prompts) applied to the LLM. Defaults are used if not
provided.
start and stop strategies default to the standard detector chain; override either to customize the detectors that trigger inference.
Usage Examples
Default Behavior
The default configuration uses VAD for turn start detection and AI-powered Smart Turn for turn end detection:Minimum Words for Interruption
Require users to speak at least 3 words before they can interrupt the bot:Wake Phrase Detection
Require a wake phrase before allowing interaction, then use the default turn strategies:Local Smart Turn Detection
Use a local turn detection model instead of a cloud service:Related
- User Input Muting - Control when user input is ignored
- Smart Turn Detection - AI-powered turn detection