Open DanLCJ opened 1 year ago
目前的设计方案是每个人格的记忆内容(聊天记录和摘要)相互独立,并且对于每个会话(即每个群组或者私聊)相互独立; 但是对于每个用户的印象(根据用户唯一id辨识)是单独记忆的 即在以下场景中: 用户A在群组A中发送一条消息,bot的回复参考信息有:bot的人格设定信息、当前会话的前n条信息、当前会话的历史摘要、对触发bot回复的用户印象 以上设计的是为了尽可能让bot"记住"某一用户,但是为了节省token消耗又不得不隔离出部分信息的一种权衡策略,希望我的解释对您有帮助,如果有更好的思路欢迎提出!
大佬你好,当bot在群里聊天时,使用当前会话的前n条信息作为bot的回复参考信息,经常会使bot变得胡言乱语,因为群里的消息如果没有@或者提及bot,那所谈论的话题基本上都是与bot毫不相关的内容。大佬是否可以考虑让bot只使用@或提及bot名字的消息作为bot的回复参考信息,让bot不要记录没有@或提及他的消息。或者设置一个开关来控制是否使用当前会话的前n条信息作为参考信息。十分感谢!大佬的项目真的超级棒!◝(⑅•ᴗ•⑅)◜..°♡
谢谢提议哈!其实让bot参考最近聊天信息的这个设计是我有意为之的,这个项目思路参考了另外两个大佬的类似ai聊天项目,一个是koishi平台的OpenAi插件:https://github.com/TomLBZ/koishi-plugin-openai,另一个是nb的gpt3:https://github.com/chrisyy2003/nonebot-plugin-gpt3 openai的方案其实就是如你所说的方式,仅使用用户与bot相关的聊天信息,并且bot的记忆只针对单用户个人,在我的测试中发现这种方式虽然能够使bot的回复对应得上提及用户的发言,但是在群聊场景下记忆的割裂感比较强,例如说两个人连续问了bot相同或者类似的问题,bot可能根据不同的记忆(通常是过时的)给出了完全不同的回答,又或者群聊中其他用户在讨论某个话题,其中一人询问bot对该话题的看法时可能会因为参考信息割裂而给出比较出戏的回答(毕竟群聊中较近期的记录对人类来说也是决定发言内容的重要参考,另外改善这个问题也是我决定开发这个插件的一个重要原因) 至于“使bot变得胡言乱语”这个问题我认为比较重要的因素可能是你的群友不太想理会bot,导致bot难以融入话题,我会尝试在下个版本调整prompt生成方式,看能不能提高bot对“提及者”的注意力,但效果尚不能确定(;´д`)ゞ 有更好的想法欢迎提出哟!谢谢喜欢 ~(○` 3′○)
我也认为让bot被@、回复或提及bot名字的消息的时候才把该条消息记录在内会比较好,否则bot会一直记录消息,生成印象promot,这样是会一直消耗token的吧。况且群友平常聊天的时候对话通常是比较无厘头可能还会发癫(?),如果一直记录群消息的话,bot很有可能会在回答问题的时候胡言乱语,所有有选择性的记录消息效果应该会比较好。
目前bot没有被@或者提及时不会消耗token,只会把当前信息暂存到当前会话的消息队列中,作为接下来可能会被唤醒时使用的参考信息,该队列设定了最大限制,超出的消息会被自动清除 另外印象prompt的生成是仅根据bot对唤醒者的对话信息生成的,用户与bot无关的日常群组互动不会参与印象记忆
可以使用我制作的异步 LLM 框架,经过长期的应用测试 https://github.com/LlmKira/llm-kira 只需要传递即可,自动调整到最优解
@sudoskys 大佬您好,我尝试研究了下您的框架,遇到了些问题,简单的说就是我几乎没有看明白,能否简要分享一下您的实现思路或者说明一下框架的详细功能呢(小声) (/▽\)
import asyncio
import random
import llm_kira
from llm_kira.client import Optimizer
from llm_kira.client.types import PromptItem
from llm_kira.client.llms.openai import OpenAiParam
from typing import List
# 定义 ApiKey池
openaiApiKey = ["key1", "key2"]
openaiApiKey: List[str]
# 定义接收者
receiver = llm_kira.client
# 创建对话,一个ID一个记忆池
conversation = receiver.Conversation(
start_name="Human:",
restart_name="AI:",
conversation_id=10093, # random.randint(1, 10000000),
)
# 创建语言模型对象
llm = llm_kira.client.llms.OpenAi(
profile=conversation,
api_key=openaiApiKey,
token_limit=3700,
auto_penalty=False, # 暂时不能用的自动惩罚
call_func=None, # Api错误回调函数,用于操作失败的情况,传入的是 key 和 错误返回
)
# 记忆管理器
mem = receiver.MemoryManager(profile=conversation)
# 创建聊天机器人
chat_client = receiver.ChatBot(profile=conversation,
memory_manger=mem,
optimizer=Optimizer.SinglePoint, # 单点聊天优化器(相对应的是群聊优化器)
llm_model=llm)
async def chat():
# 创建提示管理器
promptManager = receiver.PromptManager(profile=conversation,
connect_words="\n",
template="Templates, custom prefixes" # 模板,用于自定义你的 head,这个不会被自动对齐削减
)
# 后加入的会排在前面
promptManager.insert(item=PromptItem(start=conversation.start_name, text="My id is 1596321")) # start 就是询问人的名字,从对话对象获取
response = await chat_client.predict(llm_param=OpenAiParam(model_name="text-davinci-003", n=2, best_of=2),
prompt=promptManager,
predict_tokens=500,
increase="External enhancements, or searched result",
)
# increase 作为 一个额外接口,作为实时信息或者其他信息的注入口
print(f"id {response.conversation_id}")
print(f"ask {response.ask}")
print(f"reply {response.reply}")
print(f"usage:{response.llm.usage}")
print(f"usage:{response.llm.raw}")
print(f"---{response.llm.time}---")
promptManager.clean()
promptManager.insert(item=PromptItem(start=conversation.start_name, text="Whats my id?"))
response = await chat_client.predict(llm_param=OpenAiParam(model_name="text-davinci-003"),
prompt=promptManager,
predict_tokens=500,
increase="外部增强:每句话后面都要带 “喵”",
# parse_reply=None
)
_info = "parse_reply 函数回调会处理 llm 的回复字段,比如 list 等,传入list,传出 str 的回复。必须是 str。"
_info2 = "The parse_reply function callback handles the reply fields of llm, such as list, etc. Pass in list and pass out str for the reply."
print(f"id {response.conversation_id}")
print(f"ask {response.ask}")
print(f"reply {response.reply}")
print(f"usage:{response.llm.usage}")
print(f"usage:{response.llm.raw}")
print(f"---{response.llm.time}---")
asyncio.run(chat())
抽象了 llm 大模型, 记忆管理,提示管理,对话身份 。传入多个 api key 自动轮流负载
@sudoskys 感谢大佬的耐心解释,学习了!看起来您这个已经是一个完整的项目了,或许直接做成一个新的插件会更合适呢?
@sudoskys 感谢大佬的耐心解释,学习了!看起来您这个已经是一个完整的项目了,或许直接做成一个新的插件会更合适呢?
是LLM的基础设施
@DanLCJ 已确认bot对话管理为全局是一个bug,其他群组或私聊的消息存在串线情况,预计今晚更新修复此问题(原谅我测试不充分过了这么久才发现这个bug (/▽\)
@KroMiose 作者你好,因为有时候会有同一批人来回水好几个群,群聊信息串线的bug也许是一个很有趣的特性,增加一个同步几个指定的群的群消息的功能会不会比较好?
@xuanmeikawaii 这个bug(特性)确实相当有趣,但是我个人觉得对于更多的情况来说还是弊大于利的,主要是出于以下几点考虑:
@KroMiose 作者你好,很喜欢你做的聊天机器人。作为一个没有研究过这些的小白,我有几个问题想问您。首先就是关于api的,我选择的是国内第三方代理的gpt api请问这样可以吗,如果可以应该怎么调整呢?其次就是关于记忆功能,我看到说可以启动主动记忆,但是需要安装扩展,请问扩展是需要找其他作者的记忆扩展吗?如果不是请问能告诉我扩展的下载地址吗?谢谢!
@KroMiose 作者你好,很喜欢你做的聊天机器人。作为一个没有研究过这些的小白,我有几个问题想问您。首先就是关于api的,我选择的是国内第三方代理的gpt api请问这样可以吗,如果可以应该怎么调整呢?其次就是关于记忆功能,我看到说可以启动主动记忆,但是需要安装扩展,请问扩展是需要找其他作者的记忆扩展吗?如果不是请问能告诉我扩展的下载地址吗?谢谢!
OPENAI_BASE_URL
字段,将其值的 api.openai.com
替换为你的第三方 api 地址即可谢谢你的喜欢!(另外如有其他问题请开新 issue 讨论,在已有 issue 下提问会同时给该 issue 所有参与者发送邮件提醒)
您好!我发现现阶段nonebot的对话记忆是全局的,即有关机器人的所有对话根据时间轴进行记忆更新。但是很多时候比如群聊与私聊并不需要相同的历史记录的记忆,对每一个单独的对话应当同时拥有一个单独的记忆。请问应该在哪里进行修改?或者之后会有这部分功能的更新吗?感谢