# Agent personas and system prompts

Source: https://codeherder.com/docs/agent-personas/

What the persona and system prompt fields on an agent's launch config do, how to set and update them, and how to write ones that are effective.

Every launch config has two optional text fields that shape how a session behaves: a **persona** and a **system prompt**. They serve different purposes, apply at different points in a session, and are stored together on the config so they travel with it wherever it runs.

Most agents carry a single launch config, so in practice these fields shape every task the agent works on. An agent that carries more than one launch config can give each one its own persona and system prompt — see [Agents with more than one launch config](https://codeherder.com/docs/agent-personas/#agents-with-more-than-one-launch-config) below.

## Persona vs. system prompt

| aspect | **Persona** | **System prompt** |
| --- | --- | --- |
| **What it is** | A short description of this agent’s role and identity | Standing instructions applied to every session |
| **Where it appears** | Included in each task’s session brief — the agent “knows who it is” before it reads the task | Prepended as an instruction at the start of every session |
| **Typical length** | One or two sentences | One or more paragraphs; can be a full file |
| **What it shapes** | Tone, focus area, how the agent describes itself | Rules, constraints, style conventions, non-obvious requirements |
| **Example** | `"A senior Go engineer who prioritises correctness and minimal surface area."` | `"Always write a test before adding production code. Prefer stdlib over third-party packages."` |

For a single-config agent, both fields apply to every stage the agent runs — plan, code, review, and any custom stages in your workflow. For a multi-config agent, the config selected to run a given stage supplies that stage’s persona and system prompt, so different stages can see different personas — see [Agents with more than one launch config](https://codeherder.com/docs/agent-personas/#agents-with-more-than-one-launch-config) below.

## Viewing the current config

To see what persona and system prompt an agent currently has, run:

```
ch agent config show <agent-id>
```

If the agent has more than one launch config, this shows only the **top** one — see [Agents with more than one launch config](https://codeherder.com/docs/agent-personas/#agents-with-more-than-one-launch-config) below. The output lists the config in full — command, args, environment, capabilities, persona, and system prompt — along with a version stamp that increments each time the config is updated. A member below workspace owner or admin sees the same output, but with every argument and environment variable value (except some `@secret:` references) replaced by `[redacted]` — see [Who can manage a launch config](https://codeherder.com/docs/agents-and-cli/#who-can-manage-a-launch-config).

```
agent:        Builder (a1b2c3d4-...)
harness:      claude
command:      /usr/local/bin/claude
capabilities: model:sonnet
persona:      A senior Go engineer focused on correctness and clear, minimal code.
systemPrompt:
  Always write a test before adding production code.
  Prefer stdlib over third-party packages.
version:      3
```

## Setting or updating persona and system prompt

Use `ch agent config edit` to store a persona and system prompt on an agent. Like `config show`, this always acts on the agent’s **top** launch config — see [Agents with more than one launch config](https://codeherder.com/docs/agent-personas/#agents-with-more-than-one-launch-config) below if the agent carries more than one:

```
ch agent config edit <agent-id> \
  --persona "A senior Go engineer focused on correctness and clear, minimal code." \
  --system-prompt "Always write a test before adding production code."
```

This changes only the persona and system prompt — the config’s command, args, environment, and capabilities stay exactly as they were (see [What each edit actually changes](https://codeherder.com/docs/agents-and-cli/#what-each-edit-actually-changes)).

For a longer system prompt, read it straight from a file with `--system-prompt-file`:

```
ch agent config edit <agent-id> --system-prompt-file prompts/builder-rules.md
```

Keeping the prompt in a file this way keeps it out of your shell history and makes it easy to version-control alongside your codebase. To pipe a prompt in from another command instead, pass `--system-prompt -` to read it from standard input.

### What `config edit` changes

`config edit` is a partial update: it changes only the fields whose flag you pass, and leaves everything else as it was stored. Passing `--persona` or `--system-prompt` on its own, as in the examples above, touches only that field.

The one exception is a set of **repeatable** flags — `--arg`, `--env`, `--cap`, `--credential-ref`, and `--allowed-model` — each of which replaces its field’s whole list when you pass it at all. This doesn’t affect persona or system prompt, which are plain single-value fields, but it does mean that if you’re setting a persona in the same call as, say, `--arg`, you need to include every argument you want to keep, not just the new persona.

This means you can update the persona and system prompt without touching the command, capabilities, or anything else.

To clear a persona or system prompt, pass an empty string explicitly:

```
ch agent config edit <agent-id> --persona ""
```

## Agents with more than one launch config

An agent can carry an ordered list of launch configs rather than just one — for example, to run different coding-agent CLIs for different stages, or to keep a fallback config in reserve. Each launch config has its **own** persona and system prompt, so different configs (and the stages that run under them) can present the agent differently.

`ch agent config show` and `ch agent config edit` always read and write the **top** config — the first one in the list. Running `config edit --persona "..."` on a multi-config agent updates only that top config; every other config’s persona and system prompt is untouched.

To give a persona or system prompt to a config other than the top one:

- Set it when you create the config: `ch agent config create <agent-id> --harness <harness> --cap <capability> --persona "..." --system-prompt "..."`.
- Or edit the existing config from the **Launch configs** panel on the agent’s detail page in the web app.

The top config’s persona and system prompt can be set even earlier — in the same call that creates the agent: `ch agent create --harness <h> --config-cap <capability> --persona "..." --system-prompt "..."`. See [Creating a runnable agent in one call](https://codeherder.com/docs/agents-and-cli/#creating-a-runnable-agent-in-one-call) for the full flag set.

Reordering or enabling/disabling configs controls which config — and so which persona and system prompt — actually runs a given stage. See [Agents and the CLI](https://codeherder.com/docs/agents-and-cli/) for the full set of commands for managing multiple configs and how CodeHerder picks which one runs a stage.

## Who can change these

Setting a persona or system prompt goes through `ch agent config edit` or `ch agent config create`, which need workspace owner or admin — see [Who can manage a launch config](https://codeherder.com/docs/agents-and-cli/#who-can-manage-a-launch-config) for the full permission split. Agents cannot modify their own configs.

## Writing a good persona

A persona works best when it is:

- **Short.** One or two sentences is ideal. The persona is included in every session brief; a long paragraph adds noise rather than focus.
- **Role-focused.** Say what kind of work this agent does and what it values — not a biography.
- **Concrete.** “A backend engineer who writes Go and prioritises correctness” is more useful than “A helpful coding assistant”.

**Examples:**

```
A senior Go engineer who values correctness, minimal surface area, and thorough test coverage.
```

```
A frontend engineer specialising in React and TypeScript, focused on accessible, performant UIs.
```

```
A careful code reviewer who looks for correctness bugs, security issues, and clarity improvements.
```

## Writing a good system prompt

A system prompt is for standing rules — things that should be true on every task, not just the current one. Good candidates include:

- Coding standards the agent should always follow (“never use `%w` in `fmt.Errorf` ”)
- Style conventions specific to your codebase
- Rules about what the agent should or should not commit
- Non-obvious constraints about your environment

**Tips:**

- Keep the system prompt focused on rules the agent might otherwise get wrong. Don’t repeat things the agent already knows well.
- Use `--system-prompt-file <path>` (for example, `--system-prompt-file prompts/builder.md`) to keep your prompt in version control and update it without touching the CLI invocation. `--system-prompt-file -` (or a bare `--system-prompt -`) reads from stdin.
- Review the prompt after a few tasks. If a rule keeps being ignored, make it more specific. If a rule never comes up, remove it — shorter prompts are easier for the agent to follow.

---

To set up the rest of an agent’s launch config — the command, capabilities, and environment variables — see [Agents and the CLI](https://codeherder.com/docs/agents-and-cli/). To understand how capabilities route tasks to the right agent, see [Agents and the CLI](https://codeherder.com/docs/agents-and-cli/). To watch a running agent, see [Monitoring your agents](https://codeherder.com/docs/monitoring-agents/). For per-agent tuning that goes beyond the persona field, see the `template_persona` scope in [Workspace wiki](https://codeherder.com/docs/memory/).
