Closed Ace-Radom closed 1 year ago
目前加了多线程锁的部分有:
total_tokens_spent
更新在后台已经启动生成标题时主线程的阻塞则直接用 isAlive
和 join
实现 不需要多线程锁
~加上CLI标题更新锁后主线程不需要再阻塞标题请求支线程~
可以在 .env
内增加 AUTO_GENERATE_TITLE
开关
设置1为启用标题自动生成 设置为其他任何值则停用 默认启用 即:
OPENAI_API_KEY=sk-xxxx
AUTO_GENERATE_TITLE=1
此点需要在README内说明
我看到了你在每个记录日志的地方都加入了线程锁,这是必要的么?我记得logging本身就是支持多线程的,不管是子线程还是主进程,都是只管写日志就好了
这点我不是非常清楚 昨天是没想太多就全部加了线程锁 我一会儿再去看一下文档
查过了 logging本身是线程安全的 那我就把所有logging的mt锁删掉了
基本完成 功能实现 但是我在使用的时候注意到他的响应速度变慢了【虽然目前main分支上的那个版本一样响应慢】但你要不看看代码里会不会出现什么冲突之类的 虽然我想应该不会
碎碎念:隔壁川虎一样响应慢 看来是我的key的问题或者服务器问题……吧 虽然我晚上还是会整个代码review一遍
我又优化了一点,这个线程创建用默认类就可以了,而且它会自己分配唯一的name,ID也就不需要了。
以及mac上测试也很完美,就是它创建标题的时机我觉得还可以再早一点,在发出第一条消息之后可以马上开始标题生成线程。
还有就是感觉线程list这个管理方式还可以改进,我之前写过一个多线程的项目,是初始化的时候直接开启一个daemon线程,这个线程以一个queue作为参数,是一个while true循环,每次循环读一个队列里的内容然后生产结果,主进程只管放内容到queue中就可以。在这里的话queue的内容就是第一个信息的str内容,通过判断queue长度可以知道当前队列的阻塞程度。具体的稍后我看看能不能实现
是threading内置的Queue吧 那个我有去看过但有点迷糊 所以用了python2里常用的list管理方法 如果能改用Queue自然更好
顺便我先处理一下主分支和fork的冲突
哎这个冲突还不小,早知道等这个pull合并后再弄那个type了,现在不知道rebase main行不行
时间消耗大的函数是count_token,在初始化的时候它自己就消耗了0.16秒。如果在初始化的时候不调用count_token,启动时间就是0.001秒,这个区别足以肉眼可见了,所以我在考虑把count_token也弄成线程
这conflicts怎么还越弄越大了呢(玩脱了 我回退一下分支版本重新解决 这个可能真麻烦了
时间消耗大的函数是count_token,在初始化的时候它自己就消耗了0.16秒。如果在初始化的时候不调用count_token,启动时间就是0.001秒,这个区别足以肉眼可见了,所以我在考虑把count_token也弄成线程
是一个方法 锁好tokens spent应该问题不大
这conflicts怎么还越弄越大了呢(玩脱了 我回退一下分支版本重新解决 这个可能真麻烦了
没事到最后merge的时候再手动解决也行
好那我就先不处理冲突了 版本退回到尝试解决之前了 也就是你上次在分支里push的那个commit
是threading内置的Queue吧 那个我有去看过但有点迷糊 所以用了python2里常用的list管理方法
啊之前是理解错了 现在明白你那个啥意思了【把标题更新的请求往队列里丢然后背后运行的支线程在收到了就发送……?】 如果我理解的对的话我应该也能写 但这个看你吧不知道你是不是已经开始了
其实是【把新的第一个提问内容往队列里丢然后背后运行的支线程,支线程把提问内容从队列中取出来后开始运作修改title】,我还没写,你想写的话可以试试,不然我明天写。刚才在尝试rebase,结果一团糟,睡了睡了。
ok那我这晚上尝试一下
顺便冲突貌似解决了 在自己的fork里成功合并了 现在应该是没问题了
上两次commits的更改如下:
gen_title
函数 具体内容见下文/title
和 /save
命令中的阻塞逻辑:不再直接阻塞而是直接交给 gen_title
函数/title force
命令 用于强制重新生成标题gen_title
函数的重写细节则为:
force
参数 用于在已经有标题生成时强制重新生成标题【即绕过是否已经生成标题的判断】至于 count_tokens
我个人电脑上测试下来确实有一些慢 0.1s左右 但还是可以接受的范围内 感觉我这的一秒左右的启动时间主要是花在了加载解释器上
所以我没有直接改进支线程或者守护线程 你看你需要改吧
发现了一个非预期行为,我在windows11(arm)的终端app里从powershell运行的,标题能正常设置,就是会提示这个
额能说一下你的win11具体环境嘛 我尝试一下在我电脑上重现这个问题
还有就是title命令的force选项,我觉得没必要,可以直接默认force。因为如果自动生成title是开启的,那么运行title命令不会有任何变化,相当于只是输出下当前title;如果自动生成title关闭,那么运行title 和title force 效果是一样的,都会生成并且设置title。你觉得呢?
写到这里我又想到,如果是load的聊天记录是不是也应该根据第一个问题生成下title或者直接用文件名作为title,我觉得用文件名就挺好
额能说一下你的win11具体环境嘛 我尝试一下在我电脑上重现这个问题
这个说来话长,我是在mac的虚拟机里运行的arm版本的windows11,但是我觉得是使用Windows terminal造成的
噢还有可能是因为我的python脚本位于smb目录(//目录),要是这样的话那也就没有解决的必要了
这个说来话长,我是在mac的虚拟机里运行的arm版本的windows11,但是我觉得是使用Windows terminal造成的
你是在用虚拟机访问共享文件夹来启动嘛 如果是的话那这个问题就不是win terminal的问题而是cmd的问题了 如果我没有记错的话cmd不支持访问共享目录 所以会出现这种错误【就像我电脑上的cmd一样没法进WSL的用户目录一样】
还有就是title命令的force选项,我觉得没必要,可以直接默认force。因为如果自动生成title是开启的,那么运行title命令不会有任何变化,相当于只是输出下当前title;如果自动生成title关闭,那么运行title 和title force 效果是一样的,都会生成并且设置title。你觉得呢?
当时加入force选项是因为想在比如标题生成不满意的时候强制重新生成 但现在看这个temperature设0.5貌似结果基本不会有变 去掉貌似也没什么问题
写到这里我又想到,如果是load的聊天记录是不是也应该根据第一个问题生成下title或者直接用文件名作为title,我觉得用文件名就挺好
是一种思路 但可能的问题是未必所有人都会喜欢预定的以 chat_histroy
为开头的模式来保存聊天记录 这样加入特判会不会有很多特殊情况……?毕竟在标题开头有一个chat_history或者别的东西占着有点不太好 CLI的标题一般性都不会太长
那么在json里专门加入一条来记载需要重现的title会不会也是一种选择 在 /save
确定保存文件名后再加入一条保存title的确认 默认使用【如果已经生成】目前的title 或者自定义
改聊天记录json的结构还是不太优雅。我就弄成直接显示文件名了,毕竟文件名里即便包含chat_history也是在提示用户这是一个加载的会话。这个时候如果不满意,用/title 新标题
自定义标题或者/title
生成标题也是可以的
looks fine 直接显示文件名确实不错 从我这看没什么问题了应该 如果没有什么别的更改或增加的话应该可以merge了我想
我在程序启动的部分加了点log记录 最初是debug用的但后来想想也有一定的用处所以就没删push上来了 你可以看看要不要保留
可以保留,但是换成log.debug级别吧,正常日志只显示聊天内容和报错就好了。包括生成标题的日志我也是打算在merge前弄成debug级别的,你要是改的话也可以一起改改
在INFO级别就保留了程序启动时候的 ChatGPT-in-Terminal Start
别的都放进了DEBUG级别
标题生成日志也改了 然后在程序头加了一段注释掉的启用debug级别log记录的程序段
好的辛苦了,晚点我更新下readme就merge了
没事没事
顺便你之前在虚拟机里出现的问题其实有解决方法 就是 os.chdir
回到home目录后才启动 title
命令 但我没有详细研究过 而且这个情况确实比较少见所以我就没有改 你可以考虑一下
可能的实现方法为:
home_dir = os.path.expandvars('%USERPROFILE%')
os.chdir(home_dir)
os.system(f"title {new_title}")
没事没事 顺便你之前在虚拟机里出现的问题其实有解决方法 就是
os.chdir
回到home目录后才启动title
命令 但我没有详细研究过 而且这个情况确实比较少见所以我就没有改 你可以考虑一下可能的实现方法为:
home_dir = os.path.expandvars('%USERPROFILE%') os.chdir(home_dir) os.system(f"title {new_title}")
要chdir的话就算了,我怕影响/save功能,它默认存到相对目录的
Done, Ready to Merge
Link Issue #17
思路为 在输出ChatGPT的回复后检查messages list 如果是此chat的第一次conversation则~启动一个支线程~将对话传递给标题请求守护进程并向gpt请求标题 在正确回复后更改终端 (CLI) 的标题 主线程不会主动阻塞支线程 仅当在调用
/save
~/tokens
~/title
命令时会检查线程状态 若标题请求线程仍在运行则阻塞主线程直至标题请求线程join或异常退出TO DO:
/title
命令 用于手动生成并更改CLI标题total tokens spent
send_request
和gen_title
函数gen_title
函数中Exception进行审查~和扩展~/save
/title
等命令中加入线程检查和主线程阻塞函数.env
中增加开关 用于开关自动标题生成功能Updates:
gen_title
改为直接向Queue传递对话内容以调用标题请求守护线程tokens_count
从主线程分离以加快运行速度~【暂时取消】Bugs need to fix:
RuntimeError: threads can only be started once
print
结尾去除换行符导致缓冲区不会主动刷新 从而导致控制序列无法生效】Things need help:
change_CLI_title
的Mac端适配性~ 已完成 可用 理论上Mac现在的zsh和debian的控制序列应该是部分通的 但我没mac电脑或者虚拟机没法测试个人建议在merge这个PR之前先按照目前的main分支发布一次release 这个多线程虽然我自己看上去是没问题了用也能用但我不知道是不是所有地方都考虑到了 先发一个没有多线程模块的release会不会好一点 不知道你怎么看