One specialist, one job
A good agent has one job. The instructions describe who it is, what it handles, and what it refuses. When you try to make one agent do everything, the prompt becomes a wall of exceptions and the model starts guessing.
from livekit.agents.voice import Agent
from livekit.agents.llm import function_tool
from livekit.plugins import deepgram, silero
from utils.livekit_utils import get_livekit_llm
from prompt_utils import load_prompt
class SupportAgent(Agent):
"""Handles appointments, prescription refills, and medical records."""
def __init__(self) -> None:
super().__init__(
instructions=load_prompt("support_prompt.yaml"),
stt=deepgram.STT(),
llm=get_livekit_llm(),
tts=deepgram.TTS(model="aura-asteria-en"),
vad=silero.VAD.load(),
)
@function_tool
async def check_appointment_availability(self, day: str) -> str:
"""Return available appointment slots for the given day."""
return f"We have 9am, 11am, and 2pm open on {day}."The prompt lives in a YAML file so product can edit it without touching code. Function tools become callable actions the LLM can invoke by name, with typed arguments.
Matching exercise: Match each agent to its responsibility
Loading practice…
Prompts change more often than code. Keeping them in YAML lets non-engineers tune tone, edge cases, and escalation rules without touching Python. It also lets you diff prompt changes cleanly in code review and reuse prompt fragments across agents.
AI prompt: Try it: draft a specialist prompt
Loading practice…
Checkpoint: Single voice agent checkpoint
Loading practice…