Introduction

When building personal AI assistants with OpenClaw, a common need arises: making the AI play different roles in different contexts. In a project management Discord channel, you want it to be a rigorous task coordinator; in a casual chat channel, you want it relaxed and friendly.

Multi-Channel Persona Routing refers to the ability of a single AI Agent to automatically switch its identity, tone, and behavior based on its conversation environment. This article shares a zero-code modification lightweight solution to achieve channel-level persona switching through configuration files.


TL;DR Key Points

  • Problem: Same Discord Bot needs different personas in different channels
  • Solution: Write channel-aware routing rules in SOUL.md
  • Principle: Leverage System Prompt injection + message metadata detection
  • Advantages: Zero code, rollback-friendly, per-message judgment
  • Applicable: OpenClaw and any AI framework supporting System Prompt injection

Background & Requirements

My Discord server has two primary channels:

  • #general — Daily conversations, needs a general-purpose AI assistant (Duran)
  • #orion — Project management, needs a task coordinator (Orion)

Goal: Same Discord Bot, automatic persona switching across channels, without deploying multiple instances or applying for multiple Bot Tokens.


Solution Design Approach

This solution is not an officially recommended approach from OpenClaw, but rather a combinatorial derivation based on understanding the framework architecture and LLM prompt engineering knowledge.

Three Key Facts

  1. OpenClaw injects SOUL.md into the system prompt

    OpenClaw reads SOUL.md from the workspace and injects it as “Project Context” into every LLM call

  2. System prompt instructions have higher weight than user messages

    This is a fundamental LLM prompt engineering principle: System Prompt behavior rules are prioritized by the model

  3. Each message carries channel metadata

    OpenClaw provides chat_id, group_subject, and other fields in the inbound metadata to identify the current conversation environment

Combined Logic

“Write rules in SOUL.md (system prompt) to make the AI check chat_id before each reply, then load the corresponding persona definition.”

This becomes a variant of Self-Referential Prompting: the AI executes a “meta-instruction” first (detect channel → switch persona → generate reply), rather than directly answering the user’s question.

Important Note: This is an unofficial hack. OpenClaw officially provides Multi-Agent Routing , recommending multi-Agent configuration through bindings for complete isolation. This article’s solution is more suitable for single-user, same Bot, lightweight persona switching scenarios.


Three Approaches Comparison

ApproachCode ChangesIsolation LevelMaintenance CostSuitable Scenario
A. Modify Source CodeHigh (requires fork)CompleteHighEnterprise multi-tenant
B. Multiple InstancesMedium (multiple Tokens)CompleteMediumMultiple Discord Bots
C. Config Routing (This Article)ZeroPersona-levelLowSingle user/lightweight switching

Approach C Core Trade-off: Skills and tools remain globally shared, memory requires manual subdirectory management, but configuration and rollback costs are minimal.


Core Principles

OpenClaw’s Context Injection Mechanism

OpenClaw automatically loads configuration files from the workspace directory as Project Context on every session startup:

  • SOUL.md — AI personality definition
  • IDENTITY.md — AI identity information
  • AGENTS.md — Behavioral guidelines

These files’ contents are injected into the System Prompt of every LLM call, forming the AI’s “underlying settings.”

Channel Metadata Availability

Every Discord message routed through OpenClaw contains the following metadata:

{
  "chat_id": "channel:YOUR_ORION_CHANNEL_ID",
  "channel": "discord",
  "group_subject": "#orion"
}

Where chat_id is Discord’s unique channel identifier, usable for precise conversation environment positioning.

Why System Prompts Can Control Persona Switching

The LLM decision flow is:

  1. Receives System Prompt (Project Context) → loads behavior rules
  2. Receives user message → understands intent
  3. Generates reply → follows instructions in System Prompt

If you write “detect chat_id, if it’s YOUR_ORION_CHANNEL_ID then load Orion persona” in the system prompt, the model will automatically execute this rule before each reply generation.


Implementation Steps

Step 1: Prepare Sub-Persona Files

Create subdirectories under workspace to store dedicated persona definitions:

~/.openclaw/workspace/
├── SOUL.md              ← Main persona (Duran)
├── IDENTITY.md          ← Main identity
├── orion/
│   ├── SOUL.md          ← Orion persona definition
│   ├── IDENTITY.md      ← Orion identity info
│   └── memory/          ← Orion dedicated memory directory (optional)

Orion’s SOUL.md Example:

# Orion - The Coordinator

You are Orion, an AI coordinator and project manager powered by OpenClaw.

## Core Identity
- **Role:** Task coordinator and project orchestrator
- **Personality:** Professional, efficient, proactive
- **Communication:** Clear, structured, action-oriented

## Responsibilities
1. **Task Management** — Break down complex projects into actionable tasks
2. **Progress Tracking** — Monitor deadlines and milestones
3. **Status Briefings** — Provide clear summaries and next steps

## Communication Style
- Use bullet points and checklists for clarity
- Start responses with the most important information
- End with clear action items or next steps
- Use emojis sparingly for visual organization (✅, 📋, ⚠️)

Step 2: Modify Main SOUL.md to Add Routing Rules

Add the channel-aware routing section at the end of ~/.openclaw/workspace/SOUL.md:

## Channel-Aware Persona Routing

You must detect which Discord channel you are in and switch persona accordingly.

### Channel Detection
- Check the `chat_id` or `conversation_label` in the inbound metadata
- `#orion` channel ID: `YOUR_ORION_CHANNEL_ID`

### When in #orion
If the current channel is `#orion` (ID: `YOUR_ORION_CHANNEL_ID`):
1. **Immediately read** `~/.openclaw/workspace/orion/SOUL.md`
2. **Immediately read** `~/.openclaw/workspace/orion/IDENTITY.md`
3. Adopt the **Orion** persona fully
4. Ignore your default Duran persona for this message

### When in any other channel
- Use your default persona (Duran)

Step 3: Modify Main IDENTITY.md to Add Identity Mapping

Add channel mapping in ~/.openclaw/workspace/IDENTITY.md:

## Channel-Aware Identity

Your identity switches based on the Discord channel:

### #orion Channel (ID: YOUR_ORION_CHANNEL_ID)
- **Name:** Orion
- **Role:** Task Coordinator & Project Manager
- **Emoji:** 📋

### All Other Channels
- **Name:** Duran
- **Role:** General AI Assistant
- **Emoji:** 🤖

Step 4: Restart to Take Effect

After modification, restart OpenClaw Gateway for the new configuration to take effect:

openclaw gateway restart

Tip: It’s recommended to backup existing SOUL.md and IDENTITY.md before modification, for rollback if needed.


Technical Details

Per-Message Routing

An important characteristic of this solution is independent judgment per message, rather than per-session persona locking.

  • Receives #general message → replies with Duran persona
  • Immediately receives #orion message → replies with Orion persona
  • No restart or session switching needed

This is because Project Context is prepended to the prompt on every LLM call, and the “self-routing instruction” within makes the AI actively detect the current environment before generating a reply.

Channel Detection Reliability

Discord channel IDs are platform-assigned unique identifiers (Snowflake format) with these characteristics:

  • Globally Unique: Each channel ID is unique across the entire Discord platform
  • Persistent: Channel IDs don’t change with renaming or moving
  • Stable Metadata: OpenClaw’s inbound metadata always contains accurate chat_id

Fallback Mechanism

If orion/SOUL.md is missing or unreadable, the AI should gracefully fall back to the default persona. This can be achieved by adding error handling logic in the main SOUL.md routing rules:

### Fallback
If orion/SOUL.md is missing or unreadable:
- Log the error
- Continue using default Duran persona
- Inform the user that Orion persona is temporarily unavailable

Effect Demonstration

📋 #orion Channel (Orion Mode)

User: “I need to publish a blog post to multiple platforms today”

Orion Reply:

📋 Blog Publishing Project - Task Breakdown

🎯 Project Goal

Complete blog post writing and publish to 3 platforms today

📊 Task Breakdown

Phase 1: Content Preparation ⏱️ Estimated 2-3 hours

  • Topic confirmation
  • Outline writing
  • Main content writing
  • Images/cover design

Phase 2: Multi-Platform Adaptation ⏱️ Estimated 1-2 hours

  • Public blog version
  • WeChat Official Account version
  • Zhihu version

Phase 3: Publishing Execution ⏱️ Estimated 1 hour

  • Blog publishing
  • WeChat publishing
  • Zhihu publishing

Characteristics: Structured, task-oriented, time estimates, checklist format

💬 #general Channel (Duran Mode)

User: “How’s the weather today?”

Duran Reply:

Sunny in Beijing today, 22°C, good for going out.

Characteristics: Concise, casual, conversational


Advanced Extensions

1. Multi-Channel Multi-Persona

Add more channels and personas:

### When in #dev (ID: YOUR_DEV_CHANNEL_ID)
1. Read `dev/SOUL.md`
2. Adopt Developer persona

### When in #writing (ID: YOUR_WRITING_CHANNEL_ID)
1. Read `writer/SOUL.md`
2. Adopt Writer persona

2. Memory Isolation

Each sub-persona can have its own dedicated memory directory:

orion/
├── SOUL.md
├── IDENTITY.md
└── memory/
    ├── 2026-04-27.md    # Orion's daily notes
    └── tasks/           # Project task records

It’s recommended to keep a global MEMORY.md for cross-persona long-term memory sharing.

3. Skill Differentiation

Different personas can load different Skills:

  • Orion: Project management Skill (taskflow, calendar management)
  • Duran: General Skill (search, file operations)

Configure in their respective TOOLS.md files.


Limitations & Considerations

  1. Requires Restart to Take Effect

    After modifying SOUL.md, Gateway restart is required; cannot hot-update

  2. Not Fully Isolated

    Skills and Tools remain globally shared; cannot isolate permissions by persona

  3. Memory Requires Manual Management

    MEMORY.md is global; sub-persona memories require self-managed directories

  4. File Dependency

    If orion/SOUL.md is lost, graceful fallback mechanisms are needed


Summary

Through “self-routing instructions within the system prompt”, we achieved channel-level persona switching without modifying a single line of OpenClaw source code.

Core Points:

  • ✅ Leverage OpenClaw’s Project Context mechanism
  • ✅ Write channel detection + persona switching rules in SOUL.md
  • ✅ Independent judgment per message, no multiple instances needed
  • ✅ Configuration as code, easy version control

This solution applies to any AI framework supporting System Prompt injection, a universal, low-cost, highly flexible multi-persona implementation approach.


FAQ

Q: Is this an officially supported OpenClaw approach?

A: No. This is an unofficial hack derived from LLM prompt engineering principles. OpenClaw officially recommends configuring multi-Agent through bindings, suitable for scenarios requiring complete isolation.

Q: Can changes to SOUL.md take effect immediately?

A: No. OpenClaw Gateway restart is required to reload Project Context.

Q: Will messages from different channels in the same session mix personas?

A: No. This solution uses per-message judgment; each message independently detects channel ID and switches persona.

Q: What if a sub-persona’s SOUL.md file is lost?

A: It’s recommended to write fallback rules in the main SOUL.md to revert to the default persona when files are lost.

Q: Does this solution only apply to OpenClaw?

A: It applies to any AI framework supporting System Prompt injection, including Claude Desktop, Custom GPT, Dify, etc.



Copyright Notice: This article is licensed under CC BY-SA 4.0 . Please indicate the source when reposting. Author: Duran.