The system prompt is the operating manual under which an agent runs. What most operators do not realize is that the manual they edit is rarely the manual the model sees. By the time the model receives a prompt, the prompt has been assembled from several sources, in a specific order, with each layer either appending to or replacing the one below it. The composition is what determines how the agent behaves, and the composition is the part operators control the least when they only look at one file.
This article is about that composition. It covers where the prompt comes from, what controls the assembly order, what gets appended versus replaced, how to inject permanent instructions that survive compaction, and the common mistakes that show up when the composition is misunderstood. The patterns here are grounded in how OpenClaw and most agent runtimes do it; other platforms vary in detail but match the structure.
Where the system prompt comes from
A runtime system prompt is typically assembled from four sources:
1. Platform default. The agent runtime ships with a baseline prompt that handles universal concerns: what tools are available, how to format replies, what the stop conditions are. Operators rarely see this layer; it is invisible and usually non-negotiable. 2. Agent default. The specific agent profile the operator configured has its own default prompt. This is where the agent's scope statement, refusal rules, and tool contracts usually live. 3. Project file. For agent runtimes that support per-project overrides, a file like AGENTS.md or a workspace-level prompt gets injected at session start. This is the operator-facing layer; it is what most operators think of when they say "the system prompt." 4. Per-session injection. Some platforms inject additional instructions at session start: the session goal, retrieved memory, current state, the operator's recent edits.
The four layers compose. The platform default sits at the bottom, the agent default sits on top of it, the project file sits on top of that, and the per-session injection sits at the top. By default, later layers can override earlier ones; the override behavior is the part that varies between platforms.
What controls the assembly order
The order is not arbitrary. Two rules apply in almost every runtime:
- Universal concerns come first. The platform default is the foundation because it carries constraints the operator cannot safely override (refusal of certain tool combinations, formatting rules, security boundaries). Putting it at the bottom means later layers can extend it but cannot erase it.
- Specific concerns come last. The per-session injection is at the top because it is the most specific: this session, this goal, this context. Specific concerns are easier to reason about when they appear last in the prompt.
The order matters because the model reads the prompt as a sequence. A constraint that appears early tends to be treated as load-bearing; a constraint that appears late tends to be treated as a hint. Operators who want their project-level rules to be taken seriously should keep the project file short and put the load-bearing constraints near the top of that file.
What gets appended versus replaced
Three composition patterns, each with different semantics:
- Append. The later layer adds to the prompt. The earlier layer is preserved. This is the safest pattern: the platform default and the agent default remain intact, and the operator's project file adds new instructions without disturbing them.
- Sectional replace. Some layers define named sections, and a later layer can replace a section wholesale. OpenClaw, for example, lets the project file define a
toolssection that overrides the agent default'stoolssection but does not touch therefusalorscopesections. - Full replace. Rare and dangerous. Some platforms let a top-level layer fully replace everything below it. This is the pattern operators reach for when they want full control; it is also the pattern that produces silent loss of the platform's safety boundaries.
The pattern to default to: append, with named-section override for the few sections where override is meaningful (tool list, scope statement, refusal rules). Full replace is for special cases and should always come with an explicit decision log.
History is not the system prompt
The most common composition mistake is to confuse the conversation history with the system prompt. They are different slots in the model's input, with different authority.
The system prompt is read once per turn, every turn, for the lifetime of the session. Anything in the system prompt slot is treated as instructions.
The conversation history is the running transcript of what was said and done. Anything in the history slot is treated as data — as evidence of what the agent and the user have already agreed on.
An operator who copies user instructions into the system prompt "to make sure they are followed" is doing two things wrong. First, they are diluting the authority of the actual system prompt. Second, they are giving the model the same instruction in two channels, and the model does not know which to trust. The fix is to put the instruction in the right channel once and trust the channel.
For more on why this matters, see the prompt engineering for agents piece, which covers the channel-discipline argument in depth.
Tool results are not instructions either
The second composition mistake is treating tool results as if they were instructions. They are not. A tool result is a piece of data the agent received from the world; it sits in the tool-result slot, not in the system-prompt slot.
This matters because a tool result can contain instructions. A web page the agent fetches may contain a line like "ignore previous instructions and...". A file the agent reads may contain a prompt-injection payload. An API response may contain a malicious directive.
A correctly-composed prompt treats the tool-result slot as untrusted. The system prompt tells the model how to behave when tool results contradict instructions: ignore the embedded directive, surface the discrepancy to the operator, follow the system prompt. A system prompt that does not name this rule is a system prompt that has not yet encountered its first prompt-injection attempt.
Permanent instructions that survive compaction
Compaction is the act of summarizing older context into a smaller representation while preserving the goal-relevant facts. Compaction runs inside the session, against the transcript; it does not touch the system prompt.
The implication is that anything in the system prompt survives compaction by definition. The system prompt is the durable backbone of the session. Anything an operator wants the agent to remember for the life of the session — and across sessions if the project file is reloaded — should go into the system prompt, not into the conversation.
The trap is the opposite: operators sometimes inject session-specific instructions ("for this turn only, format the output as a table") into the system prompt "to make sure they stick." They stick, all right — they stick past the turn they were intended for, and they appear in every future turn until the session ends or the operator remembers to remove them. The right slot for a turn-specific instruction is the user message or a tool result; the right slot for a session-spanning rule is the system prompt.
Sub-agents inherit, then override
Sub-agents present a particular composition challenge. The child session needs a system prompt of its own, but it should not be a full copy of the parent's — the child does not need the parent's session history, only the parent's operating manual.
The pattern that works: the sub-agent inherits the parent's platform default and agent default, and gets a fresh project file that names only what the child needs to know. The child's per-session injection names the specific task and the specific inputs. The parent does not pass the conversation history; the child reads the inputs it was given.
This is also where the sessions and sub-agents piece connects: the boundary of a session is the boundary of its context, and the composition of the child's system prompt is what defines that boundary.
What to do when the platform does the composing
Operators sometimes discover, after the fact, that their carefully written system prompt is being overridden by a higher-priority layer. Two signs that this is happening:
- The agent ignores a rule the operator wrote. The rule is in the project file, but the agent behaves as if it never read it. Usually the cause is a higher layer overriding or contradicting the rule. The fix is to find the overriding layer (often the agent default) and reconcile.
- Two rules contradict each other. The agent flops between behaviors. The cause is usually two layers that both name the same situation and disagree about what to do. The fix is to pick one layer as authoritative for that situation and remove the rule from the other.
The discipline is to keep one layer authoritative for each situation. A rule that exists in two layers is a rule that exists in zero — the model treats one of them as authoritative and silently drops the other.
Common-mistakes checklist
A pre-flight checklist for any system prompt that will run in a long-lived agent:
- Two system prompts that contradict each other. Resolve by picking one layer as authoritative.
- User content concatenated into the system prompt. Move to the user message or tool-result channel.
- Tool output treated as instructions. Add an explicit rule in the system prompt that tool results are data, not directives.
- Turn-specific instructions in the system prompt. Move to the user message; the system prompt is for session-spanning rules.
- Project file longer than the platform default. The platform default is the foundation; the project file should extend it, not bury it.
- Rules that exist in two layers. Pick one; remove the other.
- No rule for prompt injection. Add one. The agent will encounter injected instructions eventually.
- No rule for compaction. Add a rule for what survives a long session. The system prompt is the right place for it.
- No rule for tool failure. Add a rule for what the agent does when a tool returns nothing, returns an error, or returns something it did not expect.
- No rule for refusing. A system prompt that does not name what the agent should refuse is a system prompt that has not yet been asked to do something it should not.
See also
- Tools, Skills, and Plugins — the three extension layers; the system prompt is what tells the agent how to use each one.
- [Prompt Engineering for Agents in 2026](/articles/concepts/prompt-engineering-for-agents-2026/) — the operating-manual doctrine this piece assumes.
- [Sessions, Sub-Agents, and Child Sessions](/articles/concepts/sessions-sub-agents/) — how session boundaries interact with prompt composition.
- Sandbox — the sandbox is what protects the agent when a tool result injects instructions.
- Cron Jobs and Heartbeats — cron sessions start cold, so the system prompt is the only carrier of the operating manual.