edict-multi-agent-orchestration
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseEdict (三省六部) Multi-Agent Orchestration
Edict(三省六部)多Agent编排系统
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.
你(皇帝)→ taizi(太子,任务分流)→ zhongshu(中书省,规划)→ menxia(门下省,审核/否决)
→ shangshu(尚书省,分派)→ [hubu|libu|bingbu|xingbu|gongbu|libu2](执行)
→ memorial(结果存档)与CrewAI/AutoGen的核心区别:门下省是强制质量关卡——在任务到达执行环节前,它可以否决任务并要求重新修改。
Prerequisites
前置条件
- OpenClaw installed and running
- Python 3.9+
- Node.js 18+ (for React dashboard build)
- macOS or Linux
- 已安装并运行OpenClaw
- Python 3.9+
- Node.js 18+(用于React仪表盘构建)
- macOS或Linux系统
Installation
安装步骤
Quick Demo (Docker — no OpenClaw needed)
快速演示(Docker环境 — 无需OpenClaw)
bash
undefinedbash
undefinedx86/amd64 (Ubuntu, WSL2)
x86/amd64架构(Ubuntu、WSL2)
docker run --platform linux/amd64 -p 7891:7891 cft0808/sansheng-demo
docker run --platform linux/amd64 -p 7891:7891 cft0808/sansheng-demo
Apple Silicon / ARM
Apple Silicon / ARM架构
docker run -p 7891:7891 cft0808/sansheng-demo
docker run -p 7891:7891 cft0808/sansheng-demo
Or with docker-compose (platform already set)
或使用docker-compose(已配置平台信息)
docker compose up
Open http://localhost:7891docker compose up
打开 http://localhost:7891Full Installation
完整安装
bash
git clone https://github.com/cft0808/edict.git
cd edict
chmod +x install.sh && ./install.shThe 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 for inter-agent message routing
sessions.visibility all - Syncs API keys across all agents
- Builds React frontend
- Initializes data directory and syncs official stats
bash
git clone https://github.com/cft0808/edict.git
cd edict
chmod +x install.sh && ./install.sh安装脚本将自动完成以下操作:
- 创建全部12个Agent工作区(taizi、zhongshu、menxia、shangshu、hubu、libu、bingbu、xingbu、gongbu、libu2、zaochao、legacy-compat)
- 为每个Agent工作区写入SOUL.md角色定义文件
- 在中注册Agent并配置权限矩阵
openclaw.json - 在所有Agent工作区之间创建共享数据目录的符号链接
- 设置以实现Agent间消息路由
sessions.visibility all - 为所有Agent同步API密钥
- 构建React前端
- 初始化数据目录并同步官方统计数据
First-time API Key Setup
首次API密钥配置
bash
undefinedbash
undefinedConfigure API key on first agent
在第一个Agent上配置API密钥
openclaw agents add taizi
openclaw agents add taizi
Then re-run install to propagate to all agents
然后重新运行安装脚本以同步到所有Agent
./install.sh
---./install.sh
---Running the System
运行系统
bash
undefinedbash
undefinedTerminal 1: Data refresh loop (keeps kanban data current)
终端1:数据刷新循环(保持看板数据实时更新)
bash scripts/run_loop.sh
bash scripts/run_loop.sh
Terminal 2: Dashboard server
终端2:仪表盘服务器
python3 dashboard/server.py
python3 dashboard/server.py
Open dashboard
打开仪表盘
---
---Key Commands
核心命令
OpenClaw Agent Management
OpenClaw Agent管理
bash
undefinedbash
undefinedList all registered agents
列出所有已注册的Agent
openclaw agents list
openclaw agents list
Add/configure an agent
添加/配置Agent
openclaw agents add <agent-name>
openclaw agents add <agent-name>
Check agent status
检查Agent状态
openclaw agents status
openclaw agents status
Restart gateway (required after config changes)
重启网关(配置变更后需执行)
openclaw gateway restart
openclaw gateway restart
Send a message/edict to the system
向系统发送消息/指令
openclaw send taizi "帮我分析一下竞争对手的产品策略"
undefinedopenclaw send taizi "帮我分析一下竞争对手的产品策略"
undefinedDashboard Server
仪表盘服务器
python
undefinedpython
undefineddashboard/server.py — serves on port 7891
dashboard/server.py — 监听7891端口
Built-in: React frontend + REST API + WebSocket updates
内置功能:React前端 + REST API + WebSocket实时更新
python3 dashboard/server.py
python3 dashboard/server.py
Custom port
自定义端口
PORT=8080 python3 dashboard/server.py
undefinedPORT=8080 python3 dashboard/server.py
undefinedData Scripts
数据脚本
bash
undefinedbash
undefinedSync official (agent) statistics
同步官方(Agent)统计数据
python3 scripts/sync_officials.py
python3 scripts/sync_officials.py
Update kanban task states
更新看板任务状态
python3 scripts/kanban_update.py
python3 scripts/kanban_update.py
Run news aggregation
运行新闻聚合
python3 scripts/fetch_news.py
python3 scripts/fetch_news.py
Full refresh loop (runs all scripts in sequence)
全量刷新循环(按顺序执行所有脚本)
bash scripts/run_loop.sh
---bash scripts/run_loop.sh
---Configuration
配置说明
Agent Model Configuration (openclaw.json
)
openclaw.jsonAgent模型配置(openclaw.json
)
openclaw.jsonjson
{
"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"
}
}
}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)
单个Agent模型热切换(通过仪表盘)
Navigate to ⚙️ Models panel → select agent → choose LLM → Apply. Gateway restarts automatically (~5 seconds).
导航至**⚙️ Models**面板 → 选择Agent → 选择LLM → 应用。网关将自动重启(约5秒)。
Environment Variables
环境变量
bash
undefinedbash
undefinedAPI keys (set before running install.sh or openclaw)
API密钥(在运行install.sh或openclaw前设置)
export ANTHROPIC_API_KEY="sk-ant-..."
export OPENAI_API_KEY="sk-..."
export ANTHROPIC_API_KEY="sk-ant-..."
export OPENAI_API_KEY="sk-..."
Optional: Feishu/Lark webhook for notifications
可选:飞书/Lark机器人通知Webhook
export FEISHU_WEBHOOK_URL="https://open.feishu.cn/open-apis/bot/v2/hook/..."
export FEISHU_WEBHOOK_URL="https://open.feishu.cn/open-apis/bot/v2/hook/..."
Optional: news aggregation
可选:新闻聚合API密钥
export NEWS_API_KEY="..."
export NEWS_API_KEY="..."
Dashboard port override
仪表盘端口覆盖
export DASHBOARD_PORT=7891
---export DASHBOARD_PORT=7891
---Agent Roles Reference
Agent角色参考
| Agent | Role | Responsibility |
|---|---|---|
| 太子 Crown Prince | Triage: chat → auto-reply, edicts → create task |
| 中书省 | Planning: decompose edict into subtasks |
| 门下省 | Review/Veto: quality gate, can reject and force rework |
| 尚书省 | Dispatch: assign subtasks to ministries |
| 户部 Ministry of Revenue | Finance, data analysis tasks |
| 礼部 Ministry of Rites | Communication, documentation tasks |
| 兵部 Ministry of War | Strategy, security tasks |
| 刑部 Ministry of Justice | Review, compliance tasks |
| 工部 Ministry of Works | Engineering, technical tasks |
| 吏部 Ministry of Personnel | HR, agent management tasks |
| 早朝官 | Morning briefing aggregator |
| Agent | 角色 | 职责 |
|---|---|---|
| 太子 Crown Prince | 任务分流:聊天消息→自动回复,指令→创建任务 |
| 中书省 | 任务规划:将指令拆解为子任务 |
| 门下省 | 审核/否决:质量关卡,可拒绝任务并要求返工 |
| 尚书省 | 任务分派:将子任务分配至对应六部 |
| 户部 Ministry of Revenue | 财务、数据分析类任务 |
| 礼部 Ministry of Rites | 沟通、文档类任务 |
| 兵部 Ministry of War | 战略、安全类任务 |
| 刑部 Ministry of Justice | 审核、合规类任务 |
| 工部 Ministry of Works | 工程、技术类任务 |
| 吏部 Ministry of Personnel | 人力资源、Agent管理类任务 |
| 早朝官 | 早间简报聚合 |
Permission Matrix (who can message whom)
权限矩阵(Agent间消息发送规则)
python
undefinedpython
undefinedDefined in openclaw.json — enforced by gateway
定义在openclaw.json中 — 由网关强制执行
PERMISSIONS = {
"taizi": ["zhongshu"],
"zhongshu": ["menxia"],
"menxia": ["zhongshu", "shangshu"], # can veto back to zhongshu
"shangshu": ["hubu", "libu", "bingbu", "xingbu", "gongbu", "libu2"],
# ministries report back up the chain
"hubu": ["shangshu"],
"libu": ["shangshu"],
"bingbu": ["shangshu"],
"xingbu": ["shangshu"],
"gongbu": ["shangshu"],
"libu2": ["shangshu"],
}
---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
任务状态机
python
undefinedpython
undefinedscripts/kanban_update.py enforces valid transitions
scripts/kanban_update.py 强制执行状态转换规则
VALID_TRANSITIONS = {
"pending": ["planning"],
"planning": ["reviewing", "pending"], # zhongshu → menxia
"reviewing": ["dispatching", "planning"], # menxia approve or veto
"dispatching": ["executing"],
"executing": ["completed", "failed"],
"completed": [],
"failed": ["pending"], # retry
}
VALID_TRANSITIONS = {
"pending": ["planning"],
"planning": ["reviewing", "pending"], # 中书省→门下省
"reviewing": ["dispatching", "planning"], # 门下省批准或否决返工
"dispatching": ["executing"],
"executing": ["completed", "failed"],
"completed": [],
"failed": ["pending"], # 重试
}
Invalid transitions are rejected — no silent state corruption
无效的状态转换将被拒绝 — 不会出现静默状态损坏
---
---Real Code Examples
实际代码示例
Send an Edict Programmatically
程序化发送指令
python
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=True,
text=True
)
return {"stdout": result.stdout, "returncode": result.returncode}python
import subprocess
import json
def send_edict(message: str, agent: str = "taizi") -> dict:
"""向太子Agent发送指令进行任务分流。"""
result = subprocess.run(
["openclaw", "send", agent, message],
capture_output=True,
text=True
)
return {"stdout": result.stdout, "returncode": result.returncode}Example edicts
示例指令
send_edict("分析本季度用户增长数据,找出关键驱动因素")
send_edict("起草一份关于产品路线图的对外公告")
send_edict("审查现有代码库的安全漏洞")
undefinedsend_edict("分析本季度用户增长数据,找出关键驱动因素")
send_edict("起草一份关于产品路线图的对外公告")
send_edict("审查现有代码库的安全漏洞")
undefinedRead Kanban State
读取看板状态
python
import json
from pathlib import Path
def get_kanban_tasks(data_dir: str = "data") -> list[dict]:
"""Read current kanban task state."""
tasks_file = Path(data_dir) / "tasks.json"
if not tasks_file.exists():
return []
with open(tasks_file) as f:
return json.load(f)
def get_tasks_by_status(status: str) -> list[dict]:
tasks = get_kanban_tasks()
return [t for t in tasks if t.get("status") == status]python
import json
from pathlib import Path
def get_kanban_tasks(data_dir: str = "data") -> list[dict]:
"""读取当前看板任务状态。"""
tasks_file = Path(data_dir) / "tasks.json"
if not tasks_file.exists():
return []
with open(tasks_file) as f:
return json.load(f)
def get_tasks_by_status(status: str) -> list[dict]:
tasks = get_kanban_tasks()
return [t for t in tasks if t.get("status") == status]Usage
使用示例
executing = get_tasks_by_status("executing")
completed = get_tasks_by_status("completed")
print(f"In progress: {len(executing)}, Done: {len(completed)}")
undefinedexecuting = get_tasks_by_status("executing")
completed = get_tasks_by_status("completed")
print(f"进行中任务:{len(executing)},已完成任务:{len(completed)}")
undefinedUpdate Task Status (with validation)
更新任务状态(含验证)
python
import json
from pathlib import Path
from datetime import datetime, timezone
VALID_TRANSITIONS = {
"pending": ["planning"],
"planning": ["reviewing", "pending"],
"reviewing": ["dispatching", "planning"],
"dispatching": ["executing"],
"executing": ["completed", "failed"],
"completed": [],
"failed": ["pending"],
}
def update_task_status(task_id: str, new_status: str, data_dir: str = "data") -> bool:
"""Update task status with state machine validation."""
tasks_file = Path(data_dir) / "tasks.json"
tasks = json.loads(tasks_file.read_text())
task = next((t for t in tasks if t["id"] == task_id), None)
if not task:
raise ValueError(f"Task {task_id} not found")
current = task["status"]
allowed = VALID_TRANSITIONS.get(current, [])
if new_status not in allowed:
raise ValueError(
f"Invalid transition: {current} → {new_status}. "
f"Allowed: {allowed}"
)
task["status"] = new_status
task["updated_at"] = datetime.now(timezone.utc).isoformat()
task.setdefault("history", []).append({
"from": current,
"to": new_status,
"timestamp": task["updated_at"]
})
tasks_file.write_text(json.dumps(tasks, ensure_ascii=False, indent=2))
return Truepython
import json
from pathlib import Path
from datetime import datetime, timezone
VALID_TRANSITIONS = {
"pending": ["planning"],
"planning": ["reviewing", "pending"],
"reviewing": ["dispatching", "planning"],
"dispatching": ["executing"],
"executing": ["completed", "failed"],
"completed": [],
"failed": ["pending"],
}
def update_task_status(task_id: str, new_status: str, data_dir: str = "data") -> bool:
"""通过状态机验证更新任务状态。"""
tasks_file = Path(data_dir) / "tasks.json"
tasks = json.loads(tasks_file.read_text())
task = next((t for t in tasks if t["id"] == task_id), None)
if not task:
raise ValueError(f"未找到任务 {task_id}")
current = task["status"]
allowed = VALID_TRANSITIONS.get(current, [])
if new_status not in allowed:
raise ValueError(
f"无效状态转换:{current} → {new_status}。 "
f"允许的转换:{allowed}"
)
task["status"] = new_status
task["updated_at"] = datetime.now(timezone.utc).isoformat()
task.setdefault("history", []).append({
"from": current,
"to": new_status,
"timestamp": task["updated_at"]
})
tasks_file.write_text(json.dumps(tasks, ensure_ascii=False, indent=2))
return TrueDashboard REST API Client
仪表盘REST API客户端
python
import urllib.request
import json
BASE_URL = "http://127.0.0.1:7891/api"
def api_get(endpoint: str) -> dict:
with urllib.request.urlopen(f"{BASE_URL}{endpoint}") as resp:
return json.loads(resp.read())
def api_post(endpoint: str, data: dict) -> dict:
payload = json.dumps(data).encode()
req = urllib.request.Request(
f"{BASE_URL}{endpoint}",
data=payload,
headers={"Content-Type": "application/json"},
method="POST"
)
with urllib.request.urlopen(req) as resp:
return json.loads(resp.read())python
import urllib.request
import json
BASE_URL = "http://127.0.0.1:7891/api"
def api_get(endpoint: str) -> dict:
with urllib.request.urlopen(f"{BASE_URL}{endpoint}") as resp:
return json.loads(resp.read())
def api_post(endpoint: str, data: dict) -> dict:
payload = json.dumps(data).encode()
req = urllib.request.Request(
f"{BASE_URL}{endpoint}",
data=payload,
headers={"Content-Type": "application/json"},
method="POST"
)
with urllib.request.urlopen(req) as resp:
return json.loads(resp.read())Read dashboard data
读取仪表盘数据
tasks = api_get("/tasks")
agents = api_get("/agents")
sessions = api_get("/sessions")
news = api_get("/news")
tasks = api_get("/tasks")
agents = api_get("/agents")
sessions = api_get("/sessions")
news = api_get("/news")
Trigger task action
触发任务操作
api_post("/tasks/pause", {"task_id": "task-123"})
api_post("/tasks/cancel", {"task_id": "task-123"})
api_post("/tasks/resume", {"task_id": "task-123"})
api_post("/tasks/pause", {"task_id": "task-123"})
api_post("/tasks/cancel", {"task_id": "task-123"})
api_post("/tasks/resume", {"task_id": "task-123"})
Switch model for an agent
切换Agent模型
api_post("/agents/model", {
"agent": "zhongshu",
"model": "gpt-4o-2024-11-20"
})
undefinedapi_post("/agents/model", {
"agent": "zhongshu",
"model": "gpt-4o-2024-11-20"
})
undefinedAgent Health Check
Agent健康检查
python
import json
from pathlib import Path
from datetime import datetime, timezone, timedelta
def check_agent_health(data_dir: str = "data") -> dict[str, str]:
"""
Returns health status for each agent.
🟢 active = heartbeat within 2 min
🟡 stale = heartbeat 2-10 min ago
🔴 offline = heartbeat >10 min ago or missing
"""
heartbeats_file = Path(data_dir) / "heartbeats.json"
if not heartbeats_file.exists():
return {}
heartbeats = json.loads(heartbeats_file.read_text())
now = datetime.now(timezone.utc)
status = {}
for agent, last_beat in heartbeats.items():
last = datetime.fromisoformat(last_beat)
delta = now - last
if delta < timedelta(minutes=2):
status[agent] = "🟢 active"
elif delta < timedelta(minutes=10):
status[agent] = "🟡 stale"
else:
status[agent] = "🔴 offline"
return statuspython
import json
from pathlib import Path
from datetime import datetime, timezone, timedelta
def check_agent_health(data_dir: str = "data") -> dict[str, str]:
"""
返回每个Agent的健康状态。
🟢 active = 2分钟内有心跳
🟡 stale = 心跳在2-10分钟前
🔴 offline = 心跳超过10分钟或缺失
"""
heartbeats_file = Path(data_dir) / "heartbeats.json"
if not heartbeats_file.exists():
return {}
heartbeats = json.loads(heartbeats_file.read_text())
now = datetime.now(timezone.utc)
status = {}
for agent, last_beat in heartbeats.items():
last = datetime.fromisoformat(last_beat)
delta = now - last
if delta < timedelta(minutes=2):
status[agent] = "🟢 active"
elif delta < timedelta(minutes=10):
status[agent] = "🟡 stale"
else:
status[agent] = "🔴 offline"
return statusUsage
使用示例
health = check_agent_health()
for agent, s in health.items():
print(f"{agent:12} {s}")
undefinedhealth = check_agent_health()
for agent, s in health.items():
print(f"{agent:12} {s}")
undefinedCustom SOUL.md (Agent Personality)
自定义SOUL.md(Agent个性)
markdown
<!-- ~/.openclaw/workspaces/gongbu/SOUL.md -->markdown
<!-- ~/.openclaw/workspaces/gongbu/SOUL.md -->工部尚书 · Minister of Works
工部尚书 · Minister of Works
Role
角色定位
You are the Minister of Works (工部). You handle all technical,
engineering, and infrastructure tasks assigned by Shangshu Province.
你是工部尚书,负责处理尚书省分配的所有技术、工程和基础设施类任务。
Rules
规则
- Always break technical tasks into concrete, verifiable steps
- Return structured results: { "status": "...", "output": "...", "artifacts": [] }
- Flag blockers immediately — do not silently fail
- Estimate complexity: S/M/L/XL before starting
- 始终将技术任务拆解为具体、可验证的步骤
- 返回结构化结果:{ "status": "...", "output": "...", "artifacts": [] }
- 立即标记阻塞问题 — 不要静默失败
- 开始任务前评估复杂度:S/M/L/XL
Output Format
输出格式
Always respond with valid JSON. Include a field ≤ 50 chars
for kanban display.
summary
---始终返回有效的JSON。包含一个长度≤50字符的字段,用于看板展示。
summary
---Dashboard Panels
仪表盘面板
| Panel | URL Fragment | Key Features |
|---|---|---|
| Kanban | | Task columns, heartbeat badges, filter/search, pause/cancel/resume |
| Monitor | | Agent health cards, task distribution charts |
| Memorials | | Completed task archive, 5-stage timeline, Markdown export |
| Templates | | 9 preset edict templates with parameter forms |
| Officials | | Token usage ranking, activity stats |
| News | | Daily tech/finance briefing, Feishu push |
| Models | | Per-agent LLM switcher (hot reload ~5s) |
| Skills | | View/add agent skills |
| Sessions | | Live OC-* session monitor |
| Court | | Multi-agent discussion around a topic |
| 面板 | URL片段 | 核心功能 |
|---|---|---|
| 看板 | | 任务列、心跳徽章、筛选/搜索、暂停/取消/恢复任务 |
| 监控 | | Agent健康卡片、任务分布图表 |
| 奏折 | | 已完成任务存档、5阶段时间线、Markdown导出 |
| 模板 | | 9个预设指令模板及参数表单 |
| 官员统计 | | Token使用排名、活跃度统计 |
| 新闻 | | 每日科技/财经简报、飞书推送 |
| 模型管理 | | 单个Agent LLM切换器(热重载约5秒) |
| 技能管理 | | 查看/添加Agent技能 |
| 会话监控 | | 实时OC-*会话监控 |
| 朝议 | | 围绕特定主题的多Agent讨论 |
Common Patterns
常见使用模式
Pattern 1: Parallel Ministry Execution
模式1:六部并行执行
python
undefinedpython
undefinedShangshu dispatches to multiple ministries simultaneously
尚书省同时将任务分派至多个六部
Each ministry works independently; shangshu aggregates results
每个六部独立工作;尚书省汇总结果
edict = "竞品分析:研究TOP3竞争对手的产品、定价、市场策略"
edict = "竞品分析:研究TOP3竞争对手的产品、定价、市场策略"
Zhongshu splits into subtasks:
中书省拆解为子任务:
hubu → pricing analysis
hubu → 定价分析
libu → market communication analysis
libu → 市场传播分析
bingbu → competitive strategy analysis
bingbu → 竞争策略分析
gongbu → technical feature comparison
gongbu → 技术特性对比
All execute in parallel; shangshu waits for all 4, then aggregates
所有子任务并行执行;尚书省等待全部4个结果后汇总
undefinedundefinedPattern 2: Menxia Veto Loop
模式2:门下省否决循环
python
undefinedpython
undefinedIf menxia rejects zhongshu's plan:
如果门下省否决中书省的计划:
menxia → zhongshu: "子任务拆解不完整,缺少风险评估维度,请补充"
menxia → zhongshu: "子任务拆解不完整,缺少风险评估维度,请补充"
zhongshu revises and resubmits to menxia
中书省修改后重新提交给门下省
Loop continues until menxia approves
循环直至门下省批准
Max iterations configurable in openclaw.json: "max_review_cycles": 3
最大迭代次数可在openclaw.json中配置:"max_review_cycles": 3
undefinedundefinedPattern 3: News Aggregation + Push
模式3:新闻聚合+推送
python
undefinedpython
undefinedscripts/fetch_news.py → data/news.json → dashboard #news panel
scripts/fetch_news.py → data/news.json → 仪表盘#news面板
Optional Feishu push:
可选飞书推送:
import os, json, urllib.request
def push_to_feishu(summary: str):
webhook = os.environ["FEISHU_WEBHOOK_URL"]
payload = json.dumps({
"msg_type": "text",
"content": {"text": f"📰 天下要闻\n{summary}"}
}).encode()
req = urllib.request.Request(
webhook, data=payload,
headers={"Content-Type": "application/json"}
)
urllib.request.urlopen(req)
---import os, json, urllib.request
def push_to_feishu(summary: str):
webhook = os.environ["FEISHU_WEBHOOK_URL"]
payload = json.dumps({
"msg_type": "text",
"content": {"text": f"📰 天下要闻\n{summary}"}
}).encode()
req = urllib.request.Request(
webhook, data=payload,
headers={"Content-Type": "application/json"}
)
urllib.request.urlopen(req)
---Troubleshooting
故障排查
exec format error
in Docker
exec format errorDocker中出现exec format error
exec format errorbash
undefinedbash
undefinedForce platform on x86/amd64
在x86/amd64架构上强制指定平台
docker run --platform linux/amd64 -p 7891:7891 cft0808/sansheng-demo
undefineddocker run --platform linux/amd64 -p 7891:7891 cft0808/sansheng-demo
undefinedAgents not receiving messages
Agent无法接收消息
bash
undefinedbash
undefinedEnsure sessions visibility is set to "all"
确保会话可见性设置为"all"
openclaw config set sessions.visibility all
openclaw gateway restart
openclaw config set sessions.visibility all
openclaw gateway restart
Or re-run install.sh — it sets this automatically
或重新运行install.sh — 脚本会自动设置该配置
./install.sh
undefined./install.sh
undefinedAPI key not propagated to all agents
API密钥未同步到所有Agent
bash
undefinedbash
undefinedRe-run install after configuring key on first agent
在第一个Agent上配置密钥后重新运行安装脚本
openclaw agents add taizi # configure key here
./install.sh # propagates to all agents
undefinedopenclaw agents add taizi # 在此处配置密钥
./install.sh # 同步到所有Agent
undefinedDashboard shows stale data
仪表盘显示陈旧数据
bash
undefinedbash
undefinedEnsure run_loop.sh is running
确保run_loop.sh正在运行
bash scripts/run_loop.sh
bash scripts/run_loop.sh
Or trigger manual refresh
或触发手动刷新
python3 scripts/sync_officials.py
python3 scripts/kanban_update.py
undefinedpython3 scripts/sync_officials.py
python3 scripts/kanban_update.py
undefinedReact frontend not built
React前端未构建
bash
undefinedbash
undefinedRequires Node.js 18+
需要Node.js 18+
cd dashboard/frontend
npm install && npm run build
cd dashboard/frontend
npm install && npm run build
server.py will then serve the built assets
之后server.py将提供构建后的静态资源
undefinedundefinedInvalid state transition error
出现无效状态转换错误
python
undefinedpython
undefinedkanban_update.py enforces the state machine
kanban_update.py强制执行状态机规则
Check current status before updating:
更新前检查当前状态:
tasks = get_kanban_tasks()
task = next(t for t in tasks if t["id"] == "your-task-id")
print(f"Current: {task['status']}")
print(f"Allowed next: {VALID_TRANSITIONS[task['status']]}")
undefinedtasks = get_kanban_tasks()
task = next(t for t in tasks if t["id"] == "your-task-id")
print(f"当前状态:{task['status']}")
print(f"允许的下一个状态:{VALID_TRANSITIONS[task['status']]}")
undefinedGateway restart after model change
模型变更后重启网关
bash
undefinedbash
undefinedAfter editing openclaw.json models section
编辑openclaw.json的models部分后
openclaw gateway restart
openclaw gateway restart
Wait ~5 seconds for agents to reconnect
等待约5秒让Agent重新连接
---
---Project Structure
项目结构
edict/
├── install.sh # One-command setup
├── openclaw.json # Agent registry + permissions + model config
├── scripts/
│ ├── run_loop.sh # Continuous data refresh daemon
│ ├── kanban_update.py # State machine enforcement
│ ├── sync_officials.py # Agent stats aggregation
│ └── fetch_news.py # News aggregation
├── dashboard/
│ ├── server.py # stdlib-only HTTP + WebSocket server (port 7891)
│ ├── dashboard.html # Fallback single-file dashboard
│ └── frontend/ # React 18 source (builds to server.py assets)
├── data/ # Shared data (symlinked into all workspaces)
│ ├── tasks.json
│ ├── heartbeats.json
│ ├── news.json
│ └── officials.json
├── workspaces/ # Per-agent workspace roots
│ ├── taizi/SOUL.md
│ ├── zhongshu/SOUL.md
│ └── ...
└── docs/
├── task-dispatch-architecture.md
└── getting-started.mdedict/
├── install.sh # 一键安装脚本
├── openclaw.json # Agent注册表 + 权限配置 + 模型配置
├── scripts/
│ ├── run_loop.sh # 持续数据刷新守护进程
│ ├── kanban_update.py # 状态机强制执行脚本
│ ├── sync_officials.py # Agent统计数据聚合脚本
│ └── fetch_news.py # 新闻聚合脚本
├── dashboard/
│ ├── server.py # 仅依赖标准库的HTTP + WebSocket服务器(端口7891)
│ ├── dashboard.html # 备用单文件仪表盘
│ └── frontend/ # React 18源码(构建后由server.py提供服务)
├── data/ # 共享数据目录(符号链接至所有工作区)
│ ├── tasks.json
│ ├── heartbeats.json
│ ├── news.json
│ └── officials.json
├── workspaces/ # 单个Agent工作区根目录
│ ├── taizi/SOUL.md
│ ├── zhongshu/SOUL.md
│ └── ...
└── docs/
├── task-dispatch-architecture.md
└── getting-started.md