React Query 缓存 AI 对话历史的几个权衡

之前对话历史我是自己写了一坨 state + useEffect 管的,加载、缓存、失效全手撸,代码越滚越乱。后来用 React Query(TanStack Query)接管,清爽不少。但 AI 对话这种场景跟普通列表不太一样,套缓存有几个要想清楚的取舍,聊聊。

历史列表用 useQuery 很顺

会话列表、某个会话的历史消息,都是典型的服务端状态,useQuery 一把:

php 复制代码
const { data: messages } = useQuery({
  queryKey: ['chat', sessionId],
  queryFn: () => fetchMessages(sessionId),
  staleTime: 5 * 60 * 1000, // 5 分钟内不重新拉
})

切会话再切回来,有缓存秒出,不用转圈,这点体验提升很明显。

麻烦在于:流式新消息怎么塞进缓存

这是最别扭的地方。AI 新回的消息是流式一点点来的,不是一个请求返回的整块数据,套不进 queryFn 那套。我的做法是:流式过程中用本地 state 管那条"正在生成"的消息,生成完了再用 setQueryData 手动把它合并进缓存:

ini 复制代码
queryClient.setQueryData(['chat', sessionId], old =>
  [...old, finishedMessage])

等于流式期间走本地 state,落定后才进 Query 缓存。两套状态并存,得小心别让它们打架------我就出过新消息在缓存里出现两次的 bug,因为生成完合并了一次、下次拉历史后端又返回了一次。

staleTime 别设太短

对话历史不像股价,不需要频繁刷新。我一开始没设 staleTime,默认是 0,结果每次切回会话都重新拉一遍,白白请求。设成几分钟甚至更长都行,历史消息又不会自己变。

乐观更新让发送不卡

用户发的消息,用 onMutate 先乐观塞进缓存,UI 立刻显示"我"的气泡,不用等请求回来。失败了再 onError 回滚。发消息这步体感能从"点一下等半秒"变成"秒出"。

一个没理顺的

queryKey 我用 sessionId 做 key,但分页历史(往上翻旧消息)我用了 useInfiniteQuery,跟流式新消息的合并逻辑搅在一起,代码读起来挺绕。这块结构我还想再重构,目前能跑但不算优雅。

模型这层我直接调讯飞 MaaS,现成 API 不用自建算力,前端就专心把这套缓存逻辑磨顺。你们用 Query 管 AI 对话有啥心得,评论区交流。

相关推荐
必须会一定会几秒前
AI 前端项目验收:Playwright 截图、响应式视口、控制台错误与交互回归
前端·人工智能·gpt·交互·ai编程
Bruce_Liuxiaowei3 分钟前
从基础理论开始学习人工智能(二):应用和方法——从拼图游戏到神经网络
人工智能·神经网络·学习
Fnetlink15 分钟前
解析SDWAN供应商光联世纪口碑佳的原因
网络·人工智能·安全
孫治AllenSun5 分钟前
【LangChain4J-04】Tool 工具的使用
java·人工智能
MartinYeung58 分钟前
[论文学习]动态红队测试DAS:破解医疗大语言模型静态评估的“信任陷阱”
人工智能·学习·语言模型
JavaPub-rodert11 分钟前
TrustGraph 详解:把知识图谱、Ontology、GraphRAG 和 AI Agent 串成一套系统
人工智能·知识图谱
迷迭香yy17 分钟前
回测过拟合检测体系从样本内外到组合稳健性评估 IG50免费开源股票数据API接口
服务器·开发语言·数据库·人工智能·python
数字融合19 分钟前
透明化数字孪生:未来医疗的核心平台
大数据·人工智能·virtualenv
richard_first19 分钟前
Transformer 与大语言模型:第7章 Multi-Head Attention 多头注意
人工智能·深度学习·机器学习
大江东去浪淘尽千古风流人物21 分钟前
【HMD-Poser】CVPR2024 头显端实时全身动捕:可伸缩稀疏观测、LSTM+Transformer 时空解耦与在线体型估计
人工智能·lstm·transformer·vr·人体姿态估计