Instruction profiles: a pickable brain-style for your agent
An agent's instructions are assembled from composable blocks, so an agent can offer more than one set of them and let a user choose which drives a conversation — an instruction profile, picked like a model, bounded by the admin.
An agent's instructions are not one fixed wall of text. They are assembled from composable blocks — a protocol block, a workspace block, an exec block, a citations block. Because they are composable, an agent can offer more than one set of them, and let a user choose which set drives a conversation — exactly like choosing a model. We call an offered set an instruction profile.
Blocks compose into named sets
The same blocks can compose a full, thorough instruction body or a distilled one that keeps every hard rule and drops the restatements and long examples. Each named set is a profile with an id.
Distillation is not summarization: every load-bearing signal — exact tool ids, parameter orders, path grammar, the plan-ack markers, the exec contract — is preserved. What leaves is the prose a large hosted model can afford but a small local one pays for in seconds of prompt evaluation.
The user picks one, per conversation
An agent declares its profiles in config, and the pick lives beside the model pick in the same capabilities picker. The admin declares the ceiling — which profiles exist and which is the default — and the user chooses one for a conversation.
react:
default_agent:
instruction_profiles:
default: full
options:
- { id: full, label: Full }
- { id: extra-lite, label: Extra Lite (local models), blocks: [ "xlite:workspace_exec" ] }
Choosing a profile switches the system prompt, so the runtime treats it with the same care as a model switch — the change lands on the user's cold-cache policy, not silently mid-conversation.
The contract is id-only
The wire and the picker carry only { id, label, description }. What an id
resolves to — a distilled block set, an inline body, a stored custom set, or the platform
default — never crosses that boundary. That keeps the surface framework-neutral: any agent
kind can declare its own ids, and ids now do gain versions (next section)
while the built-in sets ship with the platform.
agent config wire / picker runtime
───────────── ───────────── ───────
id + blocks/body ──▶ id + label ──▶ resolve id → instructions
(the content) (only this) (behind the boundary)
Sets became authorable artifacts
The composable-blocks story now runs end to end. Each building block carries its meaning as data: the signals it protects (“no success claims without visible proof”, “the catalog is the authority on callable tools”), semantic tags that reflect those signals, and its token weight — so blocks are distinguishable and comparable before anything is composed.
A custom set is an ordered list of blocks, set refs, and literal text, stored under a slug with immutable versions:
instr:custom:support-tone:3 pinned — always resolves to version 3
instr:custom:support-tone latest — resolves to the newest active
An edit creates the next version; retiring flips status, and a pinned ref keeps resolving
even after retire — a running agent never breaks because an administrator cleaned up. Sets
may reference other sets (and the built-in instr:profile:* sets), so a team's
house rules compose with the platform distillations instead of forking them.
Authoring happens in a constructor: a searchable block library (by name, signal, or tag; a click shows the block's signals and full text), and beside it the composed instruction rendering continuously — segmented per source block, each segment carrying its token weight, with the total on top. What you review is byte-for-byte what an agent would receive, weights included.
Assigning a set to an agent
A saved set (or a built-in one) wires into any app's agent directly from the
constructor: pick the app, pick the agent, and the set becomes one more option in that
agent's instruction_profiles — user-pickable immediately, optionally as the
default. The id-only contract from above is what makes this a one-step operation: the
agent's picker just gained an id.
Why it exists
Two agents with the same tools do not always want the same instructions. A hosted model can read the full body; a serving-constrained local model needs the lean one; a specialized workflow may want a stripped protocol with one extra rule. Profiles make that a declared, user-visible choice instead of a fork of the agent — one agent, several brain-styles, picked per conversation and bounded by the admin.
The full picture
This entry owns the choice: which instruction body drives a conversation and where bodies come from. Its companions each own one aspect of the same machine: the input's anatomy (what the model input is made of), signal parity (how three sizes keep the same rules), and roster conditioning (how the agent's tools decide what the instruction teaches).
Documentation on GitHub
The live docs behind this entry: