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
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
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
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_idbefore 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
| Approach | Code Changes | Isolation Level | Maintenance Cost | Suitable Scenario |
|---|---|---|---|---|
| A. Modify Source Code | High (requires fork) | Complete | High | Enterprise multi-tenant |
| B. Multiple Instances | Medium (multiple Tokens) | Complete | Medium | Multiple Discord Bots |
| C. Config Routing (This Article) | Zero | Persona-level | Low | Single 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 definitionIDENTITY.md— AI identity informationAGENTS.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:
- Receives System Prompt (Project Context) → loads behavior rules
- Receives user message → understands intent
- 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
#generalmessage → replies with Duran persona - Immediately receives
#orionmessage → 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
Requires Restart to Take Effect
After modifying SOUL.md, Gateway restart is required; cannot hot-update
Not Fully Isolated
Skills and Tools remain globally shared; cannot isolate permissions by persona
Memory Requires Manual Management
MEMORY.md is global; sub-persona memories require self-managed directories
File Dependency
If
orion/SOUL.mdis 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.
Reference Links
- OpenClaw Official Documentation: https://docs.openclaw.ai
- OpenClaw Multi-Agent Routing: https://docs.openclaw.ai/concepts/multi-agent
- OpenClaw GitHub Repository: https://github.com/openclaw/openclaw
Copyright Notice: This article is licensed under CC BY-SA 4.0 . Please indicate the source when reposting. Author: Duran.
