powerful-magician-63563
12/26/2025, 2:10 PMtall-airline-16756
12/26/2025, 2:10 PMtall-airline-16756
12/26/2025, 2:10 PMctx.connect() so the agent initializes with the correct instructions and doesn’t appear “ready” without its context.
1. Put the DB content into the model’s system instructions
• Use the retrieved text as the instructions parameter for the realtime Gemini model (this is the agent’s system prompt / role definition).
• Keep instructions focused: role, persona, domain constraints, and any important facts the agent must always use.
Example pattern
1. get context: context_from_db = get_context_from_db(user_selected_id)
2. create session:
session = AgentSession(
llm=google.realtime.RealtimeModel(
model="gemini-2.5-flash",
instructions=context_from_db,
voice="Puck"
),
vad=silero.VAD.load(),
)
When to use ChatContext vs instructions
• Use instructions for the permanent/defining context (role, core facts, behavior rules).
• Use ChatContext or conversation messages for transient or incremental data (recent facts, user-provided info, retrieved RAG snippets you don’t want in the system prompt long-term).
Performance and safety tips
• Pre-load and optionally cache frequently used contexts to avoid delays.
• Trim or summarize very large contexts before placing them in instructions to fit token/latency constraints.
• If contexts contain sensitive data, sanitize or redact what the agent mustn’t speak aloud, and enforce those rules in the instructions.
If you want, tell me:
• the typical size of a context record and whether contexts include long documents or structured fields (I can recommend summarization or chunking patterns), or
• whether you need dynamic retrieval mid-conversation (I can show how to inject retrieved snippets into ChatContext safely). Sources: External data and RAG | LiveKit docs | Gemini Live API plugin | LiveKit docspowerful-magician-63563
12/26/2025, 4:00 PMtall-airline-16756
12/26/2025, 4:01 PMinstructions if it should define the agent’s role/behavior for the whole session.
• Or inject the topic as an initial chat message / ChatContext if it’s transient or part of the ongoing conversation.
Option A — Make the topic the session’s system instruction (recommended if the topic defines the session)
1. Read the user’s selection on your server: topic = "I want to talk about stars".
2. Build a concise instruction that frames the agent role and how to use the topic:
◦ Example instruction: "You are an educational voice assistant. The user wants to discuss: stars. Keep answers friendly and high-level unless asked for technical detail."
1. Create the AgentSession / RealtimeModel with that string as instructions before connecting:
context = f"You are an educational voice assistant. The user wants to discuss: {topic}."
session = AgentSession(
llm=google.realtime.RealtimeModel(
model="gemini-2.5-flash",
instructions=context,
voice="Puck"
),
vad=...
)
# then connect the session
When to use: topic should persist for the whole call and shape the agent’s persona/limits.
Option B — Send the topic as the initial chat message / ChatContext (recommended if topic is conversational or may change)
1. Fetch the topic, then add it as the first user message or chat-context entry:
# pseudo-structure
initial_messages = [
{"role":"system","content":"You are a helpful voice assistant."},
{"role":"user","content":"I want to talk about stars"}
]
# pass initial_messages into ChatContext or as initial conversation state
1. Start the session with the system prompt minimal and include the initial messages so the model treats it as current conversation context.
When to use: topic is one of many conversation inputs, may change mid-call, or you prefer not to bake content into permanent instructions.
Practical tips
• Keep instructions concise and focused on role/constraints; avoid dumping very long docs there.
• If topic implies long source material, summarize or attach snippets as chat messages (RAG) rather than a huge system prompt.
• Ensure DB lookup completes before creating/connecting the session to avoid the agent starting without context.
• Sanitize user input (remove PII or unsafe content) before injecting it into prompts.
If you want, tell me:
• whether the topic should persist for the entire session or can change mid-call, and
• the typical length of topic/context text — I’ll suggest exact prompt templates or a RAG pattern for long contexts.powerful-magician-63563
12/26/2025, 4:16 PMtall-airline-16756
12/26/2025, 4:16 PMinstructions, initial chat message/ChatContext, or room/participant metadata) and example snippets tailored to your stack.powerful-magician-63563
12/26/2025, 4:18 PMtall-airline-16756
12/26/2025, 4:19 PMmetadata (JSON string).
3. LiveKit / Agent: in the agent entrypoint, read ctx.job.metadata, parse the JSON, and inject the value into the model as instructions (or otherwise apply it when creating the AgentSession) before calling ctx.connect().
Why this works
• WebRTC carries media; metadata must be sent via your backend using the LiveKit dispatch API so the agent receives it at startup.
• The agent reads ctx.job.metadata at entry and can set the Gemini Live model instructions to the user-provided text for the whole session.
Minimal examples
• Backend dispatch (Node-ish pseudocode):
// after receiving topic from frontend
const metadata = JSON.stringify({ custom_instructions: userText });
await dispatchClient.createDispatch("room-name", "agent-name", { metadata });
• Agent entrypoint (pseudo-Python):
async def entrypoint(ctx: JobContext):
metadata = json.loads(ctx.job.metadata or "{}")
instr = metadata.get("custom_instructions", "You are a helpful assistant.")
session = AgentSession(
llm=google.realtime.RealtimeModel(model="gemini-2.5-flash", instructions=instr),
...
)
await session.start(room=ctx.room, agent=...)
await ctx.connect()
Practical tips
• Ensure backend completes the dispatch (with metadata) before the client joins the room so the agent starts with instructions in place.
• Keep instructions concise; summarize or chunk large content.
• Sanitize/redact user input as needed before embedding into instructions.
If you want, tell me which backend language or SDK you use and I’ll give a concrete code snippet you can drop in.
Sources: Agent dispatch | LiveKit docs | Job lifecycle | LiveKit docs | Context Variables | LiveKit docspowerful-magician-63563
12/26/2025, 4:27 PMtall-airline-16756
12/26/2025, 4:27 PMctx.job.metadata during its entrypoint, so the agent can set instructions before calling ctx.connect().
• Guaranteed timing: the agent receives the instructions before it joins the room, avoiding race conditions where the agent starts without the right context.
• Intended pattern: dispatch metadata is the explicit mechanism for passing session-level configuration to agents on LiveKit Cloud.
• Cleaner security/control: your backend controls and validates the instructions before dispatching.
Why room.localParticipant.set(metadata) is less suitable for this use case
• Participant metadata is propagated over the room and is meant for participant-level info, not guaranteed startup config for agents.
• Timing/race risk: the agent may already be initialized before that metadata arrives or before the agent reads participant attributes.
• Less direct for agents: the agent entrypoint reads job metadata easily; reading participant metadata would require extra logic to watch for updates and may complicate startup flow.
When participant metadata can be useful
• Passing per-user presence info, display names, or transient participant attributes that both clients and the agent can read during an ongoing session.
• Small live updates mid-call (though agents may still need explicit handling to consume them).
Recommendation
• Use dispatch metadata for session-start instructions (set instructions from ctx.job.metadata).
• Use participant metadata only for user/participant-level state or non-critical live updates.
If you want, tell me whether you need to support updating instructions before the user joins the room (but after dispatch) or to change them mid-session — I can show exact code patterns for safe ordering or for listening to participant metadata changes.