- Quickstart - a complete voice desk
- Pros and cons - control and complexity
- Bind the models - one job per entry
- Choose the turn - defaults and selectors
- Extend the desk - grow the workflow
- Advanced - switch architecture
- Troubleshooting - correct common failures
- Where to go next - model references
Quickstart
Create a new package with a LiveKit target. If initialization opens the console, select LiveKit and finish creating the package.Terminal
voice-desk/agent.yaml with this complete file:
voice-desk/agent.yaml
targets.yaml, but remove its target-level models: overrides because the model palette above replaces the scaffold’s.
Keep its framework provider and version pin, and remove any phone connection: for this browser example. Replace voice-desk/instructions.md with this complete prompt:
voice-desk/instructions.md
OPENAI_API_KEY and SLNG_API_KEY in your shell or the package’s .env, then run:
Terminal
uv.
The example below stays with this same desk agent.
Pros and cons
Pros
- Control the workflow. On LiveKit and Pipecat, combine tasks, handoffs, saved values, and tool calls. Each step can have its own instructions and access to the values it needs.
- Choose each role. Use a supported transcriber, reasoning model, and voice independently. Spend more on the part that needs better quality without replacing the others.
- Find the failing stage. Compare the recognized text, model reply, tool result, and spoken output. A wrong transcription needs a different fix from a failed tool.
Cons
- More sources of delay. Turn detection, transcription, reasoning, speech generation, and tools all contribute. Streaming reduces the wait, but does not remove those costs.
- More parts to operate. Several integrations bring separate credentials, availability limits, and failure modes.
- Less audio context for reasoning. A transcript carries the words, but can lose tone, hesitation, and other clues in the caller’s voice.
1. Bind the three models
The quickstart names the transcriber, reasoning model, and voice undermodels.
The agent binds its reasoning and voice by name. A single transcriber is selected automatically for the package.
cascade | realtime | live
Set
cascade, or omit the key for the same result. Cascade is supported on all three targets, subject to each target’s model and feature limits.a models.think entry name
required
Agent-level reasoning binding, such as
agents.desk.think: reasoning.a models.speak entry name
required
Agent-level voice binding, such as
agents.desk.speak: voice.a models.listen entry name
Package-level selector. Omit it when there is one transcriber; name an entry when there is more than one. It does not belong under an agent.
A model name is forwarded to its provider. Validation checks the binding, not whether your account can use that model.
2. Choose when the agent replies
The quickstart binds LiveKit’s local turn detector. A cascade needs a turn binding. When adding Pipecat, overridedetector for that target with provider: local and model: silero.
Follow Turn detection for the target override shape and timing options.
a models.turn entry name
Package-level selector. One turn entry is selected automatically. With several entries, name the one to use here.
3. Add tools, tasks, or saved state
Extend the same desk with a local tool, then add a task when a job needs its own steps. For example, the caller wants to change an existing request:- Look up the request with a tool.
- Collect the change in a task and save its result.
- Confirm the details before running the update tool.
- Handle a refused update, or hand the call to another agent with the context it needs.
Advanced
Compare latency across architectures
Compare latency across architectures
Transcription can run while the caller speaks, and synthesis can begin while the model generates text.
Do not add all stage durations as though every stage waits for the previous one to finish.
Model choice, turn timing, network placement, and tools affect the wait for the first audio.Tune the slow stage before replacing the architecture, and compare completed actions as well as response time.
See where the time goes and the architecture comparison.
Switch this desk to speech-to-speech
Switch this desk to speech-to-speech
Follow Switch architecture.
Replace the model palette and the agent’s
think:/speak: bindings together.
Remove old target overrides and any features the destination refuses.Switch back from live or realtime
Switch back from live or realtime
Use the quickstart’s complete
agent.yaml for a minimal cascade, keeping your prompt file.
For an existing package, copy its model palette and think:/speak: bindings instead, and add the required provider secrets.
Remove models.live, models.realtime, and the old agent binding before validating.
Do not replace a larger package’s whole file if you need to retain its tools or workflow.Troubleshooting
Validation rejects an agent-level listen field
Listening is selected for the package, not for each agent. Fix: move the selector to the top level, or omit it when only one transcriber exists.The agent waits too long or cuts callers off
Turn settings or provider latency may be responsible. Fix: inspect the dev measurements and follow Turn taking before replacing all three models.A provider is refused for one role
Targets support different providers for each role. Fix: choose a supported integration from that role’s reference, then validate every declared target.Where to go next
Add a task
Give one job its own workflow.
Choose architecture
Compare and switch pipelines.