Files
Dirigent/plans/CHANNEL_MODES_AND_SHUFFLE.md

8.2 KiB
Raw Blame History

Channel Modes & Turn Shuffle 规划

背景

feat/new-feat-notes 分支中的 NEW_FEAT.md 提出了两项新的行为增强需求,需要整合进入 main 分支下的 plans/

  1. Multi-Message Mode人类连续多消息模式
  2. Shuffle Mode轮转顺序重洗牌

这两项能力都与 Dirigent 当前的 turn-manager、moderator handoff、no-reply override 机制直接相关,因此应作为 turn orchestration 的功能扩展纳入规划,而不是孤立实现。


1. Multi-Message Mode

1.1 目标

允许人类在一个 channel 中连续发送多条消息而不被 Agent 打断。

当用户显式进入 multi-message mode 后:

  • 当前 channel 的 turn manager 暂停
  • 所有 Agent 在该 channel 中进入 no-reply 覆盖
  • moderator bot 对每条人类追加消息发送 prompt marker提示继续输入
  • 直到人类发送 end marker 才恢复 turn manager
  • 恢复后由 moderator 按现有调度机制唤醒下一位 Agent

1.2 配置项

新增并已实现以下可配置项:

  • multiMessageStartMarker:默认 ↗️
  • multiMessageEndMarker:默认 ↙️
  • multiMessagePromptMarker:默认 ⤵️

这些配置已加入插件 config schema并在运行时被 message-received / before-message-write / before-model-resolve 使用。


1.3 行为规则

进入 multi-message mode

human 消息中包含 start marker

  • 当前 channel 进入 multi-message 状态
  • turn manager 暂停
  • 当前 channel 下所有 Agent 在该 channel/session 中走 no-reply override

multi-message mode 中

在该模式下:

  • 人类每发一条消息
  • moderator bot 自动回复 prompt marker例如 ⤵️
  • Agent 不应参与正常轮转回复

退出 multi-message mode

human 消息中包含 end marker

  • 当前 channel 退出 multi-message 状态
  • turn manager 恢复
  • moderator bot 发送当前调度标识scheduling identifier唤醒下一位 Agent

1.4 状态建议

每个 Discord channel 维护一个 channel mode

  • normal
  • multi-message
  • (后续可扩展其他模式)

multi-message mode 应与 discussion channel / wait-for-human / no-reply 决策互相兼容,优先级需要明确。

建议优先级初稿:

  1. closed discussion channel
  2. multi-message mode
  3. waiting-for-human
  4. normal turn-manager

2. Shuffle Mode

2.1 目标

在 turn-based speaking 中,为每个 Discord channel 增加可选的 turn order reshuffle 能力。

当 shuffle mode 开启时:

  • 在一轮 turn list 的最后一位 speaker 发言完成后
  • 对 turn order 重新洗牌
  • 但必须保证:上一轮最后一位发言者不能在新一轮中成为第一位

2.2 配置 / 控制方式

为每个 Discord channel 维护:

  • shuffling: boolean

并新增 slash command

  • /dirigent turn-shuffling on
  • /dirigent turn-shuffling off
  • /dirigent turn-shuffling(查看当前状态)

当前实现结论:

  • shufflingchannel 级 runtime state,存放在 plugin/core/channel-modes.ts
  • 默认值为 false
  • 当前版本不新增全局 shuffle default 配置项
  • 重启后会恢复为默认关闭,如需开启需要再次执行命令

这样与现有实现保持一致,也避免把一次性的实验性调度偏好混入全局静态配置。


2.3 行为规则

shuffling = true 时:

  • 正常按 turn order 轮转
  • 当“当前 speaker 是该轮最后一位”并完成发言后
  • 进入下一轮前重洗 turn order
  • 新 turn order 必须满足:
    • 上一轮最后 speaker != 新 turnOrder[0]

若无法满足(极端小集合场景),需要定义 fallback

  • 两个 Agent 时可退化为简单交换/固定顺序
  • 单 Agent 时不需要 shuffle

3. 与当前系统的关系

这两个能力都不是独立子系统,而是 Dirigent turn orchestration 的扩展。

涉及模块

  • plugin/turn-manager.ts
  • plugin/hooks/message-received.ts
  • plugin/hooks/before-model-resolve.ts
  • plugin/hooks/before-message-write.ts
  • plugin/hooks/message-sent.ts
  • plugin/commands/dirigent-command.ts
  • plugin/index.ts
  • plugin/openclaw.plugin.json
  • 如有必要新增 plugin/core/channel-modes.ts 或类似 runtime state 模块

4. 建议实现方向

4.1 Multi-Message Mode

建议不要把 multi-message mode 直接塞进规则判断字符串里,而是做成显式 channel runtime state。

建议新增:

  • channel mode state store
  • helper
    • enterMultiMessageMode(channelId)
    • exitMultiMessageMode(channelId)
    • isMultiMessageMode(channelId)

然后:

  • message-received 检测 human 消息中的 start/end marker
  • before-model-resolve 检测当前 channel 是否处于 multi-message mode若是则直接走 no-reply override
  • message-received 或合适的消息链路中触发 moderator prompt marker
  • 退出时触发一次 scheduling handoff

4.2 Shuffle Mode

建议将 shuffle 状态与 turn order 状态放在一起,或由 turn-manager 引用单独的 channel config/state。

建议新增 helper

  • setChannelShuffling(channelId, enabled)
  • getChannelShuffling(channelId)
  • reshuffleTurnOrder(channelId, { avoidFirstAccountId })

并在 turn cycle 的边界点调用重洗逻辑,而不是在任意发言后随机改顺序。


5. 风险与边界

Multi-Message Mode

  • 需要防止 moderator prompt marker 自己再次触发 turn logic
  • 需要明确 start/end marker 的匹配规则(全文包含、末尾匹配、独立一条指令等)
  • 需要明确 multi-message mode 下 human @mention 是否还有特殊行为
  • 需要避免与 discussion closed / waiting-for-human 冲突

Shuffle Mode

  • 两个 Agent 的洗牌约束需要单独处理
  • turn order 若正处于 mention override / waiting-for-human / dormant需要明确何时允许 reshuffle
  • 若 turn order 成员变化shuffle 与 bootstrap 的先后顺序要明确

6. 实现状态

Multi-Message Mode 与 Shuffle Mode 已经在代码中实现,包括:

  • Multi-Message Mode 实现:

    • plugin/core/channel-modes.ts - 管理 channel 运行时状态
    • plugin/hooks/message-received.ts - 检测 start/end marker 并切换模式
    • plugin/hooks/before-model-resolve.ts - 在 multi-message mode 中强制 no-reply
    • 配置项 multiMessageStartMarker (默认 ↗️)、multiMessageEndMarker (默认 ↙️)、multiMessagePromptMarker (默认 ⤵️)
    • plugin/openclaw.plugin.json 中添加了相应的配置 schema
  • Shuffle Mode 实现:

    • plugin/core/channel-modes.ts - 管理 shuffle 状态
    • plugin/turn-manager.ts - 在每轮结束后根据 shuffle 设置决定是否重洗牌
    • /dirigent turn-shuffling slash command 实现,支持 on/off/status 操作
    • 确保上一轮最后发言者不会在下一轮中成为第一位
    • 当前行为是运行时开关,默认关闭,不落盘

7. 验收清单

Multi-Message Mode 验收

  • 人类发送 start marker (↗️) 后进入 multi-message 模式
  • multi-message 模式中 Agent 被 no-reply 覆盖
  • 每条人类追加消息都触发 prompt marker (⤵️)
  • 人类发送 end marker (↙️) 后退出 multi-message 模式
  • 退出后 moderator 正确唤醒下一位 Agent
  • moderator prompt marker 不会触发回环
  • 与 waiting-for-human 模式兼容
  • 与 mention override 模式兼容

Shuffle Mode 验收

  • /dirigent turn-shuffling on/off 命令生效
  • shuffling 关闭时 turn order 保持不变
  • shuffling 开启时每轮结束后会重洗牌
  • 上一轮最后发言者不会在下一轮中成为第一位
  • 双 Agent 场景行为符合预期
  • 单 Agent 场景不会异常
  • 与 dormant 状态兼容
  • 与 mention override 兼容

配置项验收

  • multiMessageStartMarker 配置项生效
  • multiMessageEndMarker 配置项生效
  • multiMessagePromptMarker 配置项生效
  • 配置项在 plugin/openclaw.plugin.json 中正确声明

8. 结论

Multi-Message Mode 与 Shuffle Mode 已成功集成到 Dirigent 插件中,与现有的 turn-manager、moderator handoff、no-reply override 机制协同工作,为用户提供更灵活的多 Agent 协作控制能力。