Edict (三省六部) Multi-Agent Orchestration
Skill by ara.so — Daily 2026 Skills collection.
Edict implements a 1400-year-old Tang Dynasty governance model as an AI multi-agent architecture. Twelve specialized agents form a checks-and-balances pipeline: Crown Prince (triage) → Zhongshu (planning) → Menxia (review/veto) → Shangshu (dispatch) → Six Ministries (parallel execution). Built on OpenClaw, it provides a real-time React kanban dashboard, full audit trails, and per-agent LLM configuration.
Architecture Overview
You (Emperor) → taizi (triage) → zhongshu (plan) → menxia (review/veto)
→ shangshu (dispatch) → [hubu|libu|bingbu|xingbu|gongbu|libu2] (execute)
→ memorial (result archived)
Key differentiator vs CrewAI/AutoGen: Menxia (门下省) is a mandatory quality gate — it can veto and force rework before tasks reach executors.
Prerequisites
- OpenClaw installed and running
- Python 3.9+
- Node.js 18+ (for React dashboard build)
- macOS or Linux
Installation
Quick Demo (Docker — no OpenClaw needed)
docker run --platform linux/amd64 -p 7891:7891 cft0808/sansheng-demo
docker run -p 7891:7891 cft0808/sansheng-demo
docker compose up
Open http://localhost:7891
Full Installation
git clone https://github.com/cft0808/edict.git
cd edict
chmod +x install.sh && ./install.sh
The install script automatically:
- Creates all 12 agent workspaces (taizi, zhongshu, menxia, shangshu, hubu, libu, bingbu, xingbu, gongbu, libu2, zaochao, legacy-compat)
- Writes SOUL.md role definitions to each agent workspace
- Registers agents and permission matrix in
openclaw.json
- Symlinks shared data directories across all agent workspaces
- Sets
sessions.visibility all for inter-agent message routing
- Syncs API keys across all agents
- Builds React frontend
- Initializes data directory and syncs official stats
First-time API Key Setup
openclaw agents add taizi
./install.sh
Running the System
bash scripts/run_loop.sh
python3 dashboard/server.py
open http://127.0.0.1:7891
Key Commands
OpenClaw Agent Management
openclaw agents list
openclaw agents add <agent-name>
openclaw agents status
openclaw gateway restart
openclaw send taizi "帮我分析一下竞争对手的产品策略"
Dashboard Server
python3 dashboard/server.py
PORT=8080 python3 dashboard/server.py
Data Scripts
python3 scripts/sync_officials.py
python3 scripts/kanban_update.py
python3 scripts/fetch_news.py
bash scripts/run_loop.sh
Configuration
Agent Model Configuration (openclaw.json)
{
"agents": {
"taizi": {
"model": "claude-3-5-sonnet-20241022",
"workspace": "~/.openclaw/workspaces/taizi"
},
"zhongshu": {
"model": "gpt-4o",
"workspace": "~/.openclaw/workspaces/zhongshu"
},
"menxia": {
"model": "claude-3-5-sonnet-20241022",
"workspace": "~/.openclaw/workspaces/menxia"
},
"shangshu": {
"model": "gpt-4o-mini",
"workspace": "~/.openclaw/workspaces/shangshu"
}
},
"gateway": {
"port": 7891,
"sessions": {
"visibility": "all"
}
}
}
Per-Agent Model Hot-Switching (via Dashboard)
Navigate to ⚙️ Models panel → select agent → choose LLM → Apply. Gateway restarts automatically (~5 seconds).
Environment Variables
export ANTHROPIC_API_KEY="sk-ant-..."
export OPENAI_API_KEY="sk-..."
export FEISHU_WEBHOOK_URL="https://open.feishu.cn/open-apis/bot/v2/hook/..."
export NEWS_API_KEY="..."
export DASHBOARD_PORT=7891
Agent Roles Reference
| Agent |
Role |
Responsibility |
taizi |
太子 Crown Prince |
Triage: chat → auto-reply, edicts → create task |
zhongshu |
中书省 |
Planning: decompose edict into subtasks |
menxia |
门下省 |
Review/Veto: quality gate, can reject and force rework |
shangshu |
尚书省 |
Dispatch: assign subtasks to ministries |
hubu |
户部 Ministry of Revenue |
Finance, data analysis tasks |
libu |
礼部 Ministry of Rites |
Communication, documentation tasks |
bingbu |
兵部 Ministry of War |
Strategy, security tasks |
xingbu |
刑部 Ministry of Justice |
Review, compliance tasks |
gongbu |
工部 Ministry of Works |
Engineering, technical tasks |
libu2 |
吏部 Ministry of Personnel |
HR, agent management tasks |
zaochao |
早朝官 |
Morning briefing aggregator |
Permission Matrix (who can message whom)
PERMISSIONS = {
"taizi": ["zhongshu"],
"zhongshu": ["menxia"],
"menxia": ["zhongshu", "shangshu"],
"shangshu": ["hubu", "libu", "bingbu", "xingbu", "gongbu", "libu2"],
"hubu": ["shangshu"],
"libu": ["shangshu"],
"bingbu": ["shangshu"],
"xingbu": ["shangshu"],
"gongbu": ["shangshu"],
"libu2": ["shangshu"],
}
Task State Machine
VALID_TRANSITIONS = {
"pending": ["planning"],
"planning": ["reviewing", "pending"],
"reviewing": ["dispatching", "planning"],
"dispatching": ["executing"],
"executing": ["completed", "failed"],
"completed": [],
"failed": ["pending"],
}
Real Code Examples
Send an Edict Programmatically
import subprocess
import json
def send_edict(message: str, agent: str = "taizi") -> dict:
"""Send an edict to the Crown Prince for triage."""
result = subprocess.run(
["openclaw", "send", agent, message],
capture_output