基于 PHP +EventSource 实现了 ChatGPT 的 Stream 响应,源码分享给大家

2023-03-17 12:21:55 +08:00
 nonfu

虽迟但到,这周给我的小玩具 GeekChat 新增了对 stream 响应的支持,实现边回复边输出,感兴趣可以体验下:GeekChat —— 支持语音的免费体验版 ChatGPT。前端交互还有待优化,放到下个迭代吧。

由于 GeekChat 是用 Laravel + Vue3 实现的,所以也必须依赖这套技术栈实现 stream 流式响应,对应的实现源码已经提交到 Github:https://github.com/geekr-dev/geekchat,如果觉得对你有帮助,顺手点个 star 。

用到的东西:

注意点:

由于用到了 headerob_flushflush 这些函数,所以不支持基于 Swoole 、RoadRunner 之类常驻内存机制驱动的 PHP HTTP 服务器,在部署到生产环境的时候需要注意这一点。

2916 次点击
所在节点    程序员
15 条回复
PickleFish
2023-03-17 12:33:07 +08:00
不懂 但已 star
sunny1688
2023-03-17 13:39:08 +08:00
那你这个 server 还能并发?
brader
2023-03-17 15:43:25 +08:00
我建议你关闭缓冲区或者调整缓冲区的大小,它会让你 UI 表现看起来是逐字出现而不是一段一段的出现,表现更加丝滑,体验会更加友好。
缓冲区可能存在于列举任何一个地方:代码、中间代理服务、nginx 等等
nonfu
2023-03-17 16:35:49 +08:00
@sunny1688 并发肯定能做的啊 调用的 API 肯定支持并发 不要超过它的频率限制就好了
nonfu
2023-03-17 16:36:09 +08:00
@brader 好的 感谢反馈
shellus
2023-03-17 17:41:32 +08:00
@brader 这个逐字出现的效果在前端实现比较好吧,为了这个效果去调整传输层的缓冲区,好没有必要的感觉
shellus
2023-03-17 17:43:35 +08:00
请教一下,这个 EventSource 和 websocket 相比好像没什么优势吧,后端的支持的话,也是 swoole 的 websocket 更好简单实用,技术栈比较主流吧?
brader
2023-03-17 18:06:03 +08:00
@shellus 客户端是无法实现的我说的效果的,因为流形式 gpt 回答问题是持续性逐字回答。
因为开启了缓冲区,假设一段话被分为了 A 、B 、C 三块进行输出,那么客户端接收数据流程如下:

客户端等待 -> 客户端接收 A 块消息(这里按你说的,客户端自实现逐字输出) -> 等待 -> 接收 B 块消息 -> 等待 -> 接收 c 块消息

你会发现上面的流程,虽然你接收到一整块的大量文字的时候,自己做了逐字输出,但因为服务端必须等待接收满一个缓冲区的数据,才会向客户端发送数据,所以客户端在每一块数据之间,又进入了等待期,失去了连续性。
shellus
2023-03-17 18:46:47 +08:00
@brader 有道理
Acckr
2023-03-20 10:38:32 +08:00
速度好慢,另外总是出现 接收回复出错,请重试
nonfu
2023-03-21 02:07:03 +08:00
@Acckr 访问频率太高+key 消耗完了
ieliwb
2023-03-23 11:24:46 +08:00
大佬好,php-fpm 有连接限制的,你这开启流模式,会导致一直占有 fpm 进程,后面的用户因为连接数限制完全挤不进来啊,服务器不挂了
nonfu
2023-03-23 21:01:08 +08:00
@ieliwb 一条消息处理完就关闭了 这不比 websocket 那种一直监听
voidmnwzp
2023-03-28 18:14:33 +08:00
我用 evensource 会丢掉数据中的空格符 不知道啥原因
alanhe421
249 天前
@shellus websocket 是全双工,EventSource 是单工,开销自然是 EventSource 小一些。具体肯定是看场景。

AI 聊天是发送消息,之后服务端持续输出,WebSocket 多少是浪费点。

不过 ChatGPT 目前用的是 fetch ,而非 eventsource ,毕竟 eventsource 没办法发请求体,只靠 URL 或者再加个请求做,多少不方便点。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/924812

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX