From db4dfea7ec428dfe48ea77b8fd2cf0a7214ce305 Mon Sep 17 00:00:00 2001 From: Teknium <127238744+teknium1@users.noreply.github.com> Date: Wed, 18 Mar 2026 04:18:08 -0700 Subject: [PATCH] docs: document SOUL.md as primary agent identity (#1927) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update all SOUL.md documentation to reflect that it now occupies slot #1 in the system prompt, replacing the hardcoded default identity. Updated pages: - user-guide/features/personality.md — SOUL.md is primary identity, not just a layer - developer-guide/prompt-assembly.md — updated prompt layer order, context files list - guides/use-soul-with-hermes.md — SOUL.md replaces built-in identity - user-guide/configuration.md — updated context files table and directory tree Co-authored-by: Test --- .../docs/developer-guide/prompt-assembly.md | 9 +++-- website/docs/guides/use-soul-with-hermes.md | 10 +++--- website/docs/user-guide/configuration.md | 8 ++--- .../docs/user-guide/features/personality.md | 35 ++++++++++--------- 4 files changed, 34 insertions(+), 28 deletions(-) diff --git a/website/docs/developer-guide/prompt-assembly.md b/website/docs/developer-guide/prompt-assembly.md index 163647167..2cd29c767 100644 --- a/website/docs/developer-guide/prompt-assembly.md +++ b/website/docs/developer-guide/prompt-assembly.md @@ -28,17 +28,19 @@ Primary files: The cached system prompt is assembled in roughly this order: -1. default agent identity +1. agent identity — `SOUL.md` from `HERMES_HOME` when available, otherwise falls back to `DEFAULT_AGENT_IDENTITY` in `prompt_builder.py` 2. tool-aware behavior guidance 3. Honcho static block (when active) 4. optional system message 5. frozen MEMORY snapshot 6. frozen USER profile snapshot 7. skills index -8. context files (`AGENTS.md`, `SOUL.md`, `.cursorrules`, `.cursor/rules/*.mdc`) +8. context files (`AGENTS.md`, `.cursorrules`, `.cursor/rules/*.mdc`) — SOUL.md is **not** included here when it was already loaded as the identity in step 1 9. timestamp / optional session ID 10. platform hint +When `skip_context_files` is set (e.g., subagent delegation), SOUL.md is not loaded and the hardcoded `DEFAULT_AGENT_IDENTITY` is used instead. + ## API-call-time-only layers These are intentionally *not* persisted as part of the cached system prompt: @@ -59,10 +61,11 @@ Local memory and user profile data are injected as frozen snapshots at session s `agent/prompt_builder.py` scans and sanitizes: - `AGENTS.md` -- `SOUL.md` - `.cursorrules` - `.cursor/rules/*.mdc` +`SOUL.md` is loaded separately via `load_soul_md()` for the identity slot. When it loads successfully, `build_context_files_prompt(skip_soul=True)` prevents it from appearing twice. + Long files are truncated before injection. ## Skills index diff --git a/website/docs/guides/use-soul-with-hermes.md b/website/docs/guides/use-soul-with-hermes.md index 75e8555cc..a4cc19ef5 100644 --- a/website/docs/guides/use-soul-with-hermes.md +++ b/website/docs/guides/use-soul-with-hermes.md @@ -6,9 +6,9 @@ description: "How to use SOUL.md to shape Hermes Agent's default voice, what bel # Use SOUL.md with Hermes -`SOUL.md` is the easiest way to give Hermes a stable, default voice. +`SOUL.md` is the **primary identity** for your Hermes instance. It's the first thing in the system prompt — it defines who the agent is, how it speaks, and what it avoids. -If you want Hermes to feel like the same assistant every time you talk to it — without repeating instructions in every session — this is the file to use. +If you want Hermes to feel like the same assistant every time you talk to it — or if you want to replace the Hermes persona entirely with your own — this is the file to use. ## What SOUL.md is for @@ -65,11 +65,11 @@ Important: ## How Hermes uses it -When Hermes starts a session, it reads `SOUL.md` from `HERMES_HOME`, scans it for prompt-injection patterns, truncates it if needed, and injects the content directly into the prompt. +When Hermes starts a session, it reads `SOUL.md` from `HERMES_HOME`, scans it for prompt-injection patterns, truncates it if needed, and uses it as the **agent identity** — slot #1 in the system prompt. This means SOUL.md completely replaces the built-in default identity text. -No wrapper language is added around the file. +If SOUL.md is missing, empty, or cannot be loaded, Hermes falls back to a built-in default identity. -So the content itself matters. Write the way you want Hermes to think and speak. +No wrapper language is added around the file. The content itself matters — write the way you want your agent to think and speak. ## A good first edit diff --git a/website/docs/user-guide/configuration.md b/website/docs/user-guide/configuration.md index 14d8b90c6..bfad10b36 100644 --- a/website/docs/user-guide/configuration.md +++ b/website/docs/user-guide/configuration.md @@ -15,7 +15,7 @@ All settings are stored in the `~/.hermes/` directory for easy access. ├── config.yaml # Settings (model, terminal, TTS, compression, etc.) ├── .env # API keys and secrets ├── auth.json # OAuth provider credentials (Nous Portal, etc.) -├── SOUL.md # Optional: global persona (agent embodies this personality) +├── SOUL.md # Primary agent identity (slot #1 in system prompt) ├── memories/ # Persistent memory (MEMORY.md, USER.md) ├── skills/ # Agent-created skills (managed via skill_manage tool) ├── cron/ # Scheduled jobs @@ -1318,15 +1318,15 @@ Hermes uses two different context scopes: | File | Purpose | Scope | |------|---------|-------| +| `SOUL.md` | **Primary agent identity** — defines who the agent is (slot #1 in the system prompt) | `~/.hermes/SOUL.md` or `$HERMES_HOME/SOUL.md` | | `AGENTS.md` | Project-specific instructions, coding conventions | Working directory / project tree | -| `SOUL.md` | Default persona for this Hermes instance | `~/.hermes/SOUL.md` or `$HERMES_HOME/SOUL.md` | | `.cursorrules` | Cursor IDE rules (also detected) | Working directory | | `.cursor/rules/*.mdc` | Cursor rule files (also detected) | Working directory | +- **SOUL.md** is the agent's primary identity. It occupies slot #1 in the system prompt, completely replacing the built-in default identity. Edit it to fully customize who the agent is. +- If SOUL.md is missing, empty, or cannot be loaded, Hermes falls back to a built-in default identity. - **AGENTS.md** is hierarchical: if subdirectories also have AGENTS.md, all are combined. -- **SOUL.md** is now global to the Hermes instance and is loaded only from `HERMES_HOME`. - Hermes automatically seeds a default `SOUL.md` if one does not already exist. -- An empty `SOUL.md` contributes nothing to the system prompt. - All loaded context files are capped at 20,000 characters with smart truncation. See also: diff --git a/website/docs/user-guide/features/personality.md b/website/docs/user-guide/features/personality.md index 79130ed7b..041909b07 100644 --- a/website/docs/user-guide/features/personality.md +++ b/website/docs/user-guide/features/personality.md @@ -6,12 +6,12 @@ description: "Customize Hermes Agent's personality with a global SOUL.md, built- # Personality & SOUL.md -Hermes Agent's personality is customizable, but there are two different layers that matter: +Hermes Agent's personality is fully customizable. `SOUL.md` is the **primary identity** — it's the first thing in the system prompt and defines who the agent is. -- `SOUL.md` — a durable persona file that lives in `HERMES_HOME` and is loaded automatically for that Hermes instance +- `SOUL.md` — a durable persona file that lives in `HERMES_HOME` and serves as the agent's identity (slot #1 in the system prompt) - built-in or custom `/personality` presets — session-level system-prompt overlays -If you want a stable default voice that follows you across sessions, `SOUL.md` is the right tool. +If you want to change who Hermes is — or replace it with an entirely different agent persona — edit `SOUL.md`. ## How SOUL.md works now @@ -29,15 +29,16 @@ $HERMES_HOME/SOUL.md ### Important behavior +- **SOUL.md is the agent's primary identity.** It occupies slot #1 in the system prompt, replacing the hardcoded default identity. - Hermes creates a starter `SOUL.md` automatically if one does not exist yet - Existing user `SOUL.md` files are never overwritten - Hermes loads `SOUL.md` only from `HERMES_HOME` - Hermes does not look in the current working directory for `SOUL.md` -- If `SOUL.md` exists but is empty, Hermes adds nothing from it to the prompt +- If `SOUL.md` exists but is empty, or cannot be loaded, Hermes falls back to a built-in default identity - If `SOUL.md` has content, that content is injected verbatim after security scanning and truncation -- Hermes does not add wrapper language like "If SOUL.md is present..." around the file anymore +- SOUL.md is **not** duplicated in the context files section — it appears only once, as the identity -That makes `SOUL.md` a true per-user or per-instance default personality, not a repo-local trick. +That makes `SOUL.md` a true per-user or per-instance identity, not just an additive layer. ## Why this design @@ -117,13 +118,13 @@ You optimize for truth, clarity, and usefulness over politeness theater. ## What Hermes injects into the prompt -If `SOUL.md` contains text, Hermes injects the file's text itself — not a wrapper explanation. +`SOUL.md` content goes directly into slot #1 of the system prompt — the agent identity position. No wrapper language is added around it. -So the system prompt gets the content directly, after: +The content goes through: - prompt-injection scanning - truncation if it is too large -If the file is empty or whitespace-only, nothing from `SOUL.md` is added. +If the file is empty, whitespace-only, or cannot be read, Hermes falls back to a built-in default identity ("You are Hermes Agent, an intelligent AI assistant created by Nous Research..."). This fallback also applies when `skip_context_files` is set (e.g., in subagent/delegation contexts). ## Security scanning @@ -242,14 +243,16 @@ That gives you: ## How personality interacts with the full prompt At a high level, the prompt stack includes: -1. default Hermes identity -2. memory/user context -3. skills guidance -4. context files such as `AGENTS.md`, `.cursorrules`, and global `SOUL.md` -5. platform-specific formatting hints -6. optional system-prompt overlays such as `/personality` +1. **SOUL.md** (agent identity — or built-in fallback if SOUL.md is unavailable) +2. tool-aware behavior guidance +3. memory/user context +4. skills guidance +5. context files (`AGENTS.md`, `.cursorrules`) +6. timestamp +7. platform-specific formatting hints +8. optional system-prompt overlays such as `/personality` -So `SOUL.md` is important, but it is one layer in a broader system. +`SOUL.md` is the foundation — everything else builds on top of it. ## Related docs