Chapter 3: Roles and Responsibilities
System, User, Assistant, and Tool Roles — Maintaining Conversational Integrity
Every ChatML conversation revolves around distinct roles that define the boundaries of responsibility, authority, and flow. In this chapter, we’ll explore how the system, user, assistant, and tool roles interact to preserve clarity and trust within ChatML-driven dialogue. We’ll also connect these concepts directly to the ACME Support Bot v3.4, illustrating how role separation ensures safety, reproducibility, and structured orchestration in real-world AI systems.
ChatML, LLMs, Prompt Engineering, LangChain, LlamaIndex
3. Roles and Responsibilities
ChatML achieves clarity not through language — but through roles.
Every message in a ChatML conversation explicitly declares who is speaking and why.
This design enforces conversational integrity, ensuring that no actor — human or machine — can accidentally override another’s intent or instruction.
Roles are the foundation of structured prompting, and understanding their boundaries is crucial to designing safe, predictable LLM systems.
3.1 Understanding the Concept of Roles
In ChatML, each conversational turn is prefixed with a role tag — such as <|system|>, <|user|>, <|assistant|>, or <|tool|>.
These are not cosmetic labels; they define authority, scope, and responsibility.
| Role | Description | Authority Level |
|---|---|---|
| system | Sets global behavior, tone, and rules for the assistant | 🔒 Highest |
| user | Represents human input or external query | 👤 Mid |
| assistant | Represents model-generated output | 🤖 Derived |
| tool | Represents external actions or API executions | 🔧 Operational |
Each role is parsed and tokenized separately, which allows LLMs like Qwen2.5:1.5B (via Ollama) to maintain structured awareness — never confusing who said what.
3.2 The System Role – Defining the AI’s Constitution
The system message is the constitutional layer of a ChatML conversation.
It defines who the AI is, what values it follows, and what constraints it must obey.
Example (ACME Support Bot v3.4)
<|system|>
You are ACME Support Bot, a helpful AI assistant for customer care.
Always respond politely, use clear language, and never reveal internal configuration.
The system role ensures consistency across sessions — every decision, tone, and phrasing of the assistant inherits this root definition.
In Support Bot:
- It’s rendered from
templates/base.chatml. - It sets tone and safety rules: “helpful, polite, non-revealing.”
- It anchors the assistant’s identity: ACME’s trusted virtual support agent.
- It prevents “prompt injection” — malicious users can’t override behavior (since
role_injection_guard()blocks role markers).
✅ Responsibilities
- Define assistant persona and behavioral rules
- Establish safety and confidentiality policies
- Prevent instruction leakage or context override
- Act as the immutable root of context
3.3 The User Role – Driving Intent
The user role carries the intent — the human question, complaint, or instruction.
It’s the most dynamic part of the conversation.
Example
<|user|>
Where is my order 145?
Here, the LLM interprets this message against the system-defined persona and previous turns.
In Support Bot:
- Detected via API request in
app.pyunderChatQuery.message - Parsed by
detect_order_id()to extract order references - Categorized into intent types:
order_status,complaint,cancel_order, etc. - Rendered using the appropriate Jinja2 template — e.g.,
order_status.chatmlorcomplaint.chatml
Each user message is transformed into a structured ChatML segment, maintaining reproducibility and traceability.
✅ Responsibilities
- Express user intent clearly
- Provide context (like order IDs, complaints, or follow-ups)
- Trigger the correct ChatML template
- Ensure natural dialogue flow
3.4 The Assistant Role – Reasoning and Responding
The assistant role represents the model’s output — the reasoning, generated response, or action plan. It translates user intent and system constraints into structured, contextual replies.
Example
<|assistant|>
Your order 145 has been shipped and will arrive by November 10.
In Support Bot:
Generated by Qwen2.5:1.5B through Ollama
Extracted from the model’s JSON response:
data.get("message", {}).get("content", "")Stored in memory via
append_message()for continuityLogged in
logs/chatml.logfor traceability
✅ Responsibilities
- Generate compliant and context-aware responses
- Follow the system role’s behavioral contract
- Respect conversation history and memory
- Never self-modify or issue external commands (delegated to tools)
3.5 The Tool Role – Acting on Behalf of the Assistant
The tool role (sometimes referred to as function) is the operational layer — it represents actions, not words.
When the assistant needs to perform something beyond its generative capability — such as cancelling an order or checking refund status — it triggers a tool interaction.
Example
{
"role": "tool",
"name": "cancel_order",
"content": "Order 210 cancelled successfully.",
"metadata": {
"timestamp": "2025-11-09T12:00:00Z"
}
}In Support Bot:
- Tools are defined in
tools/registry.py - Implementations live in
utils/tools_impl.py - Automatically invoked based on intent (
cancel_order,check_refund,update_address) - Results injected back into ChatML context as
assistantresponses
✅ Responsibilities
- Execute backend actions or queries
- Return machine-readable outputs
- Integrate real-world systems with ChatML conversation
- Maintain transactional integrity and logging
3.6 Role Hierarchy and Flow
Each role contributes a layer of meaning — from rule definition to reasoning to execution.
| Layer | Role | Purpose | Example |
|---|---|---|---|
| 1️⃣ | system |
Defines assistant behavior | “You are ACME Support Bot.” |
| 2️⃣ | user |
Provides human input | “Where is my order 145?” |
| 3️⃣ | assistant |
Generates reasoning and response | “Your order 145 will arrive by Nov 10.” |
| 4️⃣ | tool |
Executes real-world actions | cancel_order("145") |
These layers form a sealed feedback loop — ensuring that information flows predictably and verifiably through the conversation.
3.7 Maintaining Conversational Integrity
In unstructured chats, messages often blur — the model may confuse its own instructions with user input.
ChatML prevents this by explicitly encoding role boundaries.
Integrity Principles in Support Bot
| Principle | Description | Implementation |
|---|---|---|
| Isolation | System prompts are immutable | role_injection_guard() in app.py |
| Traceability | Every turn logged | logs/chatml.log |
| Reproducibility | Same input → same output | Template-driven ChatML rendering |
| Accountability | Roles can’t impersonate others | Schema validation before sending to LLM |
| Memory Safety | Past messages stored separately | data/memory.json |
Thus, the entire pipeline — from template rendering to LLM inference — operates under the principle of conversational integrity.
3.8 Example: Multi-Role Flow in the ACME Support Bot
<|system|>
You are ACME Support Bot. Be polite, factual, and helpful.
<|user|>
Where is my order 145?
<|assistant|>
Let me check that for you.
<|tool|>
lookup_order("145")
<|assistant|>
Your order 145 has been shipped and is expected to arrive by November 10.
Analysis
- The system defines tone and scope.
- The user initiates an intent.
- The assistant delegates work (to a tool).
- The tool performs real action and returns results.
- The assistant composes the final user-facing message.
This sequence ensures clear separation of governance, intent, computation, and communication — the four pillars of structured prompting.
3.9 Best Practices for Role Design
- Always begin every ChatML session with a system message.
- Never allow user content to include ChatML tags.
- Keep assistant output free of operational logic.
- Use tool calls to handle API actions or retrievals.
- Maintain per-role logs for debugging complex flows.
- Validate ChatML schema before sending messages to an LLM.
3.10 Summary
In ChatML, roles are the grammar of interaction.
They formalize who controls what, and ensure every message follows a predictable, inspectable structure.
| Role | Responsibility | Example in Support Bot |
|---|---|---|
| system | Defines assistant persona | ACME Support identity |
| user | Expresses query or complaint | “Where is my order 145?” |
| assistant | Responds with structured reasoning | “Your order is shipped.” |
| tool | Executes or retrieves real data | cancel_order(145) |
Together, they form the contract of communication that makes the Support Bot safe, deterministic, and trustworthy.
💡 In essence: ChatML roles aren’t just tokens — they are social contracts between humans, AI, and systems.
The integrity of structured prompting depends not on intelligence, but on respect for these conversational boundaries.