lively-horse-90722
03/09/2026, 8:11 AMtall-airline-16756
03/09/2026, 8:11 AMtall-airline-16756
03/09/2026, 8:12 AMagent.update_chat_ctx() (or the equivalent method your agent exposes).
• Ensure the next LLM invocation reads the agent’s current ChatContext so the model sees the new system message.
Why this works
• Updating the agent’s chat context replaces or augments the system-level instructions the model uses when generating the next response, so the new instructions are applied immediately after the function call.
Example (Python-style pseudocode)
1. Update instructions after function call:
@function_tool()
async def set_system_instructions(self, context: RunContext):
# New system instruction you want the LLM to follow
new_instructions = "You are now in expert mode. Provide detailed technical advice."
# Build an updated ChatContext — include the new system message first
updated_ctx = ChatContext()
updated_ctx.add_message(role="system", content=new_instructions)
# Optionally re-add prior conversation so history is preserved
for msg in self.chat_ctx.get_messages():
updated_ctx.add_message(role=msg.role, content=msg.content)
# Persist the updated context so the next LLM turn uses it
await self.update_chat_ctx(updated_ctx)
return "Instructions updated successfully."
Implementation notes and tips
• If you only need to append a system message, you can add it to the existing ChatContext instead of recreating it.
• Keep system messages at the top of the context so they take precedence when the LLM constructs its next response.
• If the agent or runtime caches context, ensure update_chat_ctx triggers whatever sync is needed so the next model call reads the new context.
• Test by invoking a simple follow-up prompt immediately after the function returns to confirm the model honors the new instructions.
If you’d like, tell me:
• Which SDK or language you’re using (Python, Node, etc.), and
• Whether you prefer appending a new system message or replacing the existing one.
I’ll provide a tailored code snippet you can drop into your agent.
Sources: Pipeline nodes and hooks | LiveKit Documentation | Testing and evaluation | LiveKit Documentationlively-horse-90722
03/09/2026, 8:14 AMtall-airline-16756
03/09/2026, 8:14 AM@function_tool()
async def set_system_instructions(self, context: RunContext):
# 1) Compose the new system instruction
new_system = "You are now in expert mode. Provide detailed technical advice."
# 2) Build an updated ChatContext with system message first
updated_ctx = ChatContext()
updated_ctx.add_message(role="system", content=new_system)
# 3) Re-add prior conversation in order (optional but recommended)
for msg in self.chat_ctx.get_messages():
updated_ctx.add_message(role=msg.role, content=msg.content)
# 4) Persist the update and await it so it finishes before this function returns
await self.update_chat_ctx(updated_ctx)
# 5) Return something the caller can inspect if needed
return "ok"
How to verify it applied immediately
• After the function returns, explicitly call the agent/LLM for the next reply only after awaiting the function result.
• Log or inspect the agent’s current chat context immediately after await self.update_chat_ctx(...) to confirm the system message is present.
• If you call the LLM from a different coroutine/task, ensure that coroutine starts only after the update completes.
Diagnostic questions (so I can help further if the pattern above doesn’t fix it)
• Are you calling the next LLM turn from the same process/thread as the update, or from a separate worker/process?
• Do you use any local caching of chat_ctx or keep a copy of it in memory that might be stale?
• Are you sure await self.update_chat_ctx(...) is being executed (no exceptions swallowed)?
• Which exact Python SDK method are you using to send the next user prompt / trigger the next LLM response?
If you share a short snippet showing:
• the function/tool that performs the update, and
• how you trigger the next LLM call right after the function returns,
I’ll point out exactly where timing or ordering needs to change and give a targeted fix.lively-horse-90722
03/09/2026, 8:17 AMupdate_chat_ctx and update_instructions ? I am using update_instructions.tall-airline-16756
03/09/2026, 8:18 AMupdate_instructions changes the system prompt itself, so the LLM will use the new instructions on the very next generation once that call completes.
• update_chat_ctx modifies the stored chat history. It should also take effect immediately if you await it and the next LLM call reads the latest chat context — but if you’re seeing a one-turn delay, it’s often because the context update wasn’t awaited, a stale cached copy of the context was used, or the next LLM call started before the update finished.
Which to use for your goal
• If your goal is to change the LLM’s behavior or role (for example: “now respond as an expert”): use update_instructions.
• If your goal is to inject new conversational content or persist data into the conversation history (for example: saving answers collected during a function call so the model references them later): use update_chat_ctx.
Practical tips to ensure immediate effect
• Await the update call (e.g., await agent.update_instructions(...) or await agent.update_chat_ctx(...)) so the update completes before returning from the function.
• After awaiting, trigger the next LLM request only once the update call has finished.
• If you use update_chat_ctx, ensure you update the in-memory/chat object you use to build the next prompt so no stale cached version is sent.
• If you need the model to change behavior right away, prefer update_instructions because it directly replaces the system prompt.
If you want, share the short snippet where you call update_instructions and then trigger the next LLM turn — I’ll point out any ordering or awaiting issues and give a tiny edit to guarantee the update takes effect immediately.
Sources: Building an Automated IVR Menu Caller | LiveKit Documentation | Interrupt User | LiveKit Documentation | Agents and handoffs | LiveKit Documentationlively-horse-90722
03/09/2026, 8:20 AMawait update_instructions but the chat context is not updated in the very next time, though it gets updated afterwardstall-airline-16756
03/09/2026, 8:21 AMawait update_instructions(...) but the very next model response still uses the old context and only reflects the new instructions one turn later. That’s frustrating. I’ll explain exactly why that happens and give two concrete, minimal fixes you can apply in Python so the change is effective immediately.
Why this happens (short)
• update_instructions changes the agent’s system-level prompt for future turns, but it does not automatically re-inject that new prompt into an already-prepared/queued LLM generation. If the next generation was started (or the session context was prepared) before the instruction update finished, that generation will still use the old instructions.
Quick checklist (confirm these)
• You are awaiting the call: await self.update_instructions(...).
• You are not starting the next LLM call from a different coroutine/task that began before the await finished.
• You are not relying on a cached copy of chat_ctx when building the next prompt.
Two concrete ways to guarantee immediate effect
Option A — Rebuild and update the chat context (recommended for immediate, deterministic effect)
• Add the new system instruction as the first message in a rebuilt ChatContext, persist it with await self.update_chat_ctx(...), then call the LLM.
• This ensures the next generation sees the new system message because you control exactly what is sent.
Example pattern:
@function_tool()
async def my_tool(self, context: RunContext):
new_instr = "You are now in expert mode. Provide detailed, technical answers."
# Rebuild ChatContext with the new system message first
new_ctx = ChatContext()
new_ctx.add_message(role="system", content=new_instr)
# copy prior non-system messages in order
for msg in self.chat_ctx.get_messages():
if msg.role != "system":
new_ctx.add_message(role=msg.role, content=msg.content)
# persist and await so it completes before next generation
await self.update_chat_ctx(new_ctx)
# now generate the next reply — it will use the updated context
await context.session.generate_reply("Please respond under new instructions.")
Option B — Use update_instructions but ensure the next generation starts only after the update completes
• If you want to use update_instructions, make sure you do not trigger or allow any LLM call to start until the update has fully completed and the session/agent has refreshed.
• That often means: await update_instructions(), then return from the tool and let the next user/agent turn occur (or explicitly trigger the follow-up only after the await completes).
Pattern:
@function_tool()
async def my_tool(self, context: RunContext):
await self.update_instructions("You are now concise and formal.")
# Do NOT start a generation here in the same event loop tick
return "instructions-updated" # let the next cycle perform the generation
Extra diagnostic pointers (if it still lags)
• Confirm the next LLM call is created after the await, not started concurrently in another task.
• Log the agent/session chat context immediately after the await to confirm the new instruction is present.
• If you use worker processes or multiple agent instances, ensure you update the same agent/session that will do the next generation.
• If you do rebuild chat context, put the new system message at the top so it takes precedence.
If you want, share a minimal snippet showing:
• where you call await update_instructions(...), and
• how/where you immediately trigger the next LLM call
I’ll point to the exact line to change so the new instructions take effect in the very next response.
Sources: Building multi-agent architectures with LiveKit agents | LiveKit | Agents and handoffs | LiveKit Documentation | Building an Automated IVR Menu Caller | LiveKit Documentationlively-horse-90722
03/09/2026, 8:23 AMtall-airline-16756
03/09/2026, 8:23 AMawait update_instructions(...), and
2. Immediately trigger the next LLM generation (for example context.session.generate_reply(...), agent.generate_reply(...), send_user_message(...), or similar).
Please paste those 8–20 lines (the function/tool and the immediate follow-up call). I’ll mark the exact line to change and give the minimal edit you should apply so the new instructions take effect in the very next response.