Skip to content

System prompts and roles

The system prompt is the agent's character — what the LLM sees framing every heartbeat. Get it right and the agent does what you want without micromanagement; get it wrong and you'll spend the day correcting small mistakes through comments.

What you control, and what the engine adds

Your custom prompt is the system message. The engine then builds a separate user message for the issue at hand, and appends the action-verb cheat sheet, the escalation playbook, and instructions to that — you do not (and cannot) override those. So the real shape of one heartbeat is:

SYSTEM:
  [your role-default or custom prompt — this is the part you edit]

USER:
  ## You                       (name, role, who you report to)
  ## Team Roster               (routing roles only)
  ## Capabilities Available    (routing roles only)
  ## Available Skills          (every enabled skill's full body, inlined)
  ## Your Assignment           (issue id, title, status, priority, project, labels)
  ## Description               (issue body)
  ## Pinned Context            (human-pinned comments)
  ## Conversation History      (comments + activity, merged chronologically)
  ## Trigger                   (the wakeup reason, if any)
  ## Child Issues              (children's status + last comment)
  ## Attachments               (extracted attachment text)
  ## Available Actions         (the full action-verb cheat sheet)
  ## Escalation Playbook
  ## Instructions

The section names above are exact (they come from BuildHeartbeatPrompt). Two things worth internalising:

  • ## Available Skills inlines each enabled skill's full body — it is not a list of pointers. See writing-a-skill.md.
  • ## Team Roster and ## Capabilities Available appear only for routing-role agents (today, triage). A normal specialist agent never sees a roster or capability list; its prompt stays focused on its own work.

The role catalog

When you hire an agent, the role field selects its initial system prompt from a built-in catalog. Roles ship with starting prompts tuned for their purpose:

Role Prompt emphasises
general Generic competent worker — do what's asked, escalate if stuck.
engineer Code, tests, run commands. Filesystem-friendly.
pm Coordinate, decompose, track dependencies. Rarely codes.
designer Wireframes, copy, visual judgement.
qa Test plans, regressions, edge cases.
devops Infrastructure, deploy, ops procedures.
researcher Reads sources and synthesises.
scout Lightweight discovery; hands off rather than completes.
triage Routes incoming work. The one routing role — it also picks up unassigned, actionable issues and sees the roster + capabilities.
ceo Strategy, escalation, hiring. Rarely executes.
cto Technical strategy; hires engineers; approves architecture.
cmo Marketing direction; hires designers / researchers.
cfo Budget oversight; gates spending approvals.
cro Revenue exec — aligns sales, marketing, and customer success.
clo Legal / compliance exec — risk, regulation, contracts.
cio IT / technology-strategy exec — systems, data, IT risk.

The full text of each lives at internal/roles/data/<role>.md in the source tree and is baked into the binary at build time. Read those files to see exactly what an agent in that role is told to do. You can fetch a role's untouched default at runtime:

curl -s "$BASE/api/roles/cto/default-prompt"

If you hire an agent with a role that has no prompt file, it gets the generic default prompt instead.

Customising the prompt

On the agent's detail page → Configuration tab → System Prompt. The field starts populated with the role's default. Edit, save, and the next heartbeat picks it up.

Three editing strategies

1. Tighten scope. Add explicit "you only handle X" lines for specialist agents where the role default is too broad.

You are the Payments Engineer. You only work on issues tagged `payments`
or in the `services/billing` codebase. For anything else, /assign @triage
and /status blocked with a reason.

2. Add company rules. Things every agent in your company should know that aren't in the role default.

[role default]

# Company-specific rules
- We use semantic-release for versioning. Never bump versions by hand.
- All commits to main require a linked GitHub PR.
- Before deploying to prod, /request-approval with the change description.

3. Replace entirely. When the role default doesn't fit, write a fresh prompt. Keep it tight (a couple thousand tokens at most) so it doesn't crowd out the issue context.

A prompt structure that works

  1. Identity — "You are X, the Y at company Z."
  2. Scope — what you do; what you don't.
  3. Rules — invariants the agent must preserve.
  4. Escalation — when to ask, who to ask.
  5. Tone — short replies, no pleasantries.

Bullets beat paragraphs; the LLM reads structure better than prose.

What to avoid

  • Long preambles. "You are an AI assistant whose job is to carefully…" wastes tokens. Cut to the role.
  • Conflicting rules. Two lines that disagree get resolved randomly each turn.
  • Re-explaining Trimus. The ## Available Actions and ## Escalation Playbook sections already cover the mechanics.
  • Overriding the action verbs. If you write "use <DONE> instead of /status done", the engine still only parses /status done. Your override does nothing — the verb grammar is fixed (see ../concepts/action-verbs.md).
  • Secrets in the prompt. The prompt goes to the LLM provider on every run. Use Trimus Secrets for anything sensitive.

Default prompt + your edits — the lifecycle

  1. At hire time — if you didn't supply system_prompt, the engine stores the role's default as the agent's prompt.
  2. Subsequent UI edits — stored as-is, replacing the default.
  3. Heartbeat — the stored value is used. The role default is only consulted again if the stored value is empty.

This means editing internal/roles/data/<role>.md after agents have been hired does not update existing agents. To roll a new role default forward you either re-set the prompt per agent or only get it on freshly hired agents.

GEPA: prompt auto-evolution (optional)

Trimus can propose prompt revisions for an agent (the GEPA evaluator), which an operator accepts or rejects from the agent page, with optional per-agent auto-promote. Prompt versions are tracked so you can promote or restore a prior revision. It's off unless enabled — but if you see a "proposed prompt revision" on an agent page, that's where it came from.

Per-agent vs per-role, summarised

  • One agent — edit its prompt in the UI, or PATCH /api/agents/{id} with system_prompt. Affects nobody else.
  • All future agents of a role — edit the role's .md in the source tree and rebuild. Existing agents keep their stored prompt; re-set them explicitly if you want the change to apply retroactively.

Where to next