584 lines
16 KiB
Markdown
584 lines
16 KiB
Markdown
# CSM 设计稿:基于 Discord 私密频道的 Agent 协作讨论与回调机制
|
||
|
||
## 1. 背景
|
||
|
||
在 Dirigent 的多 Agent 工作流中,某个正在执行任务的 Agent 可能在处理中途需要与其他 Agent 讨论某个问题,例如:
|
||
|
||
- 方案评审
|
||
- 权限模型确认
|
||
- 实现细节对齐
|
||
- 风险/边界条件讨论
|
||
|
||
当前缺少一种受控、可回收、可回灌原工作流的讨论机制。目标是让 Agent 能在需要时主动拉起一个临时私密讨论频道,与指定 Agent 交流,并在结束后把讨论成果注入回原始工作 Session 所在的 Discord channel。
|
||
|
||
本方案采用:
|
||
|
||
- 由发起讨论的 Agent 直接调用 `discord_channel_create`
|
||
- 为该工具新增两个可选参数,以标记“讨论模式”
|
||
- 由插件侧 moderator bot 用纯字符串拼接方式驱动讨论流程
|
||
- 由发起讨论的 Agent 在讨论结束时显式调用新增工具 `discuss-callback`
|
||
- 回调后关闭讨论 channel,并唤醒原工作 channel 继续处理
|
||
|
||
---
|
||
|
||
## 2. 目标
|
||
|
||
实现一种可控的 Agent 间讨论机制,满足以下要求:
|
||
|
||
1. Agent 能在工作过程中主动创建一个私密讨论 channel
|
||
2. 讨论 channel 能通过固定规则唤醒参与 Agent 开始讨论
|
||
3. 讨论结束时,结果必须以文件形式落地
|
||
4. 讨论结果能回传到原工作 channel
|
||
5. 讨论结束后,讨论 channel 不再继续处理任何 Agent 发言
|
||
6. moderator bot 不使用任何模型,所有发言均为固定模板/字符串拼接
|
||
7. 整个机制尽量复用现有插件中的 turn-manager 轮转发言能力
|
||
|
||
---
|
||
|
||
## 3. 非目标
|
||
|
||
以下内容不在本次 MVP 范围内:
|
||
|
||
- 不做基于模型的 moderator/coordinator 智能决策
|
||
- 不做自动总结(总结必须由发起讨论的 Agent 负责)
|
||
- 不做复杂投票/仲裁机制
|
||
- 不做多级讨论嵌套
|
||
- 不做跨 workspace 的结果存储
|
||
- 不做开放式 transcript 自动压缩和长期知识抽取
|
||
|
||
---
|
||
|
||
## 4. 核心思路
|
||
|
||
将“讨论”视为一种特殊模式的私密频道:
|
||
|
||
- 由工作中的 Agent 主动创建
|
||
- 创建时提供原工作 channel id(callback channel id)和讨论指引(discuss guide)
|
||
- 插件识别该频道为特殊讨论频道
|
||
- moderator bot 通过插件内部 `sendModeratorMessage(...)` 在频道中发布一条固定 kickoff message,说明:
|
||
- 讨论目的
|
||
- 应如何进行讨论
|
||
- 结束条件
|
||
- 发起讨论的 Agent 在结束时必须写总结文档并调用 `discuss-callback`
|
||
- 讨论期间复用现有 turn-manager 轮转发言机制驱动 Agent 发言
|
||
- 如果轮转一圈无人发言,则 moderator 提醒发起者执行 callback 收尾
|
||
- callback 成功后:
|
||
- 检查总结文档是否存在,且必须位于发起讨论 Agent 的 workspace 下
|
||
- 将讨论 channel 中对应 session 的 provider/model override 到 `noReplyProvider` / `noReplyModel`
|
||
- 讨论 channel 后续任何消息都不再参与讨论,仅由 moderator 回复“channel 已关闭,仅留档”
|
||
- moderator 在原工作 channel 发消息,给出讨论结果文档路径,唤醒原工作流
|
||
|
||
---
|
||
|
||
## 5. 工具设计
|
||
|
||
### 5.1 扩展 `discord_channel_create`
|
||
|
||
在现有 `discord_channel_create` 工具上新增两个可选参数:
|
||
|
||
- `callbackChannelId?: string`
|
||
- `discussGuide?: string`
|
||
|
||
#### 兼容性要求
|
||
|
||
如果未填写 `callbackChannelId`:
|
||
- 工具行为与当前完全一致
|
||
|
||
如果填写了 `callbackChannelId`:
|
||
- 则必须同时填写 `discussGuide`
|
||
- 插件将该 channel 标记为“讨论模式 channel”
|
||
|
||
#### 参数语义
|
||
|
||
##### `callbackChannelId`
|
||
表示原工作 Session 所在的 Discord channel id。
|
||
|
||
该参数用于在讨论结束时,将结果回传给原工作 channel。
|
||
|
||
##### `discussGuide`
|
||
字符串,描述:
|
||
|
||
- 需要讨论什么
|
||
- 讨论希望得到什么结论
|
||
- 讨论的边界与目标
|
||
- 可选的产出要求
|
||
|
||
例如:
|
||
|
||
```text
|
||
讨论私密协作 channel 的回调机制,需要明确:
|
||
1. `discord_channel_create` 扩展参数设计
|
||
2. discuss-callback 工具的行为
|
||
3. 讨论结束后的 session 收口方式
|
||
4. MVP 范围内的异常处理策略
|
||
```
|
||
|
||
---
|
||
|
||
### 5.2 新工具 `discuss-callback`
|
||
|
||
新增工具:`discuss-callback`
|
||
|
||
建议工具参数最小化为:
|
||
|
||
- `summaryPath: string`
|
||
|
||
#### 参数说明
|
||
|
||
##### `summaryPath`
|
||
讨论总结文档的路径。
|
||
|
||
要求:
|
||
- 文件必须存在
|
||
- 文件必须位于发起讨论 Agent 的 workspace 下
|
||
- 不允许引用 workspace 外路径
|
||
|
||
#### 不建议暴露的参数
|
||
|
||
以下参数不应由 Agent 自己传入:
|
||
|
||
- 原工作 channel id
|
||
- discussion channel id
|
||
- 发起者身份
|
||
|
||
这些信息应由插件根据当前 channel 上下文和已记录 metadata 自动推导,避免伪造和串错。
|
||
|
||
---
|
||
|
||
## 6. 讨论模式 Channel 的元数据
|
||
|
||
当 `discord_channel_create` 以讨论模式创建 channel 时,插件需要记录对应 metadata。
|
||
|
||
建议结构如下:
|
||
|
||
```json
|
||
{
|
||
"mode": "discussion",
|
||
"discussionChannelId": "C_DISCUSS_001",
|
||
"originChannelId": "C_WORK_001",
|
||
"initiatorAgentId": "agent_planner",
|
||
"initiatorSessionId": "sess_123",
|
||
"discussGuide": "讨论如何设计 callback 机制并确定 MVP 行为",
|
||
"status": "active",
|
||
"createdAt": "2026-03-30T18:00:00Z",
|
||
"summaryPath": null
|
||
}
|
||
```
|
||
|
||
### 必需字段说明
|
||
|
||
- `mode`: 固定为 `discussion`
|
||
- `discussionChannelId`: 当前讨论 channel id
|
||
- `originChannelId`: 原工作 channel id
|
||
- `initiatorAgentId`: 发起讨论的 Agent 标识
|
||
- `initiatorSessionId`: 发起讨论对应的 session 标识
|
||
- `discussGuide`: 讨论说明
|
||
- `status`: 生命周期状态
|
||
- `createdAt`: 创建时间
|
||
- `summaryPath`: 结束后回写的总结文档路径
|
||
|
||
### 生命周期状态建议
|
||
|
||
- `active`:讨论进行中
|
||
- `completed`:已成功 callback,已完成
|
||
- `closed`:已关闭,仅作留档
|
||
|
||
对于 MVP,也可以将 `completed` 直接视为 `closed` 前的瞬时态,只要实现上清晰即可。
|
||
|
||
---
|
||
|
||
## 7. moderator bot 行为设计
|
||
|
||
moderator bot 的工作流完全不使用模型,所有输出均由模板字符串拼接生成。
|
||
|
||
### 7.1 讨论启动时发言
|
||
|
||
当检测到某 channel 为讨论模式 channel 时,moderator bot 自动发 kickoff message。
|
||
|
||
建议内容结构如下:
|
||
|
||
```text
|
||
[Discussion Started]
|
||
|
||
This channel was created for a temporary agent discussion.
|
||
|
||
Goal:
|
||
{discussGuide}
|
||
|
||
Instructions:
|
||
1. Discuss only the topic above.
|
||
2. Work toward a concrete conclusion.
|
||
3. When the initiator decides the goal has been achieved, the initiator must:
|
||
- write a summary document to a file
|
||
- call the tool: discuss-callback
|
||
- provide the summary document path
|
||
|
||
Completion rule:
|
||
Only the discussion initiator may finish this discussion.
|
||
|
||
After callback:
|
||
- this channel will be closed
|
||
- further discussion messages will be ignored
|
||
- this channel will remain only for archive/reference
|
||
- the original work channel will be notified with the summary file path
|
||
```
|
||
|
||
结尾必须明确表达以下语义:
|
||
|
||
- 讨论结束由发起讨论的 Agent 判定
|
||
- 发起者结束时必须写入总结文档
|
||
- 发起者必须调用 `discuss-callback`
|
||
- callback 成功后,原工作 channel 会被通知结果文档路径
|
||
|
||
---
|
||
|
||
### 7.2 空转提醒机制
|
||
|
||
插件当前已有基于 turn-manager 的轮转发言机制。
|
||
|
||
现有逻辑:
|
||
- 发言列表轮转一圈,如果没有人发言且所有人均回复 `NO_REPLY`,则认为 channel 休眠
|
||
|
||
本方案对“特殊讨论 channel”修改为:
|
||
|
||
#### 新逻辑
|
||
在讨论模式 channel 中:
|
||
- 若发言列表轮转一圈,无人发言
|
||
- 则 moderator 不直接判定流程结束
|
||
- 改为提醒发起讨论的 Agent:
|
||
- 若讨论目标已经达成,请写总结文档
|
||
- 然后调用 `discuss-callback` 结束讨论
|
||
|
||
建议提醒消息模板:
|
||
|
||
```text
|
||
[Discussion Idle]
|
||
|
||
No agent responded in the latest discussion round.
|
||
If the discussion goal has been achieved, the initiator should now:
|
||
1. write the discussion summary to a file in the workspace
|
||
2. call discuss-callback with the summary file path
|
||
|
||
If more discussion is still needed, continue the discussion in this channel.
|
||
```
|
||
|
||
这样可以避免讨论悄无声息悬空,同时不引入自动总结逻辑。
|
||
|
||
---
|
||
|
||
### 7.3 讨论结束后的行为
|
||
|
||
在 `discuss-callback` 成功后:
|
||
|
||
1. 讨论 channel 标记为关闭/完成
|
||
2. 讨论 channel 中所有相关 session 的 provider/model override 到 `noReplyProvider` / `noReplyModel`
|
||
3. 后续任何在该 channel 中的发言均不再触发实际讨论流程
|
||
4. 如果讨论结束后仍有人发言,由 moderator 统一回复:
|
||
- `channel 已关闭,channel 仅做留档使用`
|
||
|
||
建议模板:
|
||
|
||
```text
|
||
[Channel Closed]
|
||
|
||
This discussion channel has been closed.
|
||
It is now kept for archive/reference only.
|
||
Further discussion in this channel is ignored.
|
||
```
|
||
|
||
这部分实现明确采用已有“在指定 session 上临时覆盖为 no-reply 模型”的方式,而不是修改 Agent 的全局默认模型。
|
||
|
||
---
|
||
|
||
## 8. `discuss-callback` 工具行为细节
|
||
|
||
### 8.1 调用前提
|
||
|
||
仅允许在讨论模式 channel 中调用。
|
||
|
||
### 8.2 调用权限
|
||
|
||
只有发起讨论的 Agent 对应 session 可以成功调用。
|
||
|
||
其他参与 Agent 调用时应被拒绝。
|
||
|
||
### 8.3 调用流程
|
||
|
||
`discuss-callback(summaryPath)` 执行时,插件执行如下步骤:
|
||
|
||
1. 从当前调用上下文获取 discussion channel id
|
||
2. 查询该 channel 的 discussion metadata
|
||
3. 校验该 channel 是否为讨论模式 channel
|
||
4. 校验调用者是否为 initiator session / initiator agent
|
||
5. 校验 `summaryPath` 对应文件是否存在
|
||
6. 校验文件路径是否位于发起讨论 Agent 的 workspace 下
|
||
7. 更新 metadata:
|
||
- `summaryPath = ...`
|
||
- `status = completed` 或 `closed`
|
||
- `completedAt = now`
|
||
8. 将该 discussion channel 中相关 session 的模型覆盖为 `NO_REPLY`
|
||
9. 在原工作 channel 中由 moderator bot 发消息,给出结果文档路径
|
||
10. 讨论 channel 后续进入只留档、不再参与讨论的状态
|
||
|
||
---
|
||
|
||
## 9. 原工作 Channel 的唤醒机制
|
||
|
||
`discuss-callback` 成功后,moderator bot 需要在原工作 channel 发一条固定格式消息。
|
||
|
||
目的:
|
||
- 向原工作 Session 明确传达“讨论结束”
|
||
- 提供结果文档路径
|
||
- 用新消息唤醒原工作 channel 上的 Agent 继续执行
|
||
|
||
建议模板:
|
||
|
||
```text
|
||
[Discussion Result Ready]
|
||
|
||
A temporary discussion has completed.
|
||
|
||
Summary file:
|
||
{summaryPath}
|
||
|
||
Source discussion channel:
|
||
<#discussionChannelId>
|
||
|
||
Status:
|
||
completed
|
||
|
||
Continue the original task using the summary file above.
|
||
```
|
||
|
||
### 注意事项
|
||
|
||
这里的“唤醒”不依赖额外模型调度逻辑,而是依赖:
|
||
- moderator bot 在原 channel 发布一条新消息
|
||
- 原工作 channel 正常接收到新消息事件
|
||
- 原工作 Session 被自然触发继续处理
|
||
|
||
---
|
||
|
||
## 10. 安全与边界条件
|
||
|
||
### 10.1 `summaryPath` 伪造
|
||
|
||
必须防止 Agent 传入伪造路径。
|
||
|
||
#### 强制校验
|
||
插件必须检查:
|
||
|
||
1. 文件是否存在
|
||
2. 文件路径是否位于发起讨论 Agent 的 workspace 下
|
||
3. 不允许使用 workspace 之外的路径
|
||
|
||
这是本方案的硬约束。
|
||
|
||
---
|
||
|
||
### 10.2 discussion channel 未正常结束
|
||
|
||
由于讨论结束依赖发起者显式 callback,可能出现讨论完成但发起者未执行 callback 的情况。
|
||
|
||
#### MVP 策略
|
||
- 不做自动总结
|
||
- 复用顺序讨论机制检测“轮转一圈无人发言”
|
||
- 由 moderator bot 提醒发起者收尾
|
||
|
||
这已经足够形成最低可用闭环。
|
||
|
||
后续增强可再考虑:
|
||
- 超时提醒
|
||
- stale discussion 清理
|
||
- 管理员强制关闭
|
||
|
||
---
|
||
|
||
### 10.3 结束后继续发言
|
||
|
||
这是明确禁止的。
|
||
|
||
在讨论完成后:
|
||
|
||
- 任何会话都不应继续在该 channel 中讨论
|
||
- 相关 session 继续使用 `NO_REPLY` 模型覆盖
|
||
- channel 仅保留为留档用途
|
||
- 后续发言统一由 moderator bot 回复 channel 已关闭
|
||
|
||
这条约束需要严格执行,避免旧讨论“诈尸”。
|
||
|
||
---
|
||
|
||
### 10.4 状态重复提交
|
||
|
||
若 `discuss-callback` 被重复调用,应拒绝处理。
|
||
|
||
建议规则:
|
||
- 仅允许 `active -> completed/closed` 一次转换
|
||
- 若 channel 已完成或已关闭,则后续 callback 一律失败
|
||
|
||
---
|
||
|
||
## 11. 推荐状态机
|
||
|
||
```text
|
||
普通 channel
|
||
└── 不受本方案影响
|
||
|
||
讨论 channel
|
||
created
|
||
-> active
|
||
-> idle-reminded (可选显示态)
|
||
-> completed
|
||
-> closed
|
||
```
|
||
|
||
### 状态说明
|
||
|
||
- `created`:channel 已创建但 kickoff 尚未发完
|
||
- `active`:讨论进行中
|
||
- `idle-reminded`:轮转一圈无人发言,moderator 已提醒收尾(实现上可不单独持久化)
|
||
- `completed`:callback 已成功
|
||
- `closed`:channel 已关闭,仅保留留档
|
||
|
||
MVP 中也可简化为:
|
||
|
||
- `active`
|
||
- `closed`
|
||
|
||
只要逻辑上能区分 callback 前后即可。
|
||
|
||
---
|
||
|
||
## 12. 典型流程示例
|
||
|
||
### 12.1 发起讨论
|
||
原工作 channel 中,某 Agent 发现需要和其他 Agent 对齐方案。
|
||
|
||
Agent 调用:
|
||
|
||
```json
|
||
{
|
||
"callbackChannelId": "origin-channel-123",
|
||
"discussGuide": "讨论私密协作 channel 的结束与回调机制,需要产出一份总结说明工具参数、结束条件和异常处理策略。"
|
||
}
|
||
```
|
||
|
||
插件创建私密讨论 channel,并记录 metadata。
|
||
|
||
moderator bot 在新 channel 中发布 kickoff message。
|
||
|
||
---
|
||
|
||
### 12.2 展开讨论
|
||
参与 Agent 在该 channel 中按现有顺序讨论机制发言。
|
||
|
||
如果轮转一圈无人发言,则 moderator 提醒发起者:
|
||
- 若已达成目标,请写总结文档并 callback
|
||
|
||
---
|
||
|
||
### 12.3 结束讨论
|
||
发起讨论 Agent 在自己的 workspace 下写出总结文档,例如:
|
||
|
||
```text
|
||
plans/discussions/csm-discussion-summary.md
|
||
```
|
||
|
||
随后调用:
|
||
|
||
```json
|
||
{
|
||
"summaryPath": "plans/discussions/csm-discussion-summary.md"
|
||
}
|
||
```
|
||
|
||
插件校验通过后:
|
||
- 标记讨论完成
|
||
- 覆盖讨论 channel 中相关 session 的模型为 `NO_REPLY`
|
||
- 在原工作 channel 发 moderator message
|
||
|
||
---
|
||
|
||
### 12.4 原工作流继续
|
||
原工作 channel 收到 moderator 的结果通知:
|
||
|
||
- 结果文档路径
|
||
- 来源 discussion channel
|
||
- 状态 completed
|
||
|
||
原工作 Session 读取该总结文档,并继续原任务。
|
||
|
||
---
|
||
|
||
## 13. MVP 实施建议
|
||
|
||
建议按以下顺序实现:
|
||
|
||
### 第一步:扩展建频道工具
|
||
- 为 `create private channel` 增加 `callbackChannelId` 和 `discussGuide`
|
||
- 实现参数联动校验
|
||
- 讨论模式下写入 metadata
|
||
|
||
### 第二步:moderator kickoff
|
||
- 讨论模式 channel 创建后自动发固定模板消息
|
||
- 内容包含 callback 操作说明
|
||
|
||
### 第三步:接入空转提醒
|
||
- 复用现有 turn-manager 轮转逻辑
|
||
- 在讨论模式 channel 中改为空转提醒发起者 callback
|
||
|
||
### 第四步:实现 `discuss-callback`
|
||
- 当前 channel 识别
|
||
- initiator 身份校验
|
||
- `summaryPath` 文件存在校验
|
||
- workspace 范围校验
|
||
- metadata 更新
|
||
|
||
### 第五步:完成关闭逻辑
|
||
- 指定 session 的 provider/model override 到 `noReplyProvider` / `noReplyModel`
|
||
- 结束后任何发言统一由 moderator 回复 channel 已关闭
|
||
|
||
### 第六步:原 channel 唤醒
|
||
- moderator 在 origin channel 发布结果消息
|
||
- 确保原工作 Session 被自然唤醒
|
||
|
||
---
|
||
|
||
## 14. 后续可扩展方向
|
||
|
||
在 MVP 跑通后,可考虑增加以下能力:
|
||
|
||
- 讨论超时自动提醒
|
||
- 管理员强制 callback / 强制关闭
|
||
- 讨论文档路径规范化
|
||
- 对总结文档结构给出模板约束
|
||
- discussion 状态查询工具
|
||
- 讨论留档索引
|
||
- callback 成功后自动附带摘要预览
|
||
|
||
但这些都应放在 MVP 验证后再做。
|
||
|
||
---
|
||
|
||
## 15. 结论
|
||
|
||
本方案将 Agent 间讨论能力实现为一种“特殊模式的私密 Discord channel”,通过:
|
||
|
||
- 扩展 `discord_channel_create`
|
||
- 新增 `discuss-callback`
|
||
- 复用现有 turn-manager 轮转发言机制
|
||
- 使用纯规则驱动的 moderator bot
|
||
- 在指定 session 上临时应用 `noReplyProvider` / `noReplyModel` 覆盖
|
||
|
||
形成一个完整闭环:
|
||
|
||
1. 原工作 Agent 发起讨论
|
||
2. 私密讨论 channel 被创建并自动启动讨论
|
||
3. 讨论结果写入发起者 workspace 中的文件
|
||
4. 发起者显式 callback 结束讨论
|
||
5. 插件关闭讨论 channel 的交互能力
|
||
6. moderator 将结果路径回传到原工作 channel
|
||
7. 原工作 Session 被唤醒并继续执行
|
||
|
||
这是一个实现成本可控、行为稳定、边界清晰、适合 MVP 落地的方案。 |