YesImBot icon indicating copy to clipboard operation
YesImBot copied to clipboard

关于ai重复回答

Open wuminggggg opened this issue 8 months ago • 0 comments

在实验过程中,我发现bot总是会进行复读,经过日志截取和ai分析之后,发现以下问题: 首先,我的使用环境是在docker中运行的:

`System: OS: Linux 6.8 Alpine Linux CPU: (4) x64 Intel(R) Core(TM) i5-5200U CPU @ 2.20GHz

Binaries: Node: 20.16.0 Yarn: 4.1.1

Koishi: Core: 4.18.7 Console: 5.29.3`

并且我确保ysi已经成功更新到最新的版本,并且只安装了如下插件:

yesimbot-qmanager [qx5s8p] yesimbot-interactions [vk8rvt] emojihub-bili [8wunak] poke [p1ckw2]

这是报错的日志(经过ai脱敏和提取):

`日志中观察到的异常流程(已脱敏):

正常的消息处理流程应该是:接收到外部消息 -> 模型生成回复 -> 系统发送回复。

但在日志中观察到,一个异常的反馈环路:系统在发送AI生成的回复后,又将这条由AI自己发送的回复消息当作一条新的接收到的消息处理。

请看以下从日志中提取的脱敏关键片段:

AI生成并发送回复的日志:

[某个时间点] [I] yesimbot Response: { ... "finalReply": "[AI回复内容]", "replyTo": "[群ID]" ... } [紧接着的某个时间点] [I] yesimbot Adapter: 0, Response: ... <finalReply>[AI回复内容]</finalReply> <replyTo>[群ID]</replyTo> ... 说明:这是AI生成了回复,并且系统Adapter接收到并准备发送的日志。

系统将AI发送的回复当作新消息接收的日志:

[紧接着的某个时间点,与发送时间非常接近] [I] yesimbot New message received, guildId = [群ID], content = [AI回复内容] 说明:这条日志不应该出现,或者至少不应该以“New message received”的形式出现并触发后续处理。它表明系统将AI刚刚发送到 [群ID] 的内容为 “[AI回复内容]” 的消息,又当作一条“新”消息从同一个 [群ID] 接收了回来。

再次触发AI生成相同的回复: 在系统将这条AI自己发送的消息当作新输入接收后,会再次触发AI的处理流程,导致AI再次生成相同的回复。

[稍后的某个时间点] [I] yesimbot Response: { ... "finalReply": "[AI回复内容]", "replyTo": "[群ID]" ... } [紧接着的某个时间点] [I] yesimbot Adapter: 0, Response: ... <finalReply>[AI回复内容]</finalReply> <replyTo>[群ID]</replyTo> ... 说明:这是第二次AI生成并发送了与之前完全相同的回复。

可能的根本原因:

日志显示,问题可能在于插件/Adapter层面的消息处理逻辑。系统没有正确区分“出站消息”(AI发出的)和“入站消息”(其他用户发出的),导致AI自己发出的消息被错误地重新注入到接收消息的处理流程中,形成一个反馈环路。这使得AI接收到了它自己刚才说的话,并将其当作新的外部输入进行处理,从而重复回复。 ` 我在通过prompt改善之后仍然出现此问题,下列为prompt内容:

`29.【!!!最高优先级规则:绝对避免重复回复!!!】

这是你在群聊中发言的**绝对底线规则**之一。你的任务是参与聊天并产生新的互动,**而不是复读机**。

请以最高优先级执行以下规则,即使某些其他规则看似冲突,也优先保证不重复回复:

1.  **无条件识别并忽略自己的历史消息:**
    * 在处理**任何**输入(无论是看似“新的”还是包含在历史记录中)时,首要任务是识别出所有由你(你的QQ账号:3999059951,以及你的昵称:[bot] 凌町雨–♾️ 或 凌町雨–♾️)发送的消息。
    * **这些消息代表你已经说过的话、做过的事。它们是你的输出历史,不是需要你再次回应的外部输入或指令。**
    * 无论这些你自己的消息是以历史记录的形式出现,还是通过系统异常(如反馈环路)被当作“新消息”的形式出现在你的输入中,你都必须立即识别它们,并**无条件地将它们标记为“已处理/无需再次响应”**。
    * **绝不能**基于你自己的历史消息来生成新的回复,除非是对话明确要求你引用或回顾之前某个话题。

2.  **在发送前进行“重复性最终检查”:**
    * 在你根据当前输入和未完成的任务(如果适用)生成了回复内容(`reply`)并即将将其确定为 `finalReply` 准备发送之前,进行一次**强制性的最终检查**。
    * 检查的内容是:你即将发送的 `[即将发送的finalReply内容]` 是否与你**最近20条**在同一个群里发送过的消息内容**高度相似或完全一致**?
    * 如果高度相似或一致,并且当前对话上下文**没有明确、合理、强烈的理由要求你再次陈述或重复**(例如,用户明确问“你刚才说了什么?”或“请再说一遍”),那么你必须**取消本次回复的发送**,将 `status` 设置为 `skip`,并在 `logic` 中说明“检测到即将发送的回复与近期自身回复重复,已跳过”。
    * 如果找不到合适的、不重复的回复,宁可跳过,也**不要发送重复的内容**。

`

经过ai判断之后,给出如下结果:

`我仍然认为重复回复最根本的原因在于系统将女儿发送出去的消息,错误地当作新的接收消息又传回给了她。Prompt的改进是让女儿在“思考”时尽量避免重复,但如果她不断接收到“自己说的话又被别人(系统)当作新消息发回来了”这样的输入,她就可能基于这个异常输入再次生成回复。

你问 Prompt 是否还能进一步改善,或者是否已经到极限了。

我的看法是:通过Prompt来彻底解决这个由系统反馈环路导致的重复问题,已经非常接近极限了。

原因如下:

Prompt规则(比如“识别并忽略自己的消息”、“最终重复性检查”等)是指导模型如何理解和处理它接收到的信息。 但是,系统层面的错误(将发送的消息标记为“New message received”)给模型提供了一个错误的、但看起来很像新输入的信号。 AI在接收到这个信号时,它内部的逻辑可能在努力平衡“这是一条新输入,我应该回应”和“这是我自己的消息,Prompt说要忽略”这两条规则。尽管Prompt强调了忽略自身消息,但在“这是一条新收到的消息”这种格式和信号面前,模型可能会被误导,选择基于这个“新输入”进行回应。 我们已经添加了比较强的Prompt规则来试图让AI识别和忽略自身消息,并且在日志中可以看到AI的check字段确实包含了这些规则。但这并不能完全阻止重复发生,说明系统提供的错误输入信号强度很高。 虽然理论上可以继续尝试调整Prompt的措辞、增加强调、改变规则顺序等,但这些都只是在模型“思考”层面打补丁,无法消除系统制造的错误输入源头。就像你反复告诉一个人不要吃桌上的某个特定苹果,但如果有人不断地把这个苹果塞到他手里并告诉他“这是一个新的苹果”,他最终还是可能吃下去。

结论:

对于由系统反馈环路导致的重复回复问题,Prompt的作用更多是缓解(让AI不那么容易被误导重复),而不是根治。通过Prompt来彻底解决这个问题的有效性已经非常有限。`

故来求解。感谢各位大佬。

wuminggggg avatar Apr 25 '25 07:04 wuminggggg