is there a difference between the instructions par...
# ask-ai
a
is there a difference between the instructions parameter and a chat_ctx item in agents? Will this chat_ctx have priority over the instructions?
Copy code
class Assistant(Agent):
    def __init__(self, config: AssistantConfig):
        chat_ctx = ChatContext()
        chat_ctx.add_message(
            role="system",
            content=SYSTEM_INSTRUCTIONS,
        )

        super().__init__(
            instructions=USER_INSTRUCTIONS,
            tools=config.tools,
            allow_interruptions=True,
            chat_ctx=chat_ctx
        )
✅ 1
t
Thanks for reaching out, Ahron. I'm an AI assistant and I'm here to help. Give me a moment while I research this topic.
Thanks — great question. You're asking whether
instructions
and a
chat_ctx
system message conflict and which takes priority in your example. Short answer: they both end up as system messages, so they stack rather than one overriding the other. What happens in your code • You create a
ChatContext
and add a system message with
SYSTEM_INSTRUCTIONS
. • You then call the
Agent
constructor with
instructions=USER_INSTRUCTIONS
and pass your
chat_ctx
. • The constructor will add a system message from
instructions
in addition to the system message already in
chat_ctx
. Result • Your prompt will contain two system messages: a. The system message you added to
chat_ctx
(
SYSTEM_INSTRUCTIONS
) b. The system message created from
instructions
(
USER_INSTRUCTIONS
) • They do not replace one another — they both appear in the context. That can lead to ambiguous or conflicting guidance for the model. Recommended approach • If you build a custom
chat_ctx
that already includes the system message(s), omit the
instructions
parameter and put all needed system-level guidance into
chat_ctx
. • If you prefer the convenience of
instructions
, pass it and let the Agent construct the system message, and avoid adding a separate system message to
chat_ctx
. • If you need to combine instructions carefully, keep them in a single system message (in
chat_ctx
) so the ordering and wording are explicit. If you'd like, I can: • Show a small code example that uses only
chat_ctx
, or • Show a version that uses only
instructions
, or • Help you merge
SYSTEM_INSTRUCTIONS
and
USER_INSTRUCTIONS
into one clear system message. Which of those would be most helpful? Sources: Agents and handoffs | LiveKit Documentation, with interactive elements
a
I have a user provided instructions and system instructions for polices and guardrail
t
Thanks — that helps. You're asking how to keep user-provided instructions and separate system instructions (policies/guardrails) working together without creating conflicts. Here’s a clear, practical way to handle that. Summary of behavior • Both
instructions
and any
system
message you add to
chat_ctx
become system messages in the prompt. They do not override each other — they both appear and therefore can conflict or confuse the model if not coordinated. • To avoid ambiguity, treat all policy/guardrail content as a single, explicit system message rather than splitting it between
instructions
and another system message. Recommended approaches • Preferred (clear and explicit) ◦ Put all policy and guardrail content into one system message inside
chat_ctx
. Do not pass
instructions
to the Agent constructor. ◦ This gives you full control of wording and ordering so the model will see one authoritative set of system-level rules. Example pattern: 1. Create
ChatContext
. 2. Add a single
system
message containing both high-level policy and any operational guardrails. 3. Pass that
chat_ctx
to the Agent and omit
instructions
. • Alternative (convenience) ◦ Use
instructions
alone (no system messages added to
chat_ctx
). This is simpler if you only have one source of system-level instructions and don’t need extra messages in the context. ◦ Avoid adding another system message to
chat_ctx
in this case. • Combining carefully (when you must) ◦ If you must combine both, merge them into one system message before adding to
chat_ctx
so the effective instruction text is deterministic. ◦ If you cannot merge, ensure the system messages are complementary and that the policy/guardrail message appears first and clearly states that it takes precedence. Practical tips for policy/guardrails • Make the system message explicit about priority: e.g., start with “System policy — must follow:” and list rules. • Keep guardrails short, numbered, and unambiguous (e.g., “Do not disclose PII,” “Always refuse X,” “When X occurs, respond with Y”). • If you need user-facing behavior that changes per conversation, keep that as
user
messages in
chat_ctx
or as tool configuration rather than adding more system-level texts. If you want, I can: • Show a code example that merges your
SYSTEM_INSTRUCTIONS
and user-provided policy text into a single
system
message in
chat_ctx
, or • Review your existing
SYSTEM_INSTRUCTIONS
and
USER_INSTRUCTIONS
and suggest how to consolidate them into one clear guardrail message. Which would you prefer? , with interactive elements
a
I need 2 levels of instructions give an example of the best approach using python
t
Thanks — I’ll show a concise, practical Python example that keeps two levels of instructions (1) system-level policies/guardrails and (2) user-provided instructions, while avoiding ambiguous duplicate system messages. Key idea • Put all non-changing policy/guardrail text in a single system message inside
ChatContext
. • Put user-provided instructions as a
user
message (or agent
instructions
only if you prefer convenience, but not both). • This keeps the system-level rules authoritative and the user instructions visible and separate. Example (best practice)
Copy code
# Pseudocode / illustrative example using LiveKit-like Agent and ChatContext APIs

SYSTEM_POLICY = """
System policy (must follow):
1. Never disclose personal or sensitive data.
2. If asked to perform an action that violates policy, refuse and provide a safe alternative.
3. Always follow legal and safety constraints.
"""

# Instructions the user of the assistant provides to shape helpful behavior
USER_INSTRUCTIONS = """
You are a helpful assistant for customer support. Be concise, friendly, and provide step-by-step troubleshooting.
When unsure, ask clarifying questions before making assumptions.
"""

from livekit.agent import Agent, ChatContext, AssistantConfig  # adjust imports to your SDK

# 1) Build a ChatContext with one explicit system message containing policy/guardrails
chat_ctx = ChatContext()
chat_ctx.add_message(role="system", content=SYSTEM_POLICY)

# 2) Add the user-provided instructions as a user message (keeps them separate and editable per conversation)
chat_ctx.add_message(role="user", content=USER_INSTRUCTIONS)

# 3) Construct your Agent without passing the `instructions` parameter (avoid duplicate system messages)
config = AssistantConfig(tools=[...], allow_interruptions=True)  # fill with your config
assistant = Agent(config=config, chat_ctx=chat_ctx)

# 4) Start or run a conversation — subsequent user prompts can be added dynamically
assistant.chat_ctx.add_message(role="user", content="Hi—help me triage a failed room connection.")
response = assistant.run()  # or whichever method triggers the agent to produce output
print(response)
Why this pattern works • The system policy is a single, explicit source of guardrails and is always present at the highest priority level. • User-provided instructions are kept as user messages so they can be changed per session and do not create competing system-level directives. • You avoid having two system messages (one from
instructions
and one in
chat_ctx
) which can produce ambiguous model behavior. Variants • Convenience-only: If you prefer convenience and have no custom system policy, pass
instructions=USER_INSTRUCTIONS
into the Agent constructor and omit any system messages in
chat_ctx
. • Merged-single-system: If you want everything at system level (not recommended if user instructions must be adjustable per-session), combine policy and user-instructions into a single system message in
chat_ctx
and omit
instructions
. If you want, I can: • Convert the example to the exact function/class names in your SDK version, or • Show an example where user instructions are passed via
instructions
while ensuring the system policy remains authoritative (by merging policy into that single
instructions
value). Which would you prefer?, with interactive elements
a
Does instructions under the hood only become a chat_ctx item or it has more to it?
t
Good question — I’ll clarify. Short answer •
instructions
is a convenience: it is turned into a
system
message and added to the
ChatContext
under the hood. It does not create a separate hidden instruction channel with special runtime behavior beyond becoming a system message. Details and useful nuances • When you pass
instructions
to the Agent constructor, the Agent creates a
system
-role message from that string and adds it to the
ChatContext
. • If you also pass a pre-built
chat_ctx
that already contains system messages, the
instructions
-created system message will be added in addition to those messages (i.e., they stack). •
ChatContext.copy()
will include instructions unless explicitly excluded (so copies propagate that system message unless you opt out). • Because
instructions
ends up as a normal system message, it follows the same ordering and precedence rules as any other system message in the context. There is no extra runtime priority applied to
instructions
beyond being a system-role message. Practical implication • Treat
instructions
the same as any other system message when reasoning about ordering and potential conflicts. If you need authoritative, unambiguous guardrails, put them in a single explicit system message in
chat_ctx
(and omit
instructions
) or merge your texts before adding them. If you want, I can show: • A tiny code snippet that demonstrates the stacking behavior, or • How to explicitly exclude instructions when copying a ChatContext so you don’t duplicate system messages. Which would be most helpful? , with interactive elements
a
can you point out to me where in the source code instructions becomes a chat_ctx item?
t
Thanks — I can help locate where
instructions
becomes a
chat_ctx
message and explain what to look for in the source. Short answer • The
instructions
string is converted into a
system
-role chat message and added to the
ChatContext
during Agent initialization. You should look in the Agent constructor (or the function that builds/initializes
self.chat_ctx
) for the logic that creates a `ChatMessage`/system message from the
instructions
parameter. Where to look in the repo • Open the Agent implementation file (search for the
Agent
class or
Agent.__init__
). • Search inside that file for occurrences of
instructions
,
chat_ctx
,
ChatContext
, or code that constructs a message with
role="system"
(e.g.,
ChatMessage(role="system", content=...)
). • Also check any helper or factory functions that build or normalize the chat context (names like
build_chat_context
,
initialize_chat_ctx
, or
copy()
methods on
ChatContext
). What you’ll typically find • A branch that checks if
instructions
is provided. • Creation of a message object with role set to
system
and content set to the
instructions
string. • Appending or inserting that message into
self.chat_ctx
(or passing it to
ChatContext
constructor). • A
ChatContext.copy()
implementation that copies messages and typically includes system messages unless
exclude_instructions=True
is passed. If you want, I can: • Point to the exact file and line if you tell me which repository URL and branch/tag (for example,
main
or a specific SDK version) you’re using. • Or, if you prefer, I can show a short illustrative snippet of the exact pattern to expect (how the constructor turns
instructions
into a
system
message). Which would you like? Sources: Function tool definition | LiveKit Documentation | Agents and handoffs | LiveKit Documentation | Context Variables | LiveKit Documentation | Build Your First AI Voice Agent in Python: Complete Tutorial | LiveKit, with interactive elements
a
can you tell me which file?
t
Thanks — I can point you to the exact file, but I need one detail first. Which SDK/repo and version are you using so I can locate the right source file? Please provide one of the following: • The repo and language/SDK (for example: "livekit/agents Python SDK" or a GitHub URL), and the branch or tag (e.g.,
main
,
v1.2.3
), or • Whether you installed from PyPI (and if so, run and share the output of:
Copy code
python -c "import livekit; print(livekit.__file__, getattr(livekit, '__version__', 'no-version'))"
) • Or if you have a cloned source tree, the local path to the file that contains
Agent
(or paste your
Agent.__init__
snippet). Once you tell me which package/repo and version (or provide the small diagnostic output), I’ll point to the exact file and show the lines where
instructions
is converted into a
system
-role
ChatContext
message. , with interactive elements
a
show me the latest version
t
Thanks — I can point you to the file you should inspect in the latest LiveKit Agents SDK and summarize what to look for. Where to look (latest version) • Repository: https://github.com/livekit/agents • Primary file to inspect: livekit-agents/livekit/agents/agent.py What to look for in that file • The Agent constructor (
Agent.__init__
or equivalent) — search for the parameter name
instructions
. • Code that creates a chat message with role
"system"
(look for
ChatMessage(... role="system" ...)
or similar). • Logic that appends or inserts that message into the agent's
chat_ctx
(or calls a helper like
build_chat_context
or
initialize_chat_ctx
). • Any
ChatContext.copy()
implementation that mentions including or excluding instructions (e.g., flags like
exclude_instructions=True
). Why this is the right place • The Agent class is where initialization parameters are normalized into the conversation state. The SDK adds
instructions
as a
system
-role message inside the agent’s
ChatContext
during initialization, so the creation and insertion happen in the Agent implementation. If you want, I can: • Show an illustrative snippet that demonstrates the exact pattern to expect (how
instructions
is wrapped into a
system
ChatMessage and added to
chat_ctx
), or • If you tell me the branch or tag you’re using (for example
main
or a release tag), I can point to the exact lines in that file. Which would you prefer? Sources: Agents and handoffs | LiveKit Documentation | Function tool definition | LiveKit Documentation | Build a salary negotiation coach with a LemonSlice avatar | LiveKit, with interactive elements