Skip to content

feat(minimax-bot): 群接力的跳数上限与摘要交接(默认关闭) - #68

Open
Apageoflove wants to merge 1 commit into
MiniMax-AI:mainfrom
Apageoflove:feat/minimax-bot-relay-guard
Open

Apageoflove wants to merge 1 commit into
MiniMax-AI:mainfrom
Apageoflove:feat/minimax-bot-relay-guard

Conversation

@Apageoflove

@Apageoflove Apageoflove commented Oct 23, 2026 •

Copy link
Copy Markdown

给群接力加两道护栏,都是群自己的字段,默认都是关的:maxHops 填 0 表示不限,和现在完全一样;handover 默认 false。

跳数上限说的是一条消息引发的接力链最多几个 Bot 说话。到上限时不再 @ 别人,群里给一条系统提示(已达接力上限(N 跳),本轮讨论在此收口),并让刚说话的那个 Bot 收个口。这个收口是一个模型回合,替代被拦下的那一跳,不是额外多一轮。

摘要交接是把上一位的结论放进下一位的提示词里,做法是把上一位回复的尾部带过去。下一位因此不用再翻一遍工具重新挖同一件事。它只是提示词里的一段文本,不额外起模型回合、不额外调工具、不写记忆。

这两个设置是面板专属的:我在群设置里填,MCP 的 update_group 里没有这两个参数,模型即使硬塞也不生效。理由是上限属于成本与安全的设定,不该由正在接力的那一方自己决定要不要继续接。相应地,模型能看到的工具目录与 list_team 的返回,跟改之前逐字节相同。

为什么做这个:官方 README 自己写着 There is no fixed reply cap。我在 mcode 里对官方版跑了一套 8 步对照,第 4 步只是群里 @ 了一个成员问标题怎么起,结果一轮接力跑了 4 跳(考据→执笔→考据→执笔)、313 秒、6 次工具调用,最后也没落到一个能用的标题上。

测过什么:上游 0.7.8 自己的 216 条测试,214 过。另外 2 条(头像库的并发上传、写入失败后重试)在我这台机器上单独跑通过、全量跑失败,上游原版全量跑也是同样这 2 条,所以不是这次改动带来的。我给这个功能补了 15 个测试用例:上限填 0 等于不限,写坏的值读作不限而不是把群静音,护栏关着时群里的常驻简报与官方版逐字一致(整段群提示词我也逐段比对过,同样一致),maxHops=2 时四跳链只跳两跳并收口,收口那一回合自己失败时链路照样停在两跳、通知仍在,模型改不了这两个设置。

边界:宿主 permissionMode 是 bypassPermissions,工具权限的执行门一次都不会触发,这套护栏是行为约束,不是安全边界。我只核了上游 0.7.8 的代码,其他版本未验证。默认跳数给多少、收口时要不要在群里明说,这是我仅个人判断、不是结论,需要确认——我在 issue #66 问过。实跑环境:zcode 里的 m3.1 flash 迭代代码,在 mcode 里对着官方 bot 和自己改的 bot-lab 做 8 步对照,机器是 linux-ubuntu-24.04。


View with [code]smith Autofix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

@MyPrototypeWhat MyPrototypeWhat left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

感谢这个 PR。两道护栏默认关闭、只放在面板里,relay-guard.mjs 写成纯函数,测试也补齐了。我在本地拉了 711fa19 跑了一遍,下面是几点意见。

需要修改

1. 护栏关闭时,英文界面下的群常驻简报不再逐字一致

我实际生成了护栏全关时的群常驻简报,拿 711fa19 和 main(0.7.8)的输出逐字节比较:英文下多了一个空格(main 是 "...from a private chat.\n\n## Team",这个 PR 是 "...from a private chat. \n\n## Team"),中文一致。原因在 plugins/minimax-ai/minimax-bot/miniapp/node/engine.mjs:381:数组末尾总会追加 relayGuard ? t('brief.groupOneOwner') : '',然后整体 join(t('brief.sentenceJoin'))。中文的 brief.sentenceJoin 是空串(strings.mjs:245),英文是一个空格(strings.mjs:554),所以护栏关闭时英文末尾会多一个空格。这和 PR 描述里"护栏关着时与官方版逐字一致"的说法不符,已有会话升级后也会看到简报变化。群提示词(groupPrompt)本身中英文都一致。

建议只在需要时才把这一句放进数组,例如:

[
  t('brief.groupNoPost'),
  ...(relayGuard ? [t('brief.groupOneOwner')] : []),
].join(t('brief.sentenceJoin'))

另外,tests/relay-guard.test.mjs:169 那条"逐字一致"的测试比较的是同一份新代码在开/关两种状态下的输出,所以没能发现这个问题。建议补一个断言:护栏关闭时简报不以空格结尾(或者直接和一份 0.7.8 的基准字符串比较),中英文各测一次。

可选建议

  • 收口回合实际是第 N+1 回合,而且没带 taskId:描述和 README.md:36 说收口"替代被拦下的那一跳,不是额外多一轮"。但看实现,到上限时被拦下的那一跳并没有执行(engine.mjs:1177、engine.mjs:1217),而 convergeGroup 会让最后发言的 Bot 再跑一次模型回合(engine.mjs:341),所以一轮实际跑 limit+1 次模型回合;README.md:105 写的 "spends one extra Agent turn" 反而更贴近实现。另外,链里其他回合都会传 taskId: options.taskId(engine.mjs:1190),收口回合的调用(engine.mjs:341,参数从 engine.mjs:1230 传入)没有带 taskId,由任务派发进来的群接力,收口这一回合就不会挂在原任务下。建议把描述/README 统一成一种说法,并给收口回合也带上 taskId。
  • 服务端没有上限:面板 panels.js 里的输入框写了 max: 20,但 relay-guard.mjs:58 的 hopLimit 只处理了下限,通过 HTTP 接口直接 PATCH 一个很大的数也会被接受。可以在 hopLimit 里也夹一下上限,和面板保持一致。
  • replyMode 为 all 时的行为:engine.mjs:1177 的检查在队列里还有人时就会收口。"所有人回复"模式下初始队列本身就有多个成员,这时上限会截掉后面的成员,并让最后一个发言的成员做收口。如果这是有意为之,在面板提示或 README 里提一句会比较清楚;如果不是,可以只统计由 @ 交接产生的跳数。
  • 交接内容可能重复:上一位的回复本身已经出现在下一位提示词的"新消息"里(groupPrompt 会列出来),交接块又把它的尾部带了一遍。这不影响正确性,只是在描述里说明一下交接块的定位(强调结论),能帮使用者判断要不要打开它。
  • 版本号:这个 PR 把版本升到 0.7.9,#56 目前也是 0.7.9。两者谁后合入,谁就需要再升一个版本(plugin.json、package.json、mcp.mjs 里的 serverInfo 以及 README 的版本小节),这里先提个醒。

我这边核对过的

  • 改动只在插件目录内,没有读写 dataDir 以外的东西,没有新增文件读写或网络调用。
  • 模型这一侧改不了这两个设置:MCP 的 create_group / update_group 都没有新增参数(mcp.mjs 里的 schema 和参数转发都没变),list_team 返回的字段也没变,硬塞 max_hops / handover 不会生效,测试里也覆盖到了。面板走的 HTTP PATCH /api/groups/:id(server.mjs:615)会把请求体原样交给 updateGroup,和其他群字段一样,这是面板自己的写入路径。
  • 护栏关闭时 groupPrompt 不加任何内容,接力循环的行为和之前一致(limit 为 0 时两处新判断都不会触发)。
  • 新测试放在插件自己的 tests/ 里,仓库根目录 test/ 没有改动。
  • 本地结果(Node 22):先在插件的 tests/ 里执行 npm ci,再跑 node --test tests/*.test.mjs,231/231 通过;不装依赖时会有 7 个 UI/jsdom 相关的测试文件失败,main 上也是同样这 7 个。仓库根目录 npm run check 通过 validate,69 条测试全部通过。

主要就是第 1 点,改完我再看一眼。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants