Overview
Keyterms improve recognition of distinctive words such as names, brands, products, places, and technical terms that the STT is most likely to misspell. In specialized domains, getting these few terms right often matters more than general transcription accuracy, and a wrong spelling can break a downstream response or tool call.
LiveKit Agents manages one keyterm set for the session and applies it to whichever STT you use, so you configure keyterms once instead of learning each provider's parameter. This works with models served through LiveKit Inference and with STT plugins.
Supply keyterms as static terms you set ahead of time, as terms detected automatically from the live conversation, or both.
Static keyterms
Pass a list of terms in stt_context_options (keytermsOptions in Node.js) on the AgentSession. These terms are applied for the entire session and are never removed by detection:
from livekit.agents import AgentSession, STTContextOptions, inferencesession = AgentSession(stt=inference.STT(model="deepgram/nova-3", language="en"),stt_context_options=STTContextOptions(keyterms=["LiveKit", "Acme Corp"],),# ... llm, tts, etc.)
import { AgentSession, inference } from '@livekit/agents';const session = new AgentSession({stt: new inference.STT({ model: "deepgram/nova-3", language: "en" }),keytermsOptions: {keyterms: ["LiveKit", "Acme Corp"],},// ... llm, tts, etc.});
Keyterm state is owned by the session, so it survives agent handoffs within the same session.
Automatic keyterm detection
When you don't know the vocabulary ahead of time, enable automatic detection. A background LLM reads the recent conversation transcript once per user turn (by default) and extracts distinctive spellings, such as a caller's name or a product mentioned during the call. The default detection model runs on LiveKit Inference, so no extra setup is required.
Detection is precision-focused. A wrong keyterm degrades recognition for the rest of the call with no recovery, so a term is applied only after the transcript corroborates it (for example, a spell-out the agent accepts, or the agent's own confident use of the term). Terms that aren't corroborated are tracked as candidates without affecting recognition, and dropped if they're never confirmed. When detection is uncertain, it changes nothing.
Enable automatic detection by setting enabled inside keyterm_detection (keytermDetection in Node.js):
from livekit.agents import AgentSession, STTContextOptions, inferencesession = AgentSession(stt=inference.STT(model="deepgram/nova-3", language="en"),stt_context_options=STTContextOptions(keyterms=["LiveKit"],keyterm_detection={"enabled": True,"turn_interval": 1,},),# ... llm, tts, etc.)
import { AgentSession, inference } from '@livekit/agents';const session = new AgentSession({stt: new inference.STT({ model: "deepgram/nova-3", language: "en" }),keytermsOptions: {keyterms: ["LiveKit"],keytermDetection: {enabled: true,turnInterval: 1,},},// ... llm, tts, etc.});
Detection requires an STT that supports keyterms. If the STT doesn't, detection doesn't run, and LiveKit Agents logs a warning. See Supported providers for the current list.
Detection options
Set these keys inside keyterm_detection. Node.js uses the camelCase equivalents (for example, turn_interval becomes turnInterval):
enabledboolDefault: FalseWhether to run the background detector. Static keyterms still apply when detection is off.
llmLLM | str | NoneDefault: NoneLLM used for extraction. When unset, a built-in detection model (google/gemma-4-31b-it) on LiveKit Inference is used. Pass an LLM instance or a model string to override. The agent's own LLM isn't used.
turn_intervalintDefault: 1Run a detection pass once per this many user turns. Increase it to run detection less often and reduce LLM calls.
max_keytermsint | NoneDefault: NoneCap on the number of confirmed detected keyterms. When the number of confirmed terms exceeds the cap, detection drops the oldest first. Defaults to no cap.
instructionsstr | NoneDefault: NoneOverride the built-in extraction prompt.
timeoutfloatDefault: 10.0Maximum time a single detection pass may run before it's dropped, making no change to the keyterms. Python takes seconds (default 10.0). Node.js takes milliseconds (default 10000). Raise it if a slow detection llm needs longer.
Read and update keyterms
Read the effective keyterm set, static terms plus any confirmed detected terms, from the session:
print(session.keyterms)
console.log(session.keyterms);
Replace the static keyterms mid-session with update_options (updateOptions in Node.js). Auto-detected terms are left in place:
session.update_options(keyterms=["LiveKit", "Acme Corp"])
session.updateOptions({ keyterms: ["LiveKit", "Acme Corp"] });
Supported providers
Keyterm management applies to any STT that supports keyterms. LiveKit Agents maps its managed keyterms into each provider's native parameter for you:
| Provider | Native parameter | Available through |
|---|---|---|
| Deepgram | keyterm | LiveKit Inference, plugin |
| AssemblyAI | keyterms_prompt | LiveKit Inference, plugin |
| Speechmatics | additional_vocab | LiveKit Inference |
Other keyterm-capable STT plugins also receive the managed set. For example, the Google plugin applies the terms as a recognition boost, when no custom adaptation is set.
For STTs that don't support keyterms, LiveKit Agents ignores the managed terms and logs a warning.
To bypass the managed set on a keyterm-capable provider and pass its native parameter yourself, use extra_kwargs (modelOptions in Node.js). See the Deepgram and AssemblyAI pages for per-provider parameters.