Files
edict/docs/task-dispatch-architecture.md
cft0808 0f1c24bd44 fix: 修复多个bug并合并社区贡献
Bug 修复:
- Fix #232: court_discuss.py 添加 from __future__ import annotations 兼容 Python 3.9
- Fix #233: Dockerfile 添加 channels 模块 COPY 解决 Docker 运行时 ModuleNotFoundError
- Fix #234: sync_agent_config.py 将 dispatchChannel 默认值从 'feishu' 改为空字符串
- Fix #241: sync_agent_config.py 收集 defaults.models 中的所有可用模型到看板选择器

社区贡献 (cherry-pick):
- PR #239 (@ElninoZhong): 添加 workflow state vs execution ownership 文档
- PR #237 (@ElninoZhong): 修复 feishu 默认值问题
- PR #212 (@YIOYIOIOI): Windows install.ps1 优先 python 命令 + UTF-8 编码修复

依赖更新 (Dependabot):
- actions/checkout v4 → v6
- docker/setup-buildx-action v3 → v4
- docker/build-push-action v5 → v7
- actions/labeler v5 → v6
- actions/stale v9 → v10
2026-03-30 21:48:55 +08:00

55 KiB
Raw Permalink Blame History

三省六部任务分发流转体系 · 业务与技术架构

本文档详细阐述「三省六部」项目如何从业务制度设计代码实现细节完整处理复杂多Agent协作的任务分发与流转。这是一个制度化的AI多Agent框架,而非传统的自由讨论式协作系统。

文档概览图

━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
业务层:帝国制度 (Imperial Governance Model)
  ├─ 分权制衡:皇上 → 太子 → 中书 → 门下 → 尚书 → 六部
  ├─ 制度约束:不可越级、状态严格递进、门下必审议
  └─ 质量保障:可封驳反工、实时可观测、紧急可干预
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
技术层OpenClaw多Agent编排 (Multi-Agent Orchestration)
  ├─ 状态机9个状态Pending → Taizi → Zhongshu → Menxia → Assigned → Doing/Next → Review → Done/Cancelled
  ├─ 数据融合flow_log + progress_log + session JSONL → unified activity stream
  ├─ 权限矩阵严格的subagent调用权限控制
  └─ 调度层:自动派发、超时重试、停滞升级、自动回滚
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
观测层React 看板 + 实时API (Dashboard + Real-time Analytics)
  ├─ 任务看板10个视图面板全部/按状态/按部门/按优先级等)
  ├─ 活动流59条/任务的混合活动记录(思考过程、工具调用、状态转移)
  └─ 在线状态Agent 实时节点检测 + 心跳喚醒机制
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

📚 第一部分:业务架构

1.1 帝国制度:分权制衡的设计哲学

核心理念

传统的多Agent框架如CrewAI、AutoGen采用**"自由协作"模式**

  • Agent自主选择协作对象
  • 框架仅提供通信通道
  • 质量控制完全依赖Agent智能
  • 问题容易出现Agent相互制造假数据、重复工作、方案质量无保障

三省六部采用**"制度化协作"模式**,模仿古代帝国官僚体系:

              皇上
              (User)
               │
               ↓
             太子 (Taizi)
        [分拣官、消息接入总负责]
      ├─ 识别:这是旨意还是闲聊?
      ├─ 执行:直接回复闲聊 || 建立任务→转中书
      └─ 权限:只能调用 中书省
               │
               ↓
           中书省 (Zhongshu)
      [规划官、方案起草总负责]
      ├─ 接旨后分析需求
      ├─ 拆解为子任务todos
      ├─ 调用门下省审议 OR 尚书省咨询
      └─ 权限:只能调用 门下 + 尚书
               │
               ↓
           门下省 (Menxia)
        [审议官、质量把握人]
      ├─ 审查中书方案(可行性、完整性、风险)
      ├─ 准奏 OR 封驳(含修改建议)
      ├─ 若封驳 → 返回中书修改 → 重新审议最多3轮
      └─ 权限:只能调用 尚书 + 回调中书
               │
         (✅ 准奏)
               │
               ↓
           尚书省 (Shangshu)
        [派发官、执行总指挥]
      ├─ 接到准奏方案
      ├─ 分析派发给哪个部门
      ├─ 调用六部(礼/户/兵/刑/工/吏)执行
      ├─ 监控各部进度 → 汇总结果
      └─ 权限:只能调用 六部(不能越权调中书)
               │
               ├─ 礼部 (Libu)      - 文档编制官
               ├─ 户部 (Hubu)      - 数据分析官
               ├─ 兵部 (Bingbu)    - 代码实现官
               ├─ 刑部 (Xingbu)    - 测试审查官
               ├─ 工部 (Gongbu)    - 基础设施官
               └─ 吏部 (Libu_hr)   - 人力资源官
               │
         (各部并行执行)
               ↓
           尚书省·汇总
      ├─ 收集六部结果
      ├─ 状态转为 Review
      ├─ 回调中书省转报皇上
               │
               ↓
           中书省·回奏
      ├─ 汇总现象、结论、建议
      ├─ 状态转为 Done
      └─ 回复飞书消息给皇上

制度的4大保障

保障机制 实现细节 防护效果
制度性审核 门下省必审议所有中书方案,不可跳过 防止Agent胡乱执行确保方案具有可行性
分权制衡 权限矩阵:谁能调谁严格定义 防止权力滥用(如尚书越权调中书改方案)
完全可观测 任务看板10个面板 + 59条活动/任务 实时看到任务卡在哪、谁在工作、工作状态如何
实时可干预 看板内一键 stop/cancel/resume/advance 紧急情况如发现Agent走错方向能立即纠正

1.2 任务完整流转流程

流程示意图

stateDiagram-v2
[*] --> Pending: 皇上下旨
Pending --> Taizi: 太子接旨
Taizi --> Zhongshu: 太子转交中书
Zhongshu --> Menxia: 中书提交审议
Menxia --> Zhongshu: 门下封驳(可多次)
Menxia --> Assigned: 门下准奏
Assigned --> Doing: 尚书派发执行
Doing --> Review: 各部完成
Review --> Done: 皇上御批通过
Review --> Menxia: 皇上要求修改
Done --> [*]
Doing --> [*]: 手动取消
Review --> [*]: 业务终止

具体关键路径

理想路径无阻滞4-5天完成

DAY 1:
  10:00 - 皇上飞书:"为三省六部编写完整自动化测试方案"
          太子接旨。state = Taizi, org = 太子
          自动派发 taizi agent → 处理此旨意
  
  10:30 - 太子分拣完毕。判定为「工作旨意」(非闲聊)
          建任务 JJC-20260228-E2E
          flow_log 记录:"皇上 → 太子:下旨"
          state: Taizi → Zhongshu, org: 太子 → 中书省
          自动派发 zhongshu agent

DAY 2:
  09:00 - 中书省接旨。开始规划
          汇报进展:"分析测试需求,拆解为单元/集成/E2E三层"
          progress_log 记录:"中书省 张三:分需求"
          
  15:00 - 中书省完成方案
          todos 快照:需求分析✅、方案设计✅、待审议🔄
          flow_log 记录:"中书省 → 门下省:方案提交审议"
          state: Zhongshu → Menxia, org: 中书省 → 门下省
          自动派发 menxia agent

DAY 3:
  09:00 - 门下省开始审议
          进度汇报:"现在审查方案的完整性和风险"
          
  14:00 - 门下省审议完毕
          判定:"方案可行,但缺失 _infer_agent_id_from_runtime 函数的测试"
          行为:✅ 准奏 (带修改建议)
          flow_log 记录:"门下省 → 尚书省:✅ 准奏通过5条建议"
          state: Menxia → Assigned, org: 门下省 → 尚书省
          OPTIONAL中书省收到建议主动优化方案
          自动派发 shangshu agent

DAY 4:
  10:00 - 尚书省接到准奏
          分析:"该测试方案应派给工部+刑部+礼部协力完成"
          flow_log 记录:"尚书省 → 六部:派发执行(兵吏合作)"
          state: Assigned → Doing, org: 尚书省 → 兵部+刑部+礼部
          自动派发 bingbu/xingbu/libu 三个agent并行

DAY 4-5:
  (各部并行执行)
  - 兵部(bingbu):实现 pytest + unittest 测试框架
  - 刑部(xingbu):编写测试覆盖所有关键函数
  - 礼部(libu):整理测试文档和用例说明
  
  实时汇报hourly progress
  - 兵部:"✅ 已实现 16 个单元测试"
  - 刑部:"🔄 正在编写集成测试8/12 完成)"
  - 礼部:"等待兵部完成再写报告"

DAY 5:
  14:00 - 各部完成
          state: Doing → Review, org: 兵部 → 尚书省
          尚书省汇总:"所有测试已完成,通过率 98.5%"
          转回中书省
          
  15:00 - 中书省回奏皇上
          state: Review → Done
          模板回复飞书,含最终成果链接和总结

挫折路径含封驳和重试6-7天

DAY 2 同上

DAY 3 [封驳场景]
  14:00 - 门下省审议完毕
          判定:"方案不完整,缺少性能测试 + 压力测试"
          行为:🚫 封驳
          review_round += 1
          flow_log 记录:"门下省 → 中书省:🚫 封驳(需补充性能测试)"
          state: Menxia → Zhongshu  # 返回中书修改
          自动派发 zhongshu agent重新规划

DAY 3-4
  16:00 - 中书省收到封驳通知唤醒agent
          分析改进意见,补充性能测试方案
          progress"已整合性能测试需求,修正方案如下..."
          flow_log 记录:"中书省 → 门下省修订方案第2轮审议"
          state: Zhongshu → Menxia
          自动派发 menxia agent

  18:00 - 门下省重新审议
          判定:"✅ 本次通过"
          flow_log 记录:"门下省 → 尚书省:✅ 准奏通过第2轮"
          state: Menxia → Assigned → Doing
          后续同理想路径...

DAY 7全部完成比理想路径晚1-2天

1.3 任务规格书与业务契约

Task Schema 字段说明

{
  "id": "JJC-20260228-E2E",          // 任务全局唯一ID (JJC-日期-序号)
  "title": "为三省六部编写完整自动化测试方案",
  "official": "中书令",              // 负责官职
  "org": "中书省",                   // 当前负责部门
  "state": "Assigned",               // 当前状态(见 _STATE_FLOW
  
  // ──── 质量与约束 ────
  "priority": "normal",              // 优先级critical/high/normal/low
  "block": "无",                     // 当前阻滞原因(如"等待工部反馈"
  "reviewRound": 2,                  // 门下审议第几轮
  "_prev_state": "Menxia",           // 若被 stop记录之前状态用于 resume
  
  // ──── 业务产出 ────
  "output": "",                      // 最终任务成果URL/文件路径/总结)
  "ac": "",                          // Acceptance Criteria验收标准
  "priority": "normal",
  
  // ──── 流转记录 ────
  "flow_log": [
    {
      "at": "2026-02-28T10:00:00Z",
      "from": "皇上",
      "to": "太子",
      "remark": "下旨:为三省六部编写完整自动化测试方案"
    },
    {
      "at": "2026-02-28T10:30:00Z",
      "from": "太子",
      "to": "中书省",
      "remark": "分拣→传旨"
    },
    {
      "at": "2026-02-28T15:00:00Z",
      "from": "中书省",
      "to": "门下省",
      "remark": "规划方案提交审议"
    },
    {
      "at": "2026-03-01T09:00:00Z",
      "from": "门下省",
      "to": "中书省",
      "remark": "🚫 封驳:需补充性能测试"
    },
    {
      "at": "2026-03-01T15:00:00Z",
      "from": "中书省",
      "to": "门下省",
      "remark": "修订方案第2轮审议"
    },
    {
      "at": "2026-03-01T20:00:00Z",
      "from": "门下省",
      "to": "尚书省",
      "remark": "✅ 准奏通过第2轮5条建议已采纳"
    }
  ],
  
  // ──── Agent 实时汇报 ────
  "progress_log": [
    {
      "at": "2026-02-28T10:35:00Z",
      "agent": "zhongshu",              // 汇报agent
      "agentLabel": "中书省",
      "text": "已接旨。分析测试需求,拟定三层测试方案...",
      "state": "Zhongshu",              // 汇报时的状态快照
      "org": "中书省",
      "tokens": 4500,                   // 资源消耗
      "cost": 0.0045,
      "elapsed": 120,
      "todos": [                        // 待办任务快照
        {"id": "1", "title": "需求分析", "status": "completed"},
        {"id": "2", "title": "方案设计", "status": "in-progress"},
        {"id": "3", "title": "await审议", "status": "not-started"}
      ]
    },
    // ... 更多 progress_log 条目 ...
  ],
  
  // ──── 调度元数据 ────
  "_scheduler": {
    "enabled": true,
    "stallThresholdSec": 180,         // 停滞超过180秒自动升级
    "maxRetry": 1,                    // 自动重试最多1次
    "retryCount": 0,
    "escalationLevel": 0,             // 0=无升级 1=门下协调 2=尚书协调
    "lastProgressAt": "2026-03-01T20:00:00Z",
    "stallSince": null,               // 何时开始停滞
    "lastDispatchStatus": "success",  // queued|success|failed|timeout|error
    "snapshot": {
      "state": "Assigned",
      "org": "尚书省",
      "note": "review-before-approve"
    }
  },
  
  // ──── 生命周期 ────
  "archived": false,                 // 是否归档
  "now": "门下省准奏,移交尚书省派发",  // 当前实时状态描述
  "updatedAt": "2026-03-01T20:00:00Z"
}

业务契约

契约 含义 违反后果
不可越级 太子只能调中书,中书只能调门下/尚书,六部不能对外调用 超权调用被拒绝,系统自动拦截
状态单向递进 Pending → Taizi → Zhongshu → ... → Done不能跳过或倒退 只能通过 review_action(reject) 返回上一步
门下必审 所有中书提出的方案都要门下省审议,无法跳过 中书不能直接转尚书,门下必入
一旦Done无改 任务进入Done/Cancelled后不能再修改状态 若需修改需要创建新任务或取消后重新建
task_id唯一性 JJC-日期-序号 全局唯一,同一天同一任务不重复建 看板防重,自动去重
资源消耗透明 每次进展汇报都要上报 tokens/cost/elapsed 便于成本核算和性能优化

🔧 第二部分:技术架构

2.1 状态机与自动派发

状态转移完整定义

_STATE_FLOW = {
    'Pending':  ('Taizi',   '皇上',    '太子',    '待处理旨意转交太子分拣'),
    'Taizi':    ('Zhongshu','太子',    '中书省',  '太子分拣完毕,转中书省起草'),
    'Zhongshu': ('Menxia',  '中书省',  '门下省',  '中书省方案提交门下省审议'),
    'Menxia':   ('Assigned','门下省',  '尚书省',  '门下省准奏,转尚书省派发'),
    'Assigned': ('Doing',   '尚书省',  '六部',    '尚书省开始派发执行'),
    'Next':     ('Doing',   '尚书省',  '六部',    '待执行任务开始执行'),
    'Doing':    ('Review',  '六部',    '尚书省',  '各部完成,进入汇总'),
    'Review':   ('Done',    '尚书省',  '太子',    '全流程完成,回奏太子转报皇上'),
}

每个状态自动关联 Agent ID_STATE_AGENT_MAP

_STATE_AGENT_MAP = {
    'Taizi':    'taizi',
    'Zhongshu': 'zhongshu',
    'Menxia':   'menxia',
    'Assigned': 'shangshu',
    'Doing':    None,      # 从 org 推断(六部之一)
    'Next':     None,      # 从 org 推断
    'Review':   'shangshu',
    'Pending':  'zhongshu',
}

自动派发流程

当任务状态转移时(通过 handle_advance_state() 或审批),后台自动执行派发:

1. 状态转移触发派发
   ├─ 查表 _STATE_AGENT_MAP 得到目标 agent_id
   ├─ 若是 Doing/Next从 task.org 查表 _ORG_AGENT_MAP 推断具体部门agent
   └─ 若无法推断则跳过派发(如 Done/Cancelled

2. 构造派发消息针对性促使Agent立即工作
   ├─ taizi: "📜 皇上旨意需要你处理..."
   ├─ zhongshu: "📜 旨意已到中书省,请起草方案..."
   ├─ menxia: "📋 中书省方案提交审议..."
   ├─ shangshu: "📮 门下省已准奏,请派发执行..."
   └─ 六部: "📌 请处理任务..."

3. 后台异步派发(非阻塞)
   ├─ spawn daemon thread
   ├─ 标记 _scheduler.lastDispatchStatus = 'queued'
   ├─ 检查 Gateway 进程是否开启
   ├─ 运行 openclaw agent --agent {id} -m "{msg}" --deliver --timeout 300
   ├─ 重试最多2次失败间隔5秒退避
   ├─ 更新 _scheduler 状态和错误信息
   └─ flow_log 记录派发结果

4. 派发状态转移
   ├─ success: 立即更新 _scheduler.lastDispatchStatus = 'success'
   ├─ failed: 记录失败原因Agent 超时不会 block 看板
   ├─ timeout: 标记 timeout允许用户手动重试 / 升级
   ├─ gateway-offline: Gateway 未启动,跳过此次派发(后续可重试)
   └─ error: 异常情况,记录堆栈供调试

5. 到达目标Agent的处理
   ├─ Agent 从飞书消息收到通知
   ├─ 通过 kanban_update.py 与看板交互(更新状态/记录进展)
   └─ 完成工作后再次触发派发到下一个Agent

2.2 权限矩阵与Subagent调用

权限定义openclaw.json 中配置)

{
  "agents": [
    {
      "id": "taizi",
      "label": "太子",
      "allowAgents": ["zhongshu"]
    },
    {
      "id": "zhongshu",
      "label": "中书省",
      "allowAgents": ["menxia", "shangshu"]
    },
    {
      "id": "menxia",
      "label": "门下省",
      "allowAgents": ["shangshu", "zhongshu"]
    },
    {
      "id": "shangshu",
      "label": "尚书省",
      "allowAgents": ["libu", "hubu", "bingbu", "xingbu", "gongbu", "libu_hr"]
    },
    {
      "id": "libu",
      "label": "礼部",
      "allowAgents": []
    },
    // ... 其他六部同样 allowAgents = [] ...
  ]
}

权限检查机制(代码层面)

dispatch_for_state() 之外,还有一套防御性的权限检查:

def can_dispatch_to(from_agent, to_agent):
    """检查 from_agent 是否有权调用 to_agent。"""
    cfg = read_json(DATA / 'agent_config.json', {})
    agents = cfg.get('agents', [])
    
    from_record = next((a for a in agents if a.get('id') == from_agent), None)
    if not from_record:
        return False, f'{from_agent} 不存在'
    
    allowed = from_record.get('allowAgents', [])
    if to_agent not in allowed:
        return False, f'{from_agent} 无权调用 {to_agent}(允许列表:{allowed}'
    
    return True, 'OK'

权限违反示例与处理

场景 请求 结果 理由
正常 中书省 → 门下省审议 允许 门下在中书的 allowAgents 中
违反 中书省 → 尚书省改方案 拒绝 中书只能调门下/尚书,不能手工改尚书工作
违反 工部 → 尚书省 "我完成了" 改状态 通过 flow_log 和 progress_log不是跨Agent调用
违反 尚书省 → 中书省 "重新改方案" 拒绝 尚书不在门下/中书的 allowAgents 中
防控 Agent 伪造其他agent派发 拦截 API 层验证 HTTP 请求来源/签名

2.3 数据融合progress_log + session JSONL

现象

当任务执行时,有三层数据源:

1⃣ flow_log
   └─ 纯粹记录状态转移Zhongshu → Menxia
   └─ 数据源:任务 JSON 的 flow_log 字段
   └─ 来自Agent 通过 kanban_update.py flow 命令上报

2⃣ progress_log
   └─ Agent 的实时工作汇报文本进展、todos快照、资源消耗
   └─ 数据源:任务 JSON 的 progress_log 字段
   └─ 来自Agent 通过 kanban_update.py progress 命令上报
   └─ 周期通常每30分钟或关键节点上报1次

3⃣ session JSONL新增
   └─ Agent 的内部思考过程thinking、工具调用tool_result、对话历史user
   └─ 数据源:~/.openclaw/agents/{agent_id}/sessions/*.jsonl
   └─ 来自OpenClaw框架自动记录Agent无需主动操作
   └─ 周期:消息级别,粒度最细

问题诊断

过去,只靠 flow_log + progress_log 展现进展:

  • 看不到Agent的具体思考过程
  • 看不到每次工具调用的结果
  • 看不到Agent中间的对话历史
  • Agent 表现出"黑盒状态"

例如progress_log 记录"正在分析需求",但用户看不到到底分析了什么。

解决方案Session JSONL 融合

get_task_activity() 中新增融合逻辑40行

def get_task_activity(task_id):
    # ... 前面代码同上 ...
    
    # ── 融合 Agent Session 活动thinking / tool_result / user──
    session_entries = []
    
    # 活跃任务:尝试按 task_id 精确匹配
    if state not in ('Done', 'Cancelled'):
        if agent_id:
            entries = get_agent_activity(
                agent_id, limit=30, task_id=task_id
            )
            session_entries.extend(entries)
        
        # 也从相关Agent获取
        for ra in related_agents:
            if ra != agent_id:
                entries = get_agent_activity(
                    ra, limit=20, task_id=task_id
                )
                session_entries.extend(entries)
    else:
        # 已完成任务:基于关键词匹配
        title = task.get('title', '')
        keywords = _extract_keywords(title)
        if keywords:
            for ra in related_agents[:5]:
                entries = get_agent_activity_by_keywords(
                    ra, keywords, limit=15
                )
                session_entries.extend(entries)
    
    # 去重(通过 at+kind 去重避免重复)
    existing_keys = {(a.get('at', ''), a.get('kind', '')) for a in activity}
    for se in session_entries:
        key = (se.get('at', ''), se.get('kind', ''))
        if key not in existing_keys:
            activity.append(se)
            existing_keys.add(key)
    
    # 重新排序
    activity.sort(key=lambda x: x.get('at', ''))
    
    # 返回时标记数据来源
    return {
        'activity': activity,
        'activitySource': 'progress+session',  # 新标记
        # ... 其他字段 ...
    }

Session JSONL 格式解析

从 JSONL 中提取的条目,统一转换为看板活动条目:

def _parse_activity_entry(item):
    """将 session jsonl 的 message 统一解析成看板活动条目。"""
    msg = item.get('message', {})
    role = str(msg.get('role', '')).strip().lower()
    ts = item.get('timestamp', '')
    
    # 🧠 Assistant 角色 - Agent思考过程
    if role == 'assistant':
        entry = {
            'at': ts,
            'kind': 'assistant',
            'text': '...主回复...',
            'thinking': '💭 Agent考虑到...',  # 内部思维链
            'tools': [
                {'name': 'bash', 'input_preview': 'cd /src && npm test'},
                {'name': 'file_read', 'input_preview': 'dashboard/server.py'},
            ]
        }
        return entry
    
    # 🔧 Tool Result - 工具调用结果
    if role in ('toolresult', 'tool_result'):
        entry = {
            'at': ts,
            'kind': 'tool_result',
            'tool': 'bash',
            'exitCode': 0,
            'output': '✓ All tests passed (123 tests)',
            'durationMs': 4500  # 执行时长
        }
        return entry
    
    # 👤 User - 人工反馈或对话
    if role == 'user':
        entry = {
            'at': ts,
            'kind': 'user',
            'text': '请实现测试用例的异常处理'
        }
        return entry

融合后的活动流结构

单个任务的59条活动流JJC-20260228-E2E 示例):

kind    count  代表事件
────────────────────────────────────────────────
flow      10   状态转移链Pending→Taizi→Zhongshu→...
progress  11   Agent工作汇报"正在分析"、"已完成"
todos     11   待办任务快照(进度更新时每条)
user       1   用户反馈(如"需要补充性能测试"
assistant 10   Agent思考过程💭 reasoning chain
tool_result 16   工具调用记录bash运行结果、API调用结果
────────────────────────────────────────────────
总计      59   完整工作轨迹

看板展示时,用户可以:

  • 📋 看流转链了解任务在哪个阶段
  • 📝 看 progress 了解Agent实时说了什么
  • 看 todos 了解任务拆解和完成进度
  • 💭 看 assistant/thinking 了解Agent的思考过程
  • 🔧 看 tool_result 了解每次工具调用的结果
  • 👤 看 user 了解是否有人工干预

2.4 调度系统:超时重试、停滞升级、自动回滚

调度元数据结构

_scheduler = {
    # 配置参数
    'enabled': True,
    'stallThresholdSec': 180,         # 停滞多久后自动升级默认180秒
    'maxRetry': 1,                    # 自动重试次数0=不重试1=重试1次
    'autoRollback': True,             # 是否自动回滚到快照
    
    # 运行时状态
    'retryCount': 0,                  # 当前已重试几次
    'escalationLevel': 0,             # 0=无升级 1=门下协调 2=尚书协调
    'stallSince': None,               # 何时开始停滞的时间戳
    'lastProgressAt': '2026-03-01T...',  # 最后一次获得进展的时间
    'lastEscalatedAt': '2026-03-01T...',
    'lastRetryAt': '2026-03-01T...',
    
    # 派发追踪
    'lastDispatchStatus': 'success',  # queued|success|failed|timeout|gateway-offline|error
    'lastDispatchAgent': 'zhongshu',
    'lastDispatchTrigger': 'state-transition',
    'lastDispatchError': '',          # 错误堆栈(如有)
    
    # 快照(用于自动回滚)
    'snapshot': {
        'state': 'Assigned',
        'org': '尚书省',
        'now': '等待派发...',
        'savedAt': '2026-03-01T...',
        'note': 'scheduled-check'
    }
}

调度算法

每 60 秒运行一次 handle_scheduler_scan(threshold_sec=180)

FOR EACH 任务:
  IF state in (Done, Cancelled, Blocked):
    SKIP  # 终态不处理
  
  elapsed_since_progress = NOW - lastProgressAt
  
  IF elapsed_since_progress < stallThreshold:
    SKIP  # 最近有进展,无需处理
  
  # ── 停滞处理逻辑 ──
  IF retryCount < maxRetry:
    ✅ 执行【重试】
    - increment retryCount
    - dispatch_for_state(task, new_state, trigger='taizi-scan-retry')
    - flow_log: "停滞180秒触发自动重试第N次"
    - NEXT task
  
  IF escalationLevel < 2:
    ✅ 执行【升级】
    - nextLevel = escalationLevel + 1
    - target_agent = menxia (if L=1) else shangshu (if L=2)
    - wake_agent(target_agent, "💬 任务停滞,请介入协调推进")
    - flow_log: "升级至{target_agent}协调"
    - NEXT task
  
  IF escalationLevel >= 2 AND autoRollback:
    ✅ 执行【自动回滚】
    - restore task to snapshot.state
    - retryCount = 0
    - escalationLevel = 0
    - dispatch_for_state(task, snapshot.state, trigger='taiji-auto-rollback')
    - flow_log: "连续停滞,自动回滚到{snapshot.state}"

示例场景

场景中书省Agent进程崩溃任务卡在 Zhongshu

T+0:
  中书省正在规划方案
  lastProgressAt = T
  dispatch status = success

T+30:
  Agent 进程意外崩溃(或超载无响应)
  lastProgressAt 仍然 = T没有新的 progress

T+60:
  scheduler_scan 扫一遍,发现:
  elapsed = 60 < 180跳过

T+180:
  scheduler_scan 扫一遍,发现:
  elapsed = 180 >= 180触发处理
  
  ✅ 阶段1重试
  - retryCount: 0 → 1
  - dispatch_for_state('JJC-20260228-E2E', 'Zhongshu', trigger='taizi-scan-retry')
  - 派发消息发送到中书省唤醒agent或重启
  - flow_log: "停滞180秒自动重试第1次"

T+ 240:
  中书省 Agent 恢复(或手工重启),收到重试派发
  汇报进展:"已恢复,继续规划..."
  lastProgressAt 更新为 T+240
  retryCount 重置为 0
  
  ✓ 问题解决

T+360 (若仍未恢复):
  scheduler_scan 再次扫,发现:
  elapsed = 360 >= 180, retryCount 已经 = 1
  
  ✅ 阶段2升级
  - escalationLevel: 0 → 1
  - wake_agent('menxia', "💬 任务JJC-20260228-E2E停滞中书省无反应请介入")
  - flow_log: "升级至门下省协调"
  
  门下省Agent被唤醒可以
  - 检查中书省是否在线
  - 若在线,询问进度
  - 若离线,可能启动应急流程(如由门下暂代起草)

T+540 (若仍未解决):
  scheduler_scan 再次扫,发现:
  escalationLevel = 1, 还能升级到 2
  
  ✅ 阶段3再次升级
  - escalationLevel: 1 → 2
  - wake_agent('shangshu', "💬 任务长期停滞,中书省+门下省都无法推进,尚书省请介入协调")
  - flow_log: "升级至尚书省协调"

T+720 (若仍未解决):
  scheduler_scan 再次扫,发现:
  escalationLevel = 2已最大autoRollback = true
  
  ✅ 阶段4自动回滚
  - snapshot.state = 'Assigned' (前一个稳定状态)
  - task.state: Zhongshu → Assigned
  - dispatch_for_state('JJC-20260228-E2E', 'Assigned', trigger='taizi-auto-rollback')
  - flow_log: "连续停滞自动回滚到Assigned由尚书省重新派发"
  
  结果:
  - 尚书省重新派发给六部执行
  - 中书省的方案保留在前一个 snapshot 版本中
  - 用户可以看到回滚操作,决定是否介入

🎯 第三部分核心API与CLI工具

3.1 任务操作API端点

任务创建:POST /api/create-task

请求:
{
  "title": "为三省六部编写完整自动化测试方案",
  "org": "中书省",           // 可选,默认太子
  "official": "中书令",      // 可选
  "priority": "normal",
  "template_id": "test_plan", // 可选
  "params": {},
  "target_dept": "兵部+刑部"  // 可选,派发建议
}

响应:
{
  "ok": true,
  "taskId": "JJC-20260228-001",
  "message": "旨意 JJC-20260228-001 已下达,正在派发给太子"
}

任务活动流:GET /api/task-activity/{task_id}

请求:
GET /api/task-activity/JJC-20260228-E2E

响应:
{
  "ok": true,
  "taskId": "JJC-20260228-E2E",
  "taskMeta": {
    "title": "为三省六部编写完整自动化测试方案",
    "state": "Assigned",
    "org": "尚书省",
    "output": "",
    "block": "无",
    "priority": "normal"
  },
  "agentId": "shangshu",
  "agentLabel": "尚书省",
  
  // ── 完整活动流59条示例──
  "activity": [
    // flow_log (10条)
    {
      "at": "2026-02-28T10:00:00Z",
      "kind": "flow",
      "from": "皇上",
      "to": "太子",
      "remark": "下旨:为三省六部编写完整自动化测试方案"
    },
    // progress_log (11条)
    {
      "at": "2026-02-28T10:35:00Z",
      "kind": "progress",
      "text": "已接旨。分析测试需求,拟定三层测试方案...",
      "agent": "zhongshu",
      "agentLabel": "中书省",
      "state": "Zhongshu",
      "org": "中书省",
      "tokens": 4500,
      "cost": 0.0045,
      "elapsed": 120
    },
    // todos (11条)
    {
      "at": "2026-02-28T15:00:00Z",
      "kind": "todos",
      "items": [
        {"id": "1", "title": "需求分析", "status": "completed"},
        {"id": "2", "title": "方案设计", "status": "in-progress"},
        {"id": "3", "title": "await审议", "status": "not-started"}
      ],
      "agent": "zhongshu",
      "diff": {
        "changed": [{"id": "2", "from": "not-started", "to": "in-progress"}],
        "added": [],
        "removed": []
      }
    },
    // session活动 (26条总计)
    // - assistant (10条)
    {
      "at": "2026-02-28T14:23:00Z",
      "kind": "assistant",
      "text": "基于需求,我建议采用三层测试架构:\n1. 单元测试覆盖核心函数\n2. 集成测试覆盖API端点\n3. E2E测试覆盖完整流程",
      "thinking": "💭 考虑到项目的复杂性需要覆盖七个Agent的交互逻辑。单元测试应该采用pytest集成测试用server.py启动后的HTTP测试...",
      "tools": [
        {"name": "bash", "input_preview": "find . -name '*.py' -type f | wc -l"},
        {"name": "file_read", "input_preview": "dashboard/server.py (first 100 lines)"}
      ]
    },
    // - tool_result (16条)
    {
      "at": "2026-02-28T14:24:00Z",
      "kind": "tool_result",
      "tool": "bash",
      "exitCode": 0,
      "output": "83",
      "durationMs": 450
    }
  ],
  
  "activitySource": "progress+session",
  "relatedAgents": ["taizi", "zhongshu", "menxia"],
  "phaseDurations": [
    {
      "phase": "太子",
      "durationText": "30分",
      "ongoing": false
    },
    {
      "phase": "中书省",
      "durationText": "4小时32分",
      "ongoing": false
    },
    {
      "phase": "门下省",
      "durationText": "1小时15分",
      "ongoing": false
    },
    {
      "phase": "尚书省",
      "durationText": "4小时10分",
      "ongoing": true
    }
  ],
  "totalDuration": "10小时27分",
  "todosSummary": {
    "total": 3,
    "completed": 2,
    "inProgress": 1,
    "notStarted": 0,
    "percent": 67
  },
  "resourceSummary": {
    "totalTokens": 18500,
    "totalCost": 0.0187,
    "totalElapsedSec": 480
  }
}

状态推进:POST /api/advance-state/{task_id}

请求:
{
  "comment": "任务分明该推进了"
}

响应:
{
  "ok": true,
  "message": "JJC-20260228-E2E 已推进到下一阶段 (已自动派发 Agent)",
  "oldState": "Zhongshu",
  "newState": "Menxia",
  "targetAgent": "menxia"
}

审批操作:POST /api/review-action/{task_id}

请求(准奏):
{
  "action": "approve",
  "comment": "方案可行,已采纳改进建议"
}

OR 请求(封驳):
{
  "action": "reject",
  "comment": "需补充性能测试第N轮审议"
}

响应:
{
  "ok": true,
  "message": "JJC-20260228-E2E 已准奏 (已自动派发 Agent)",
  "state": "Assigned",
  "reviewRound": 1
}

3.2 CLI工具kanban_update.py

Agent 通过此工具与看板交互共7个命令

命令1创建任务太子或中书手工

python3 scripts/kanban_update.py create \
  JJC-20260228-E2E \
  "为三省六部编写完整自动化测试方案" \
  Zhongshu \
  中书省 \
  中书令

# 说明通常不需要手工运行看板API自动触发除非debug

命令2更新状态

python3 scripts/kanban_update.py state \
  JJC-20260228-E2E \
  Menxia \
  "方案提交门下省审议"

# 说明:
# - 第一个参数task_id
# - 第二个参数新状态Pending/Taizi/Zhongshu/...
# - 第三个参数:可选,描述信息(会记录到 now 字段)
# 
# 效果:
# - task.state = Menxia
# - task.org 自动推断为 "门下省"
# - 触发派发 menxia agent
# - flow_log 记录转移

命令3添加流转记录

python3 scripts/kanban_update.py flow \
  JJC-20260228-E2E \
  "中书省" \
  "门下省" \
  "📋 方案提交审核,请审议"

# 说明:
# - 参数1task_id
# - 参数2from_dept谁在上报
# - 参数3to_dept流转到谁
# - 参数4remark备注可包含emoji
#
# 注意:只是记录 flow_log不改变 task.state
#(多用于细节流转,如部门间的协调)

命令4实时进展汇报重点

python3 scripts/kanban_update.py progress \
  JJC-20260228-E2E \
  "已完成需求分析和方案初稿,现正征询工部意见" \
  "1.需求分析✅|2.方案设计✅|3.工部咨询🔄|4.待门下审议"

# 说明:
# - 参数1task_id
# - 参数2进展文本说明
# - 参数3todos 当前快照(用 | 分隔各项支持emoji
#
# 效果:
# - progress_log 添加新条目:
#   {
#     "at": now_iso(),
#     "agent": inferred_agent_id,
#     "text": "已完成需求分析和方案初稿,现正征询工部意见",
#     "state": task.state,
#     "org": task.org,
#     "todos": [
#       {"id": "1", "title": "需求分析", "status": "completed"},
#       {"id": "2", "title": "方案设计", "status": "completed"},
#       {"id": "3", "title": "工部咨询", "status": "in-progress"},
#       {"id": "4", "title": "待门下审议", "status": "not-started"}
#     ],
#     "tokens": (自动从 openclaw 会话数据读取),
#     "cost": (自动计算),
#     "elapsed": (自动计算)
#   }
#
# 看板效果:
# - 即时渲染为活动条目
# - todos 进度条更新67% 完成)
# - 资源消耗累加显示

命令5任务完成

python3 scripts/kanban_update.py done \
  JJC-20260228-E2E \
  "https://github.com/org/repo/tree/feature/auto-test" \
  "自动化测试方案已完成,涵盖单元/集成/E2E三层通过率98.5%"

# 说明:
# - 参数1task_id
# - 参数2output URL可以是代码仓库、文档链接等
# - 参数3最终总结
#
# 效果:
# - task.state = Done从 Review 推进)
# - task.output = "https://..."
# - 自动发送Feishu消息给皇上太子转报
# - flow_log 记录完成转移

命令6 & 7停止/取消任务

# 叫停(随时可恢复)
python3 scripts/kanban_update.py stop \
  JJC-20260228-E2E \
  "等待工部反馈继续"

# 说明:
# - task.state 暂存_prev_state
# - task.block = "等待工部反馈继续"
# - 看板显示 "⏸️ 已叫停"
#
# 恢复:
python3 scripts/kanban_update.py resume \
  JJC-20260228-E2E \
  "工部已反馈,继续执行"
#
# - task.state 恢复到 _prev_state
# - 重新派发 agent

# 取消(不可恢复)
python3 scripts/kanban_update.py cancel \
  JJC-20260228-E2E \
  "业务需求变更,任务作废"
#
# - task.state = Cancelled
# - flow_log 记录取消原因

💡 第四部分:对标与对比

CrewAI / AutoGen 的传统方式 vs 三省六部的制度化方式

维度 CrewAI AutoGen 三省六部
协作模式 自由讨论Agent自主选择协作对象 面板+回调Human-in-the-loop 制度化协作(权限矩阵+状态机)
质量保障 依赖Agent智能无审核 Human审核频繁中断 自动审核(门下省必审)+可干预
权限控制 ⚠️ Hard-coded 配置化权限矩阵
可观测性 Agent消息黑盒 Human看到对话 极高59条活动/任务)
可干预性 无(跑起来后很难叫停) 有(需要人工批准) 一键stop/cancel/advance
任务分发 不确定Agent自主选 确定Human手工分 自动确定(权限矩阵+状态机)
吞吐量 1任务1Agent串行讨论 1任务1Team需人工管理 多任务并行(六部同时执行)
失败恢复 (重新开始) ⚠️(需人工调试) 自动重试3阶段
成本控制 不透明(没有成本上限) 中等Human可叫停 透明每条progress上报成本

业务契约的严格性

CrewAI 的"温和"方式

# Agent可以自由选择下一步工作
if task_seems_done:
    # Agent自己决定要不要报告给其他Agent
    send_message_to_someone()  # 可能发错人,可能重复

三省六部的"严格"方式

# 任务状态严格受限,下一步由系统决定
if task.state == 'Zhongshu' and agent_id == 'zhongshu':
    # 只能做Zhongshu该做的事起草方案
    deliver_plan_to_menxia()
    
    # 状态转移只能通过API不能绕过
    # 中书不能直接转尚书,必须经过门下审议
    
    # 若想绕过门下审议
    try:
        dispatch_to(shangshu)  # ❌ 权限检查拦截
    except PermissionError:
        log.error(f'zhongshu 无权越权调用 shangshu')

🔍 第五部分:故障场景与恢复机制

场景1Agent进程崩溃

症状任务卡在某个状态180秒无新进展
报警:太子调度系统检测到停滞

自动处理流程:
  T+0: 崩溃
  T+180: scan 检测到停滞
    ✅ 第1阶段自动重试
       - 派发消息到agent唤醒或重启
       - 如果agent恢复流程继续
  
  T+360: 若仍未恢复
    ✅ 第2阶段升级协调
       - 唤醒门下省agent
       - 汇报:"中书省无响应,请介入"
       - 门下可能接管或代理工作
  
  T+540: 若仍未恢复
    ✅ 第3阶段再次升级
       - 唤醒尚书省agent
       - 汇报:"任务彻底卡住,请企业级协调"
  
  T+720: 若仍未恢复
    ✅ 第4阶段自动回滚
       - 恢复到前一个稳定状态
       - 派发给尚书省重新处理
       - 用户可看到完整回滚链路

场景2Agent作恶伪造数据

假设 zhongshu agent 想骗过系统:

# 尝试伪造门下省的准奏直接改JSON
task['flow_log'].append({
    'from': '门下省',      # ❌ 假冒身份
    'to': '尚书省',
    'remark': '✅ 准奏'
})

# 系统防御:
# 1. 权限验证API 层检查 HTTP 请求者身份
#    ├─ 来自 zhongshu agent 的请求不能直接 flow
#    ├─ 必须通过 flow_log 记录,且签名验证
#    └─ 签名不匹配则拒绝
# 2. 状态机验证:状态转移受控
#    ├─ 即使 flow_log 被篡改state 仍然是 Zhongshu
#    ├─ 下一步只能由 gate-keeper 系统转移
#    └─ zhongshu 无权自己改 state

# 结果:❌ Agent 的伪造被系统拦截

场景3业务流程违反如中书越权调尚书改方案

# 中书省想绕过门下审议,直接咨询尚书省
try:
    result = dispatch_to_agent('shangshu', '请帮我审查一下这个方案')
except PermissionError:
    # ❌ 权限矩阵拦截
    log.error('zhongshu 无权调用 shangshu (仅限: menxia, shangshu)')

# 门下省想升级到皇上
try:
    result = dispatch_to_agent('taizi', '我需要皇上的指示')
except PermissionError:
    # ❌ 权限矩阵拦截
    log.error('menxia 无权调用 taizi')

📊 第六部分:监控与可观测性

看板的10个视图面板

1. 全任务列表
   └─ 所有任务的汇总视图(按创建时间倒序)
   └─ 快速过滤:活跃/完成/已封驳

2. 按状态分类
   ├─ Pending待处理
   ├─ Taizi太子分拣中
   ├─ Zhongshu中书规划中
   ├─ Menxia门下审议中
   ├─ Assigned尚书派发中
   ├─ Doing六部执行中
   ├─ Review尚书汇总中
   └─ Done/Cancelled已完成/已取消)

3. 按部门分类
   ├─ 太子任务
   ├─ 中书省任务
   ├─ 门下省任务
   ├─ 尚书省任务
   ├─ 六部任务(并行视图)
   └─ 已派发任务

4. 按优先级分类
   ├─ 🔴 Critical紧急
   ├─ 🟠 High高优
   ├─ 🟡 Normal普通
   └─ 🔵 Low低优

5. Agent 在线状态
   ├─ 🟢 运行中(正在处理任务)
   ├─ 🟡 待命(最近有活动,闲置)
   ├─ ⚪ 空闲超过10分钟无活动
   ├─ 🔴 离线Gateway 未启动)
   └─ ❌ 未配置(工作空间不存在)

6. 任务详情面板
   ├─ 基本信息(标题、创建人、优先级)
   ├─ 完整活动流flow_log + progress_log + session
   ├─ 阶段耗时统计各Agent停留时间
   ├─ Todos 进度条
   └─ 资源消耗tokens/cost/elapsed

7. 停滞任务监控
   ├─ 列出所有超过阈值未推进的任务
   ├─ 显示停滞时长
   ├─ 快速操作:重试/升级/回滚

8. 审批工单池
   ├─ 清单所有在 Menxia 等待审批的任务
   ├─ 按停留时长排序
   ├─ 一键准奏/封驳

9. 今日概览
   ├─ 今日新建任务数
   ├─ 今日完成任务数
   ├─ 平均流转时长
   ├─ 各Agent活动频率

10. 历史报表
    ├─ 周报(人均产出、平均周期)
    ├─ 月报(部门协作效率)
    └─ 成本分析API调用成本、Agent工作量

实时APIAgent 在线检测

GET /api/agents-status

响应:
{
  "ok": true,
  "gateway": {
    "alive": true,           // 进程存在
    "probe": true,          // HTTP 响应正常
    "status": "🟢 运行中"
  },
  "agents": [
    {
      "id": "taizi",
      "label": "太子",
      "status": "running",        // running|idle|offline|unconfigured
      "statusLabel": "🟢 运行中",
      "lastActive": "03-02 14:30", // 最后活跃时间
      "lastActiveTs": 1708943400000,
      "sessions": 42,             // 活跃session数
      "hasWorkspace": true,
      "processAlive": true
    },
    // ... 其他agent ...
  ]
}

🎓 第七部分:使用示例与最佳实践

完整案例:创建→分发→执行→完成

# ═══════════════════════════════════════════════════════════
# 第1步皇上下旨飞书消息或看板API
# ═══════════════════════════════════════════════════════════

curl -X POST http://127.0.0.1:7891/api/create-task \
  -H "Content-Type: application/json" \
  -d '{
    "title": "编写三省六部协议文档",
    "priority": "high"
  }'

# 响应JJC-20260302-001 已创建
# 太子Agent 收到通知:"📜 皇上旨意..."

# ═══════════════════════════════════════════════════════════
# 第2步太子接旨分拣Agent自动
# ═══════════════════════════════════════════════════════════

# 太子Agent 判定:这是"工作旨意"(非闲聊)
# 自动运行:
python3 scripts/kanban_update.py state \
  JJC-20260302-001 \
  Zhongshu \
  "分拣完毕,转中书省起草"

# 中书省Agent 收到派发通知

# ═══════════════════════════════════════════════════════════
# 第3步中书起草Agent工作
# ═══════════════════════════════════════════════════════════

# 中书Agent 分析需求、拆解任务

# 第一次汇报30分钟后
python3 scripts/kanban_update.py progress \
  JJC-20260302-001 \
  "已完成需求分析,拟定三部分文档:概述|技术栈|使用指南" \
  "1.需求分析✅|2.文档规划✅|3.内容编写🔄|4.审查待完成"

# 看板显示:
# - 进度条50% 完成
# - 活动流:新增 progress + todos 条目
# - 消耗1200 tokens, $0.0012, 18分钟

# 第二次汇报再过90分钟
python3 scripts/kanban_update.py progress \
  JJC-20260302-001 \
  "文档初稿已完成,现提交门下省审议" \
  "1.需求分析✅|2.文档规划✅|3.内容编写✅|4.待审查"

python3 scripts/kanban_update.py flow \
  JJC-20260302-001 \
  "中书省" \
  "门下省" \
  "提交审议"

python3 scripts/kanban_update.py state \
  JJC-20260302-001 \
  Menxia \
  "方案提交门下省审议"

# 门下省Agent 收到派发通知,开始审议

# ═══════════════════════════════════════════════════════════
# 第4步门下审议Agent工作
# ═══════════════════════════════════════════════════════════

# 门下Agent 审查文档质量

# 审议结果30分钟后

# 情景A准奏
python3 scripts/kanban_update.py state \
  JJC-20260302-001 \
  Assigned \
  "✅ 准奏,已采纳改进建议"

python3 scripts/kanban_update.py flow \
  JJC-20260302-001 \
  "门下省" \
  "尚书省" \
  "✅ 准奏:文档质量良好,建议补充代码示例"

# 尚书省Agent 收到派发

# 情景B封驳
python3 scripts/kanban_update.py state \
  JJC-20260302-001 \
  Zhongshu \
  "🚫 封驳:需补充协议规范部分"

python3 scripts/kanban_update.py flow \
  JJC-20260302-001 \
  "门下省" \
  "中书省" \
  "🚫 封驳:协议部分过于简略,需补充权限矩阵示例"

# 中书省Agent 收到唤醒,重新修改方案
# 3小时后 → 重新提交门下审议)

# ═══════════════════════════════════════════════════════════
# 第5步尚书派发Agent工作
# ═══════════════════════════════════════════════════════════

# 尚书省Agent 分析文档应派给谁:
# - 礼部:文档排版和格式
# - 兵部:代码示例补充
# - 工部:部署文档

python3 scripts/kanban_update.py state \
  JJC-20260302-001 \
  Doing \
  "派发给礼部+兵部+工部三部并行执行"

python3 scripts/kanban_update.py flow \
  JJC-20260302-001 \
  "尚书省" \
  "六部" \
  "派发执行:礼部排版|兵部代码示例|工部基础设施部分"

# 六部Agent 分别收到派发

# ═══════════════════════════════════════════════════════════
# 第6步六部执行并行
# ═══════════════════════════════════════════════════════════

# 礼部进展汇报20分钟
python3 scripts/kanban_update.py progress \
  JJC-20260302-001 \
  "已完成文档排版和目录调整,现待其他部门内容补充" \
  "1.排版✅|2.目录调整✅|3.等待代码示例|4.等待基础设施部分"

# 兵部进展汇报40分钟
python3 scripts/kanban_update.py progress \
  JJC-20260302-001 \
  "已编写5个代码示例权限检查、派发流程、session融合等待集成到文档" \
  "1.分析需求✅|2.编码示例✅|3.集成文档🔄|4.测试验证"

# 工部进展汇报60分钟
python3 scripts/kanban_update.py progress \
  JJC-20260302-001 \
  "已编写Docker+K8s部署部分Nginx配置和让证书更新文案完成" \
  "1.Docker编写✅|2.K8s配置✅|3.一键部署脚本🔄|4.部署文档待完成"

# ═══════════════════════════════════════════════════════════
# 第7步尚书汇总Agent工作
# ═══════════════════════════════════════════════════════════

# 等所有部门汇报完成后,尚书省汇总所有成果

python3 scripts/kanban_update.py progress \
  JJC-20260302-001 \
  "全部部门已完成。汇总成果:\n- 文档已排版包含9个章节\n- 15个代码示例已集成\n- 完整部署指南已编写\n通过率100%" \
  "1.排版✅|2.代码示例✅|3.基础设施✅|4.汇总✅"

python3 scripts/kanban_update.py state \
  JJC-20260302-001 \
  Review \
  "所有部门完成,进入审查阶段"

# 皇上/太子收到通知,审查最终成果

# ═══════════════════════════════════════════════════════════
# 第8步完成终态
# ═══════════════════════════════════════════════════════════

python3 scripts/kanban_update.py done \
  JJC-20260302-001 \
  "https://github.com/org/repo/docs/architecture.md" \
  "三省六部协议文档已完成包含89页5个阶段历时3天总消耗成本$2.34"

# 看板显示:
# - 状态Done ✅
# - 总耗时3天2小时45分
# - 完整活动流79条活动记录
# - 资源统计87500 tokens, $2.34, 890分钟总工作时间

# ═══════════════════════════════════════════════════════════
# 查询最终成果
# ═══════════════════════════════════════════════════════════

curl http://127.0.0.1:7891/api/task-activity/JJC-20260302-001

# 响应:
# {
#   "taskMeta": {
#     "state": "Done",
#     "output": "https://github.com/org/repo/docs/architecture.md"
#   },
#   "activity": [79条完整流转链],
#   "totalDuration": "3天2小时45分",
#   "resourceSummary": {
#     "totalTokens": 87500,
#     "totalCost": 2.34,
#     "totalElapsedSec": 53700
#   }
# }

📋 总结

三省六部是一个制度化的AI多Agent系统,不是传统的"自由讨论"框架。它通过:

  1. 业务层:模仿古代帝国官僚体系,建立分权制衡的组织结构
  2. 技术层:状态机 + 权限矩阵 + 自动派发 + 调度重试,确保流程可控
  3. 观测层React 看板 + 完整活动流59条/任务),实时掌握全局
  4. 介入层一键stop/cancel/advance遇到异常能立即纠正

核心价值:用制度确保质量,用透明确保信心,用自动化确保效率。

相比 CrewAI/AutoGen 的"自由+人工管理",三省六部提供了一套企业级的AI协作框架

Workflow state vs execution ownership

In Edict workflows, workflow state and execution ownership are related but not always identical.

Workflow state

Workflow state describes the current institutional stage of a task, for example:

  • Taizi
  • Zhongshu
  • Menxia
  • Assigned
  • Doing
  • Review
  • Done

This is the stage shown in the board/UI and reflects where the task is in the intended process.

Execution ownership

Execution ownership means which actual runtime agent/session currently owns the next action or is writing the next progress/log update.

In simple flows, workflow state and execution ownership may appear to match.

In more complex or multi-stage flows, they can temporarily diverge. For example:

  • the workflow state may already show Assigned
  • while the active runtime execution context is still tied to an earlier stage's dispatch chain

Why this distinction matters

This distinction is useful when:

  • debugging handoff behavior
  • understanding why a later-stage label appears before a fully isolated execution handoff occurs
  • reasoning about future improvements such as stage-isolated orchestration

In short:

  • workflow state = where the task is in the institutional process
  • execution ownership = which runtime path currently holds the next action

This documentation does not change runtime semantics. It only clarifies an important concept for advanced real-world usage.