在看 openai 的 messages api ,发现客户端需要做大量得状态管理,来维护历史消息,为什么不和网站 cookie 一样弄个 sessionId 这样的状态字段。另外,聊天场景下,每次请求都携带重复的历史数据,得浪费多少带宽资源!
请问,从技术角度分析这样设计的好处是啥?
这是官方的 python 客户端示例:
1 zhlxsh 128 天前 via iPhone ![]() 无状态的好处,就是不需要保存状态。谜底就在谜面上。 想象一下,你需要给一百个用户提供打扑克的出牌预测服务,每个人的步骤不一样,你需要保存这 100 个人之前出过的所有状态,如果谁中途掉了你还得一直保存,因为说不定他啥时候连上来。 而如果是无状态的,每个人发出的请求里携带之前出过的人牌就可以了,只需要在客户端保存数据,而服务端每次只需要做都是当前状态的分析,结束就是结束了。你的代码只需要做一件事,已知出过的牌和手里的牌,预测最佳的出牌方法 |
![]() | 2 beyondstars 128 天前 国外宽带资源不那么贵吧,然后,无状态便于水平横向拓展?容易 scale up? |
3 RedNax 128 天前 ![]() 大概是因为和 AI 计算的消耗比起来,那点带宽根本不算钱吧。 |
![]() | 4 msg7086 128 天前 ![]() 因为有 session 以后横向扩展更难,你需要维护一个 session storage 。 而且在有 session id 的情况下你计算节点不还是要通过网络去 session storage 读取数据?这不还是要带宽? 从用户的网络传历史数据对企业来说并没有多浪费啊。 |
![]() | 5 neteroster 128 天前 via Android 你是否在找:Responses API |
![]() | 6 neteroster 128 天前 via Android @neteroster 不过我不怎么喜欢 Responses API ,感觉整体还是无状态的设计比较好 |
7 Ljxtt 128 天前 感觉是因为大模型本身就是无状态的吧。同时上下文是需要成本的,而且上下文大小也是有限制的,你可以自行决定怎么去处理上下文。 |
8 allplay 128 天前 via Android @zhlxsh 这样能理解为什么 ai 在最终给出答案的时候才知道自己说出了不该说的话。用户利用这一点还能规避审查。比如让 ai 在答案中插入字符,拼音表示等等,扰乱。 |
![]() | 9 cowcomic 128 天前 这个问题其实技术不是重点 商业模式才是重点,有状态的话,怎么收费 |
![]() | 10 zx9481 128 天前 为了隐私? |
11 mumbler 128 天前 长期记忆太贵了,支持 32K 上下文就需要 150G 显存 |
12 acorngyl 128 天前 因为大模型本来就没状态。所谓的多轮对话和上下文,都是模拟出来的。你给个简单问题,大模型根据简单问题给个回答;给个带上下文的对话,大模型根据这个对话内容,给个回答。模型只有输入、输出的概念,没有轮的概念。这就是为什么 chat 刚出来的时候限制 50 轮对话了,问题超过 50 轮的拼接,大模型一次处理不过来。 |
![]() | 13 elevioux 128 天前 因为 llm 本身就是必须每次都提供完整的上下文,api 的设计只是反映了这一点而已。 当然,各公司也可以在此基础之上再封装一层( api 或 sdk ),帮用户维护 session ,就看成本了。 对我来说,提供完整上下文反而可能更灵活些,因为有些场景会对用户的输入或上下文进行修改。 |
![]() | 14 ckvv 128 天前 模型有上下文大小限制 1M 都没有 |
![]() | 15 zdl0929 128 天前 |
![]() | 16 wulili 128 天前 应该就是出于成本考虑,如果额外加一层历史消息存储得浪费不少资源,那干脆就将问题抛给前端用户了,省时省力。 不过感觉这种 api 设计迟早得改,不然随着以后上下文越来越长,每次带着一坨屎山一样的历史数据传来传去,带宽成本早晚得超过存储成本。 |
![]() | 17 maokg 128 天前 没有什么是加一个中间层不能解决的,如果不行,就加两层 |
![]() | 18 irrigate2554 128 天前 无状态好处很多,我举例一个,比如你和 AI 进行了 5 轮会话,这个时候你感觉从第 3 轮开始有些跑偏了,想从第三轮开始重新对话,如果是有状态 API 这个挺麻烦的,要么设计回滚对话的 API 要么重新从第一轮开始进行对话(由于大模型的不稳定性你不一定能得到一样的对话),如果是无状态则很简单,删除 4 ,5 轮的对话记录继续对话就行。 |
19 wnpllrzodiac 128 天前 via Android @mumbler 人脑值几百亿了 |
20 jonsmith 128 天前 via Android 可能是现在的 LLM 上下文不大,做 session 没有必要。等以后上下文越来越大,可能会做了。 |
21 hwdq0012 128 天前 热知识:有状态服务可以通过 redis 之类的服务转换为无状态,弹性扩容更方便 |
![]() | 22 min 128 天前 带宽值几个钱? |
24 mumbler 128 天前 @wnpllrzodiac #19 人脑内存并不大,验证码超过 6 位都要分至少两次输入,背单词背课文更是困难,一会就忘了,记忆都是极其精简的摘要和画面,上下文不足 1K ,只不过人脑效率高,而且容错率极高,哪怕真错了也可以不承认 |
25 Need4more OP @min @RedNax 可是他们现在月活都超 5 亿了呀,这么大的流量不考虑带宽成本吗? 个人感觉是历史遗留问题,早期纯文本对话这样设计不是问题,可是现在支持多模态,输入会包含图片、视频、文件了,带宽成本不容小觑! 他们现在也有带状态的 api ,pdf 上传: https://platform.openai.com/docs/guides/pdf-files?api-mode=responses |
![]() | 26 coefu 128 天前 今年都加大权重的堆砌记忆能力了,还需要 web 的状态做什么。 |
![]() | 27 DTCPSS 128 天前 方便 scale |
![]() | 28 wyntalgeer 128 天前 因为状态在应用层,LLM 你把它理解成一个高级算法。你见过给 SDK/工具类/算法库加状态的? |
![]() | 29 ipwx 128 天前 大模型的上下文是内部的某种 embedding 输出啊。。。 ==== 这个 embedding 不同模型都不一样,同一个模型的不同版本都不一样。只有精确到某个版本、某个模型,才有可能存储这个真正的上下文。你调用的是通用接口,所以没办法拿到这个真正的上下文,那你只能把 history 再喂给它一遍,让它重新构造出这个内部上下文。 有些模型有 streaming api ,一个合理的实现方法是客户端只存某个 id ,让服务器去存储这个上下文 context 。用 id 去关联 context 。但用户啥时候弃用这个 context ?多长时间过期?这些问题都很麻烦,特别是互联网场景,用户很多的情况下。所以很多 api 不支持 streaming 也很合理嘛。 更何况如果你用着某个上下文,服务器那边模型更新了,瞬间原来的 context embedding 废了,进去就是一堆乱码,用户这不得骂娘,还不如浪费些算力让大模型重新看一遍历史。 ==== 当然不得不存储 embedding 的场景也是有的,那种就叫做 rag 。这也算是一种折中:让大模型每次都看一遍整个资料库显然计算开销太大了,但是让大模型每次都把所有对话的 embedding 都存下来那存储(和检索)开销又太大了。那么不得已,就采用资料库的 embedding 存起来、对话不存 embedding 。这不是很合理么 |
![]() | 30 willchen 128 天前 计费透明呗 |
![]() | 32 sakeven 127 天前 via iPhone 别给无状态 API 找各种理由了,OpenAI 已经在主推 Responses API 了 |
![]() | 33 lan894734188 127 天前 via iPhone 因为综合来说 显存和运行性能划算 无状态还能吃你 input tokens |