AI大模型上下文连续对话+Token计费统计商用方案|SpringBoot3实现对话记忆、精准计费、额度限流(生产可用)

发布时间:2026/9/13 14:52:23

AI大模型上下文连续对话+Token计费统计商用方案|SpringBoot3实现对话记忆、精准计费、额度限流(生产可用) AI大模型上下文连续对话Token计费统计商用方案SpringBoot3实现对话记忆、精准计费、额度限流生产可用一、前言单轮对话的致命短板在上一篇Java后端对接AI大模型SSE流式输出实战中我们实现了基础的AI打字机流式问答但仅支持单轮独立对话存在两大商用致命问题无上下文记忆每轮问答相互独立AI无法关联历史对话完全不符合用户使用习惯无计费统计无法统计用户提问、AI回复的Token消耗付费AI产品无法核算成本、计费收费无额度管控无限流、无额度限制极易被恶意刷接口造成高额AI成本损耗本文基于原有SSE流式架构零重构升级完整实现多轮上下文记忆对话 精准Token计费统计 用户额度限流管控一套代码直接支撑商用AI产品落地。二、核心原理前置认知2.1 AI上下文对话原理大模型本身无本地记忆能力所有上下文记忆均由业务后端维护。每次请求AI接口时需要携带历史对话记录 当前用户提问大模型根据完整对话列表实现连续问答。2.2 Token计费规则主流大模型DeepSeek、GPT、通义千问均采用输入Token输出Token分开计费模式输入Token用户提问 历史上下文总字符消耗输出TokenAI返回回答内容消耗总费用 输入Token单价 输出Token单价2.3 上下文过期与截断机制对话无限累加会导致上下文过长、Token暴增、请求超时生产环境必须配置上下文最大长度限制、自动截断、过期清理机制。三、项目依赖复用原有架构无需新增复杂依赖沿用之前SSE流式项目依赖仅需新增Redis依赖维护用户会话上下文!-- Redis维护用户会话上下文、额度限流 --dependencygroupIdorg.springframework.boot/groupIdartifactIdspring-boot-starter-data-redis/artifactId/dependency四、核心实体类定义4.1 对话消息实体统一封装单条对话消息角色、内容适配大模型标准参数格式importlombok.AllArgsConstructor;importlombok.Data;importlombok.NoArgsConstructor;/** * AI对话消息实体 */DataNoArgsConstructorAllArgsConstructorpublicclassAiMessage{// 角色user用户提问、assistant AI回复、system系统提示词privateStringrole;// 对话内容privateStringcontent;}4.2 Token计费统计实体精准记录单轮对话、用户累计Token消耗importlombok.Data;/** * AI对话Token计费统计实体 */DatapublicclassAiTokenBill{// 输入Token用户提问上下文privateIntegerinputToken;// 输出TokenAI回复privateIntegeroutputToken;// 本轮总TokenpublicIntegergetTotalToken(){returninputTokenoutputToken;}}五、工具类封装Token计算上下文管理5.1 Token通用计算工具类采用行业通用字符估算规则适配绝大多数大模型误差极低商用足够/** * AI Token计算工具类 * 通用估算规则1中文≈2Token1英文/数字≈1Token */publicclassAiTokenUtil{/** * 文本转Token估算 */publicstaticintcountToken(Stringtext){if(textnull||text.isEmpty()){return0;}// 中文字符统计longchineseCounttext.chars().filter(c-c127).count();// 英文、数字、符号统计longotherCounttext.length()-chineseCount;// 通用换算公式return(int)(chineseCount*2otherCount);}}5.2 原有SSE工具类复用沿用上篇文章SseUtil工具类无需修改保证流式推送稳定性。六、Redis上下文会话管理核心使用Redis缓存用户会话对话记录设置过期时间实现多轮记忆、自动过期清理支持多端会话同步。importcom.alibaba.fastjson2.JSON;importorg.springframework.data.redis.core.StringRedisTemplate;importorg.springframework.stereotype.Component;importorg.springframework.util.CollectionUtils;importjavax.annotation.Resource;importjava.util.ArrayList;importjava.util.List;importjava.util.concurrent.TimeUnit;/** * AI会话上下文管理工具 */ComponentpublicclassAiSessionContext{ResourceprivateStringRedisTemplatestringRedisTemplate;// 用户会话Key前缀privatestaticfinalStringAI_SESSION_PREFIXai:session:;// 会话过期时间30分钟无对话自动失效privatestaticfinallongSESSION_EXPIRE30;// 最大上下文对话轮数防止Token溢出privatestaticfinalintMAX_HISTORY_NUM10;/** * 获取用户完整上下文对话 */publicListAiMessagegetHistoryMessage(StringsessionId){StringkeyAI_SESSION_PREFIXsessionId;StringjsonstringRedisTemplate.opsForValue().get(key);if(jsonnull||json.isEmpty()){returnnewArrayList();}// 读取历史对话只保留最新10轮截断旧对话ListAiMessagemessageListJSON.parseArray(json,AiMessage.class);if(messageList.size()MAX_HISTORY_NUM){messageListmessageList.subList(messageList.size()-MAX_HISTORY_NUM,messageList.size());}returnmessageList;}/** * 更新用户会话上下文 */publicvoidupdateSessionMessage(StringsessionId,ListAiMessagemessageList){StringkeyAI_SESSION_PREFIXsessionId;StringjsonJSON.toJSONString(messageList);// 更新并重置过期时间stringRedisTemplate.opsForValue().set(key,json,SESSION_EXPIRE,TimeUnit.MINUTES);}/** * 清空用户会话 */publicvoidclearSession(StringsessionId){stringRedisTemplate.delete(AI_SESSION_PREFIXsessionId);}}七、完整商用接口上下文对话Token计费整合SSE流式推送、多轮上下文记忆、Token实时统计、会话更新可直接上线商用importcom.alibaba.fastjson2.JSON;importcom.alibaba.fastjson2.JSONObject;importokhttp3.*;importorg.springframework.web.bind.annotation.*;importorg.springframework.web.servlet.mvc.method.annotation.SseEmitter;importjavax.annotation.Resource;importjava.io.BufferedReader;importjava.io.InputStreamReader;importjava.util.List;importjava.util.UUID;RestControllerRequestMapping(/ai)publicclassAiChatController{// 大模型密钥地址privatestaticfinalStringAPI_KEYsk-xxxx;privatestaticfinalStringAI_URLhttps://api.deepseek.com/v1/chat/completions;ResourceprivateAiSessionContextaiSessionContext;/** * 多轮上下文流式对话 Token计费统计 * param sessionId 会话ID前端生成唯一标识用户对话 * param prompt 用户提问 * return SSE流式响应 */GetMapping(value/chat/context/stream,producestext/event-stream;charsetUTF-8)publicSseEmitterchatContextStream(RequestParamStringsessionId,RequestParamStringprompt){SseEmitteremitterSseUtil.createEmitter();// 异步处理对话逻辑不阻塞主线程newThread(()-{try{// 1. 获取用户历史上下文对话ListAiMessagehistoryListaiSessionContext.getHistoryMessage(sessionId);// 2. 加入当前用户新提问historyList.add(newAiMessage(user,prompt));// 3. 计算输入Token上下文当前提问总消耗StringinputAllContentJSON.toJSONString(historyList);intinputTokenAiTokenUtil.countToken(inputAllContent);// 4. 构建大模型请求参数JSONObjectjsonnewJSONObject();json.put(model,deepseek-chat);json.put(stream,true);json.put(temperature,0.7);json.put(messages,historyList);// 5. 发起大模型请求OkHttpClientclientnewOkHttpClient();RequestBodybodyRequestBody.create(json.toString(),MediaType.get(application/json; charsetutf-8));RequestrequestnewRequest.Builder().url(AI_URL).addHeader(Authorization,Bearer API_KEY).post(body).build();Responseresponseclient.newCall(request).execute();BufferedReaderreadernewBufferedReader(newInputStreamReader(response.body().byteStream()));// 6. 流式接收AI回复统计输出TokenStringBuilderaiReplynewStringBuilder();Stringline;while((linereader.readLine())!null){if(line.startsWith(data: )!line.contains([DONE])){Stringdataline.substring(6);JSONObjectresJsonJSON.parseObject(data);StringcontentresJson.getJSONArray(choices).getJSONObject(0).getJSONObject(delta).getString(content);if(content!null){aiReply.append(content);// 逐字推送给前端SseUtil.send(emitter,content);}}}// 7. 统计完整Token消耗intoutputTokenAiTokenUtil.countToken(aiReply.toString());AiTokenBilltokenBillnewAiTokenBill();tokenBill.setInputToken(inputToken);tokenBill.setOutputToken(outputToken);// 8. 更新会话上下文存入AI回复实现下一轮记忆historyList.add(newAiMessage(assistant,aiReply.toString()));aiSessionContext.updateSessionMessage(sessionId,historyList);// 9. 末尾推送计费信息特殊标识前端单独解析SseUtil.send(emitter,\n【计费统计】输入TokeninputToken输出TokenoutputToken总TokentokenBill.getTotalToken());}catch(Exceptione){SseUtil.send(emitter,对话异常请重试);}finally{SseUtil.complete(emitter);}}).start();returnemitter;}/** * 清空对话上下文 */GetMapping(/chat/clear)publicStringclearChat(RequestParamStringsessionId){aiSessionContext.clearSession(sessionId);return对话上下文清空成功;}}八、前端测试页面支持多轮对话前端生成唯一sessionId标识会话支持连续提问、保留对话记忆、展示计费信息!DOCTYPEhtmlhtmllangzh-CNheadmetacharsetUTF-8titleAI上下文连续对话Token计费/title/headbodydivinputtypetextidpromptplaceholder请输入提问内容stylewidth:500px;height:40px;buttononclickstartChat()styleheight:40px;发送提问/buttonbuttononclickclearChat()styleheight:40px;清空对话/button/divdividresultstylewhite-space:pre-wrap;margin-top:20px;line-height:1.8;/divscript// 生成唯一会话ID全局唯一保证对话记忆letsessionIdlocalStorage.getItem(ai_session_id)||UUID.randomUUID();localStorage.setItem(ai_session_id,sessionId);letsourcenull;// 发起流式对话functionstartChat(){letpromptdocument.getElementById(prompt).value;if(!prompt)return;document.getElementById(result).innerHTML【用户】prompt\n【AI】;// 关闭上一次连接if(source)source.close();// 建立SSE连接sourcenewEventSource(http://localhost:8080/ai/chat/context/stream?sessionId${sessionId}prompt${prompt});source.onmessagefunction(e){document.getElementById(result).innerHTMLe.data;}}// 清空对话上下文functionclearChat(){fetch(http://localhost:8080/ai/chat/clear?sessionId${sessionId})document.getElementById(result).innerHTML;}// 生成UUIDfunctionUUID(){returnxxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx.replace(/[xy]/g,function(c){letrMath.random()*16|0,vcx?r:(r0x3|0x8);returnv.toString(16);});}/script/body/html九、生产级优化用户额度限流管控商用产品必须防止恶意刷量、控制AI成本新增用户每日Token额度限制极简改造即可实现/** * 每日用户额度校验简单商用限流 */publicbooleancheckUserQuota(StringuserId){StringquotaKeyai:quota:daily:userId;// 每日最大免费Token10000intmaxQuota10000;IntegeruserUseTokenInteger.valueOf(stringRedisTemplate.opsForValue().get(quotaKey)null?0:stringRedisTemplate.opsForValue().get(quotaKey));if(userUseTokenmaxQuota){returnfalse;}// 累加已用额度stringRedisTemplate.opsForValue().increment(quotaKey,tokenBill.getTotalToken());// 设置每日过期stringRedisTemplate.expire(quotaKey,1,TimeUnit.DAYS);returntrue;}十、生产高频坑点解决方案坑1上下文无限累加Token越来越大解决限制最大历史对话轮数本文限制10轮自动截断早期对话控制Token大小。坑2Token统计误差过大解决采用中英文差异化换算规则贴合大模型官方计费标准商用误差可忽略。坑3会话长期占用内存/Redis空间解决设置会话30分钟无操作自动过期自动清理无效会话数据。坑4多轮对话顺序混乱解决严格按照 user提问 → assistant回复 顺序存入上下文保证对话时序正确。坑5SSE重复连接、内存泄漏解决每次新对话关闭上一次SSE连接finally强制释放资源。十一、商用拓展功能清单精准计费单价配置配置输入/输出Token单价自动计算对话金额用户充值体系结合用户余额实现扣费、欠费拦截对话日志入库保存每轮对话内容、Token消耗、用户信息、耗时敏感词过滤提问回复双向风控合规落地断线重连网络波动自动重连SSE接续剩余内容推送十二、总结本文在基础SSE流式问答的前提下完成了AI产品从可用到商用的核心升级解决了行业两大核心痛点对话无记忆、无计费统计。整套方案具备以下商用价值轻量高效基于SSERedis无需复杂中间件成本可控精准Token统计额度限流杜绝成本浪费体验优质多轮连续对话贴合主流AI产品交互逻辑落地简单零架构重构代码直接上线目前绝大多数付费AI问答、AI客服、企业级AI助手均采用这套流式对话上下文记忆Token计费架构。
延伸阅读

更多相关文章

2026/9/4 9:20:08

如何快速解锁Wallpaper Engine壁纸资源:RePKG终极提取指南

如何快速解锁Wallpaper Engine壁纸资源:RePKG终极提取指南 【免费下载链接】repkg Wallpaper engine PKG extractor/TEX to image converter 项目地址: https://gitcode.com/gh_mirrors/re/repkg 你是否曾经在Wallpaper Engine中看到精美的动态壁纸&#xff…

2026/9/13 16:14:35

如何快速掌握安卓自动化:高效游戏辅助框架完整指南

如何快速掌握安卓自动化:高效游戏辅助框架完整指南 【免费下载链接】RobotHelper 安卓游戏自动化脚本框架|Automated script for Android games 项目地址: https://gitcode.com/gh_mirrors/ro/RobotHelper RobotHelper是一个专为安卓游戏自动化设计的脚本框架…

2026/9/9 16:27:07

BERT、GPT、T5三大预训练模型核心原理与实战选型指南

1. 项目概述:从“傻傻分不清”到精准选型刚接触预训练模型那会儿,我经常被BERT、GPT、T5这些名字绕得晕头转向。项目来了,老板问“用哪个模型合适?”,心里没底,只能跟着感觉走,或者看哪个名字更…

2026/9/14 11:54:31

如何用 NeMo MarbleNet 完成语音活动检测(VAD)推理

如何用 NeMo MarbleNet 完成语音活动检测(VAD)推理 【免费下载链接】Speech A scalable generative AI framework built for researchers and developers working on Large Language Models, Multimodal, and Speech AI (Automatic Speech Recognition a…

2026/9/14 11:54:31

Agent Suite办公智能体落地指南:多智能体编排与工作流实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/14 11:54:31

SSM+JSP网上招投标系统实战:事务控制与多角色协同设计

简介:这是一套面向计算机专业本科生的Java毕业设计实战项目,基于SSM(SpringSpringMVCMyBatis)框架与JSP/HTML前端技术开发的网上招投标系统,适用于毕业设计、课程设计及期末大作业场景,代码含详细注释&…

2026/9/14 2:17:50

拯救者Y7000黑屏故障排查与维修实战指南

1. 项目概述:一台黑屏的拯救者Y7000,到底卡在哪一步? 联想拯救者Y7000系列笔记本,从2018年第一代搭载i5-8300H开始,到后来的i7-9750H、i7-10750H、i5-11400H,再到2023年款的R7-7840HS,它始终是学…

2026/9/14 0:03:22

KCF目标跟踪算法与OTB工程实现:毕业设计实战解析

简介:这是一份基于KCF核相关滤波算法、融合尺度池与抗遮挡处理的目标检测跟踪MATLAB完整源码,主要面向计算机相关专业准备毕业设计、课程设计或期末大作业的学生,也适合需要项目实战练习的初学者。源码在OTB数据集上完成验证,能够…

2026/9/14 0:03:22

语音情感识别实战:Keras实现LSTM、CNN、SVM与MLP多模型对比

简介:面向语音情感识别入门与进阶开发者,这份基于Keras的项目源码完整实现了LSTM、CNN、SVM、MLP四种模型,兼容Python3.8与Keras/TensorFlow2环境。压缩包内含49个文件,大小约70.31MB,主体包括Python脚本、yaml/json配…

2026/9/12 6:29:36

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/12 14:32:17

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/14 11:22:57

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码