From 3b5ca21f40972d0f9db015f960a3e8b350fd7384 Mon Sep 17 00:00:00 2001 From: nav Date: Mon, 30 Mar 2026 18:14:58 +0000 Subject: [PATCH] docs: add CSM discussion callback design --- plans/CSM.md | 584 +++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 584 insertions(+) create mode 100644 plans/CSM.md diff --git a/plans/CSM.md b/plans/CSM.md new file mode 100644 index 0000000..fd6e80e --- /dev/null +++ b/plans/CSM.md @@ -0,0 +1,584 @@ +# CSM 设计稿:基于 Discord 私密频道的 Agent 协作讨论与回调机制 + +## 1. 背景 + +在 Dirigent 的多 Agent 工作流中,某个正在执行任务的 Agent 可能在处理中途需要与其他 Agent 讨论某个问题,例如: + +- 方案评审 +- 权限模型确认 +- 实现细节对齐 +- 风险/边界条件讨论 + +当前缺少一种受控、可回收、可回灌原工作流的讨论机制。目标是让 Agent 能在需要时主动拉起一个临时私密讨论频道,与指定 Agent 交流,并在结束后把讨论成果注入回原始工作 Session 所在的 Discord channel。 + +本方案采用: + +- 由发起讨论的 Agent 直接调用 `create private channel` +- 为该工具新增两个可选参数,以标记“讨论模式” +- 由插件侧 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. 整个机制尽量复用现有插件顺序讨论能力 + +--- + +## 3. 非目标 + +以下内容不在本次 MVP 范围内: + +- 不做基于模型的 moderator/coordinator 智能决策 +- 不做自动总结(总结必须由发起讨论的 Agent 负责) +- 不做复杂投票/仲裁机制 +- 不做多级讨论嵌套 +- 不做跨 workspace 的结果存储 +- 不做开放式 transcript 自动压缩和长期知识抽取 + +--- + +## 4. 核心思路 + +将“讨论”视为一种特殊模式的私密频道: + +- 由工作中的 Agent 主动创建 +- 创建时提供原工作 channel id(callback channel id)和讨论指引(discuss guide) +- 插件识别该频道为特殊讨论频道 +- moderator bot 在频道中发布一条固定 kickoff message,说明: + - 讨论目的 + - 应如何进行讨论 + - 结束条件 + - 发起讨论的 Agent 在结束时必须写总结文档并调用 `discuss-callback` +- 讨论期间复用现有“顺序讨论”机制驱动 Agent 发言 +- 如果轮转一圈无人发言,则 moderator 提醒发起者执行 callback 收尾 +- callback 成功后: + - 检查总结文档是否存在,且必须位于发起讨论 Agent 的 workspace 下 + - 将讨论 channel 中对应 session 的模型覆盖为 `NO_REPLY` + - 讨论 channel 后续任何消息都不再参与讨论,仅由 moderator 回复“channel 已关闭,仅留档” + - moderator 在原工作 channel 发消息,给出讨论结果文档路径,唤醒原工作流 + +--- + +## 5. 工具设计 + +### 5.1 扩展 `create private channel` + +在现有 `create private channel` 工具上新增两个可选参数: + +- `callbackChannelId?: string` +- `discussGuide?: string` + +#### 兼容性要求 + +如果未填写 `callbackChannelId`: +- 工具行为与当前完全一致 + +如果填写了 `callbackChannelId`: +- 则必须同时填写 `discussGuide` +- 插件将该 channel 标记为“讨论模式 channel” + +#### 参数语义 + +##### `callbackChannelId` +表示原工作 Session 所在的 Discord channel id。 + +该参数用于在讨论结束时,将结果回传给原工作 channel。 + +##### `discussGuide` +字符串,描述: + +- 需要讨论什么 +- 讨论希望得到什么结论 +- 讨论的边界与目标 +- 可选的产出要求 + +例如: + +```text +讨论私密协作 channel 的回调机制,需要明确: +1. create private channel 扩展参数设计 +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 的元数据 + +当 `create private channel` 以讨论模式创建 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 空转提醒机制 + +插件当前已有顺序讨论机制。 + +现有逻辑: +- 发言列表轮转一圈,如果没有人发言且所有人均回复 `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 的模型覆盖为 `NO_REPLY` +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 操作说明 + +### 第三步:接入空转提醒 +- 复用现有顺序讨论逻辑 +- 在讨论模式 channel 中改为空转提醒发起者 callback + +### 第四步:实现 `discuss-callback` +- 当前 channel 识别 +- initiator 身份校验 +- `summaryPath` 文件存在校验 +- workspace 范围校验 +- metadata 更新 + +### 第五步:完成关闭逻辑 +- 指定 session 模型覆盖为 `NO_REPLY` +- 结束后任何发言统一由 moderator 回复 channel 已关闭 + +### 第六步:原 channel 唤醒 +- moderator 在 origin channel 发布结果消息 +- 确保原工作 Session 被自然唤醒 + +--- + +## 14. 后续可扩展方向 + +在 MVP 跑通后,可考虑增加以下能力: + +- 讨论超时自动提醒 +- 管理员强制 callback / 强制关闭 +- 讨论文档路径规范化 +- 对总结文档结构给出模板约束 +- discussion 状态查询工具 +- 讨论留档索引 +- callback 成功后自动附带摘要预览 + +但这些都应放在 MVP 验证后再做。 + +--- + +## 15. 结论 + +本方案将 Agent 间讨论能力实现为一种“特殊模式的私密 Discord channel”,通过: + +- 扩展 `create private channel` +- 新增 `discuss-callback` +- 复用现有顺序讨论机制 +- 使用纯规则驱动的 moderator bot +- 在指定 session 上临时覆盖 `NO_REPLY` 模型 + +形成一个完整闭环: + +1. 原工作 Agent 发起讨论 +2. 私密讨论 channel 被创建并自动启动讨论 +3. 讨论结果写入发起者 workspace 中的文件 +4. 发起者显式 callback 结束讨论 +5. 插件关闭讨论 channel 的交互能力 +6. moderator 将结果路径回传到原工作 channel +7. 原工作 Session 被唤醒并继续执行 + +这是一个实现成本可控、行为稳定、边界清晰、适合 MVP 落地的方案。 \ No newline at end of file