Guide
Split your prompts into small, single-responsibility
.mg
components. Wire them together with includes. Build any agent/prompt your team needs without duplicating a line.
When your entire prompt lives in a single file, it becomes harder to understand what each section does as it grows. Team collaboration makes this worse—duplicate a code standards file for different use cases, and now fixes in one won't propagate to the others.
Every team that needs a slightly different agent copies the whole prompt. Shared rules diverge silently — until something breaks in production.
A 400-line prompt file is impossible to review meaningfully. Nobody knows which paragraph sets the tone, which enforces safety, or which is just stale copy.
Changing a shared rule means finding every file that contains it, editing each one, and hoping nothing else was accidentally changed in the surrounding text.
.mg file with a single job. Variables in the frontmatter
make them reusable — the same file works for any team just by passing different values at
include time. if blocks handle variation inside the file so you never need
two nearly-identical copies.
Establishes the agent's identity. Pass a different role_title,
team, and mission and the same file works for any team in
your organisation.
# persona/role.mg
<<
## Role
You are a **${role_title}** on the **${ team }** team.
**Your mission**: ${mission}
You are a trusted expert in your domain. You work with precision,
clarity, and good judgment. You always consider the broader context
before responding.
>>
Sets how the agent communicates. A single file covers every style via
if blocks — no need for five separate tone files.
# style/tone.mg
<< ## Communication Style >>
if style == "professional":
<< Communicate in a professional, polished tone. Be direct, use
precise language, and avoid casual phrasing. >>
elif style == "friendly":
<< Communicate in a warm, approachable tone. Use plain language,
be encouraging, and make the user feel at ease. >>
elif style == "technical":
<< Communicate with technical depth and precision. Use correct
terminology and assume the reader has a strong technical background. >>
elif style == "concise":
<< Be extremely concise. Lead with the answer. No preamble,
no filler. If something can be said in five words, use five words. >>
Injects the live task. The background block is optional — if it's an
empty string the section is omitted entirely, keeping the prompt clean.
# context/context-window.mg
<<
## Task Context
**User request**:
${user_request}
>>
if background != "":
<<
**Background / supporting context**:
${background}
>>
[[ include ]] to pull the components in, passing values inline.
The order is the rendered order — persona first, then style, then task. Different
teams use the same three files with different values and get a completely different agent.
// ── Persona ─────────────────────────────────
[[ components/persona/role.mg
role_title="Support Engineer"
team="Customer Success"
mission="Diagnose and resolve customer
issues with clarity and care." ]]
// ── Style ────────────────────────────────────
[[ components/style/tone.mg
style="friendly" ]]
// ── Task ─────────────────────────────────────
[[ components/context/context-window.mg
user_request="${ticket}"
background="" ]]
@effect run
// ── Persona ─────────────────────────────────
[[ components/persona/role.mg
role_title="Senior Platform Engineer"
team="Platform Engineering"
mission="Review pull requests for
correctness and team standards." ]]
// ── Style ────────────────────────────────────
[[ components/style/tone.mg
style="technical" ]]
// ── Task ─────────────────────────────────────
[[ components/context/context-window.mg
user_request="Review this pull request."
background="${pr_description}" ]]
@effect run
[[ include ]], substitutes variables,
and evaluates if blocks. The agent sees a single, clean prompt — assembled
from the three components — with no trace of the template structure.
The background was an empty string so that section was omitted.
The friendly tone block was selected. All three components merged into one prompt.
## Role
You are a **Support Engineer** on the **Customer Success** team.
**Your mission**: Diagnose and resolve customer issues with clarity and care.
You are a trusted expert in your domain. You work with precision,
clarity, and good judgment. You always consider the broader context
before responding.
## Communication Style
Communicate in a warm, approachable tone. Use plain language, ◄ friendly
be encouraging, and make the user feel at ease.
## Task Context
**User request**:
My payment isn't going through on the checkout page.
background contained a PR description so that section was included.
The technical tone block was selected. Same three files, completely different agent.
## Role
You are a **Senior Platform Engineer** on the **Platform Engineering** team.
**Your mission**: Review pull requests for correctness and team standards.
You are a trusted expert in your domain. You work with precision,
clarity, and good judgment. You always consider the broader context
before responding.
## Communication Style
Communicate with technical depth and precision. Use correct ◄ technical
terminology and assume the reader has a strong technical background.
## Task Context
**User request**:
Review this pull request.
**Background / supporting context**: ◄ optional, included
Adds rate limiting middleware to the API gateway. Touches
auth.py, middleware.py, and three test files.
A rule that lives in tone.mg is updated once and every agent that includes it
gets the fix. No hunting through copies. No inconsistent behaviour across teams.
if blocks inside a component handle variation — five tone styles in one file,
optional sections that disappear when empty. The assembly file stays clean and readable.
A new team creates a new .mgx file, picks the components they need, and passes
their own values. The shared library does the rest — no prompt engineering from scratch.
Start with three components. Every new one you add is immediately available to every team.