资讯动态

基于SpringBoot+Vue的AI课程社区平台:智能推荐、对话与情感分析全栈实战

发布时间:2026/10/20 17:28:26 来源:尧图企业网站定制
1. 项目缘起与整体设计思路1.1 这个平台到底要解决什么问题在线课程社区这几年积累了大量用户行为数据但绝大多数平台的内容分发还停留在最新发布或人工置顶的阶段。一个学员打开社区首页看到的往往是三天前别人发的帖子跟自己当前学习进度毫无关系想找一门课的配套讨论得靠搜索框反复试关键词评论区里有人写了长篇反馈运营同学要一条条读完才知道大家到底满意还是不满意。这些问题的本质是数据在产生但没有被用起来。这个项目的核心目标就是给课程社区装上一套会思考的引擎。具体来说它要同时干三件事第一根据用户的历史行为浏览、收藏、评论、完课进度自动推荐可能感兴趣的课程和帖子第二提供一个能理解上下文、能结合课程知识库回答问题的AI对话入口第三对社区评论做情感倾向分析把好评、差评、中性自动分出来让运营和讲师能一眼看到反馈分布。适合谁来参考这套方案我认为有三类人一是正在做毕业设计或课程设计的学生需要一个功能完整、技术栈主流的全栈项目二是中小型在线教育团队的技术负责人想低成本验证AI社区的可行性三是对前后端分离、AI能力集成感兴趣想找一个综合练手项目的开发者。整套方案基于 SpringBoot Vue.js 的前后端分离架构AI部分通过调用大模型接口实现不依赖本地训练大模型部署门槛相对可控。1.2 为什么选这套技术组合技术选型这件事我的原则一直是够用、好维护、社区活跃。SpringBoot 做后端最大的好处是生态成熟整合 MyBatis、Redis、定时任务、消息队列都有现成的 starter写业务逻辑的时间远多于配置时间。Vue.js 做前端组件化开发配合 Element Plus 这类 UI 库能快速搭出管理后台和用户端两套界面而且前后端通过 JSON 交互职责边界清晰前端同学不用等后端接口全部完成就能用 mock 数据先跑起来。AI 能力这块我没有选择自己训练模型原因很直接课程社区的语料规模通常撑不起一个效果好的推荐模型而情感分析和对话理解用通用大模型接口就能达到可用水平。推荐模块采用协同过滤 内容特征的混合策略情感分析走大模型接口对话聊天则结合课程知识库做检索增强。这样做的代价是有接口调用成本但换来的是开发周期从几个月压缩到几周对中小团队来说这笔账是划算的。前后端分离还有一个容易被忽略的好处可视化数据分析模块可以独立演进。运营想看的数据维度经常变如果前后端耦合改一个图表就要动后端代码分离之后后端只管把聚合好的数据以接口形式吐出来前端用 ECharts 想怎么画就怎么画。1.3 整体架构分层整个系统我习惯分成四层来看这样排查问题时能快速定位是哪一层出了状况层级主要职责关键技术接入层请求路由、鉴权、限流Nginx、JWT应用层业务逻辑、AI能力编排SpringBoot、Service数据层结构化数据、缓存、向量检索MySQL、Redis、向量库展示层页面渲染、图表、交互Vue.js、ECharts接入层用 Nginx 做反向代理同时承担静态资源分发和接口转发。应用层是核心AI 推荐、AI 对话、情感分析三个能力都封装成独立的 Service通过统一的 AI 网关去调用外部接口这样以后换模型供应商只需要改网关配置。数据层里 MySQL 存用户、课程、评论等业务数据Redis 缓存热点推荐结果和会话上下文向量库用来存课程内容的向量表示支撑语义检索。展示层就是 Vue 应用用户端和管理端分开打包部署。提示把 AI 调用统一收口到一个网关 Service是这套架构里我最推荐的一个设计。很多项目把大模型调用散落在各个业务代码里后期换 key、加限流、做降级时非常痛苦。2. 核心功能模块的细节拆解2.1 AI智能推荐混合策略怎么落地推荐模块是整个平台最考验设计的地方。纯协同过滤有个经典冷启动问题新用户没有行为数据新课程没有交互记录算法直接失灵。我的做法是分三段处理。第一段是召回。对老用户用基于物品的协同过滤找出和他历史交互过的课程相似的课程集合对新用户用内容特征召回根据注册时选择的兴趣标签、当前学习中的课程分类匹配同类别的高分课程。召回阶段的目标是广撒网宁可多召回一些也不要漏掉潜在感兴趣的内容。第二段是排序。召回出来的候选集可能有几百条需要用一个打分函数排序。我的打分公式大致是这样的score w1 * 协同过滤得分 w2 * 内容相似度 w3 * 课程热度 w4 * 时效衰减因子其中权重 w1 到 w4 不是拍脑袋定的而是先用历史数据做离线评估看哪组权重下点击率最高。实测下来对于行为数据丰富的老用户w1 可以给到 0.5 左右对新用户w1 直接置零把权重让给 w2 和 w3。时效衰减因子用指数衰减比如exp(-λ * 天数)λ 取 0.05 左右意味着两周前的热门内容权重会明显下降。第三段是重排。排序结果里如果连续出现同一讲师的课程要做打散处理避免推荐列表看起来太单调。同时要过滤掉用户已经完课的课程这个逻辑看似简单但很多项目会漏掉导致用户反复看到已经学完的内容。2.2 AI会话聊天检索增强是关键直接让大模型回答这门课第三章讲了什么它大概率会编。因为通用模型并不知道你平台上具体课程的内容。解决办法是检索增强生成RAG用户提问时先把问题转成向量去向量库里检索最相关的课程内容片段把这些片段作为上下文拼进提示词再让模型基于这些真实内容回答。具体流程是这样的课程上架时把课程简介、章节大纲、讲义文本切分成 500 字左右的片段每个片段调用 embedding 接口转成向量存入向量库。用户提问时同样把问题转成向量做相似度检索取 Top 3 到 Top 5 的片段。拼提示词的时候要明确告诉模型只根据以下资料回答资料中没有的信息就说不知道这句话能大幅降低胡编的概率。会话上下文的管理也有讲究。多轮对话时不能把全部历史都塞进去那样 token 消耗会爆炸。我的做法是保留最近 5 轮对话更早的对话做摘要压缩。Redis 里存会话状态key 用chat:session:{userId}:{sessionId}设置 30 分钟过期用户长时间不操作就自动清理。2.3 AI评论情感分析批量与实时结合评论情感分析看起来简单实际做起来要考虑成本和时效的平衡。如果每条评论发布时都同步调用一次大模型接口高峰期接口延迟会拖慢整个发布流程。我的方案是异步批量处理评论先入库状态标记为待分析然后由一个定时任务每 5 分钟捞一批比如 50 条批量送去做情感分析分析完回写结果。情感标签我分了三类正面、中性、负面。但光有标签不够运营真正想看的是负面评论集中在哪些课程最近一周负面比例有没有上升。所以分析结果除了标签还要提取关键词比如从老师讲得太快跟不上里提取出节奏快这个标签。这些关键词聚合起来就能形成课程改进的线索。批量处理时要注意接口的并发限制。我一般用线程池控制并发数在 5 到 10 之间太高容易触发限流太低又慢。失败的要进重试队列重试三次还失败就标记为分析失败人工介入。2.4 可视化数据分析让数据说话数据分析模块的价值在于把散落的行为数据变成决策依据。我设计了几个核心看板课程热度趋势、用户活跃度分布、评论情感占比、推荐点击转化率。每个看板背后都是一个聚合查询为了不影响主库性能聚合查询走的是定时任务预计算结果存到一张统计表里前端直接读统计表。ECharts 的配置有几个坑要提醒。折线图展示趋势时如果数据点太多比如按天统计一年的数据要做采样或者按周聚合否则图会糊成一团。饼图展示情感占比时颜色要用语义化的正面用绿色系、负面用红色系别用默认配色不然运营一眼看不出重点。3. 实操过程与核心环节实现3.1 后端项目骨架搭建先建 SpringBoot 工程依赖这块我列一下核心的dependencies dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-web/artifactId /dependency dependency groupIdorg.springframework.boot/groupId artifactIdspring-boot-starter-data-redis/artifactId /dependency dependency groupIdcom.baomidou/groupId artifactIdmybatis-plus-boot-starter/artifactId version3.5.3/version /dependency dependency groupIdio.jsonwebtoken/groupId artifactIdjjwt/artifactId version0.9.1/version /dependency /dependencies包结构按controller / service / mapper / entity / config / ai来分。ai包单独放 AI 网关和三个能力的实现类跟业务代码隔离开。配置文件里把大模型接口的地址、密钥、超时时间都放到application.yml用ConfigurationProperties读取别硬编码在代码里。数据库表设计上除了常规的用户表、课程表、评论表我额外加了两张user_behavior记录用户行为流水行为类型、目标ID、时间戳recommend_result存推荐结果快照。行为流水是推荐的燃料推荐快照是为了做效果对比——今天推的和昨天推的哪个点击率高得有数据才能评估。3.2 推荐服务的核心代码推荐服务的入口方法大概长这样public ListCourseVO recommend(Long userId, int size) { // 1. 判断新老用户 int behaviorCount behaviorMapper.countByUser(userId); ListLong candidates; if (behaviorCount 5) { // 新用户走内容召回 candidates contentRecall(userId); } else { // 老用户走协同过滤召回 candidates cfRecall(userId); } // 2. 打分排序 ListScoredCourse scored candidates.stream() .map(id - new ScoredCourse(id, score(id, userId))) .sorted(Comparator.comparingDouble(ScoredCourse::getScore).reversed()) .collect(Collectors.toList()); // 3. 打散与过滤 return rerank(scored, userId, size); }score方法里就是前面说的加权公式。这里有个实操细节协同过滤的相似度矩阵不要每次请求都算那样性能扛不住。我的做法是离线任务每天凌晨算一次物品相似度矩阵存到 Redis 里线上请求直接查。内容相似度因为课程特征变化不频繁也是离线算好。注意新老用户的阈值我这里设的 5 次行为不是固定的要根据平台实际数据量调整。数据稀疏的平台可以调到 3数据丰富的可以调到 10。这个值最好通过 A/B 测试来确定。3.3 AI对话接口的对接对话接口的调用封装在AiGateway里核心是拼提示词和解析响应public String chat(String question, Long courseId) { // 1. 检索相关课程内容 ListString contexts vectorSearch(question, courseId, 5); // 2. 拼提示词 String prompt buildPrompt(question, contexts); // 3. 调用模型接口 String answer callModel(prompt); // 4. 记录会话 saveSession(question, answer); return answer; }buildPrompt里我会明确写清楚角色和约束比如你是一个课程助教只根据提供的资料回答问题资料中没有的内容要明确说明无法回答。这句话看着简单但实测能显著减少模型自由发挥。vectorSearch用的是余弦相似度返回的片段要按相似度排序取前几个。调用模型接口时要设置合理的超时时间我一般设 30 秒超时就走降级逻辑返回当前咨询人数较多请稍后再试。降级不是丢人的事是保证系统可用的必要手段。3.4 情感分析的异步任务情感分析的定时任务用 Spring 的Scheduled实现Scheduled(fixedDelay 300000) public void analyzeComments() { ListComment pending commentMapper.selectPending(50); if (pending.isEmpty()) return; // 批量构造请求 ListString texts pending.stream() .map(Comment::getContent).collect(Collectors.toList()); ListSentimentResult results aiGateway.batchSentiment(texts); // 回写结果 for (int i 0; i pending.size(); i) { commentMapper.updateSentiment(pending.get(i).getId(), results.get(i)); } }批量接口比单条调用效率高很多50 条一次请求token 消耗和延迟都更优。但要注意单次请求的文本总长度别超过模型限制超了要分批。回写时用批量更新别在循环里一条条 update那样数据库压力大。3.5 前端页面的关键实现前端用 Vue3 Vite 搭建路由分用户端和管理端。推荐列表页用无限滚动加载每次请求 10 条滚到底部再请求下一页。这里有个体验细节加载时要有骨架屏别让用户看着空白页面等。ECharts 图表的封装我建议做成一个通用组件传入配置项和数据就能渲染。这样不同看板复用同一个组件改样式只改一处。图表数据请求要加 loading 状态数据没回来时显示加载动画避免图表区域闪烁。前后端联调时跨域问题用 Vite 的 proxy 配置解决开发环境代理到后端端口生产环境用 Nginx 转发。别在代码里写死后端地址用环境变量区分。4. 常见问题与排查技巧实录4.1 推荐结果不更新怎么办这是最常见的问题。用户明明刚看了几门新课推荐列表还是老样子。排查思路是这样的先看行为流水有没有写进去user_behavior表里有没有最新记录再看推荐结果是不是走了缓存如果 Redis 里缓存了推荐结果且没设过期时间那自然不会更新。我的做法是推荐结果缓存 10 分钟过期同时用户产生关键行为完课、收藏时主动清除该用户的推荐缓存。还有一种情况是离线相似度矩阵没更新。如果矩阵是每天凌晨算一次那白天的行为不会立即影响相似度。这个要跟产品说清楚推荐不是实时的有延迟是正常的。4.2 AI接口调用超时或报错大模型接口不稳定是常态必须做好容错。我总结了几个处理策略问题现象可能原因处理方式偶发超时接口波动重试1次仍失败则降级持续超时网络或服务异常熔断走本地兜底逻辑返回内容为空提示词问题检查提示词加兜底话术触发限流并发过高降低线程池并发数熔断我用的 Resilience4j配置简单跟 SpringBoot 集成也顺。熔断打开后对话功能返回预设话术推荐功能退回热门榜单保证核心流程不中断。4.3 情感分析准确率不理想情感分析不准八成是提示词没写好。我踩过的坑是一开始只让模型输出正面/负面结果遇到反讽的评论讲得真好我睡了三觉就判断成正面。后来改成让模型输出标签加理由比如负面因为用户表达了不满准确率明显提升。另外领域词汇要补充比如水课干货这类社区黑话通用模型可能理解偏差可以在提示词里给几个例子。4.4 数据量大了之后查询变慢评论表和用户行为表是最容易膨胀的。我的经验是行为表按月分表历史数据归档评论表的查询加联合索引course_id create_time这种组合索引能覆盖大部分查询场景。统计类查询全部走预计算别让前端直接查明细表做聚合那样数据量一上来必卡。提示分表这件事要提前规划别等表到千万级了才动手那时候迁移成本很高。我一般建议行为表超过 500 万行就考虑分表。4.5 前后端联调的典型坑跨域问题前面说了用 proxy 解决。另一个坑是时间格式后端返回的时间戳前端要统一处理别一个页面显示时间戳一个页面显示格式化字符串。还有分页参数前后端要约定好是pageNum/pageSize还是offset/limit不统一的话每个接口都要转换很烦。接口返回结构也要统一我一般用{code, message, data}三段式前端拦截器统一处理 code 非 0 的情况弹出错误提示。这样业务代码里就不用每个请求都判断成功了。5. 部署与性能优化的一些经验5.1 部署架构与资源配置部署我推荐用 Docker Compose 编排把 MySQL、Redis、后端、前端、Nginx 都写进一个 compose 文件一键启动。资源分配上后端服务给 2 核 4G 起步MySQL 给 2 核 4GRedis 给 1 核 2G。如果 AI 调用量大后端可以水平扩展多个实例前面用 Nginx 做负载均衡。前端打包后是静态文件直接扔 Nginx 里。Nginx 配置里要注意 gzip 压缩开启不然 JS 文件传输慢。接口转发要设置合理的超时时间AI 相关接口超时设长一点普通接口设短一点。5.2 缓存策略的设计缓存用得好数据库压力能降一个数量级。我的缓存分层是这样的课程详情、用户信息这类读多写少的数据缓存 30 分钟推荐结果缓存 10 分钟会话上下文缓存 30 分钟。缓存更新策略用更新数据库时删除缓存而不是更新缓存这样能避免并发写导致的脏数据。缓存穿透也要防查询不存在的 key 时缓存一个空值并设短过期时间避免每次都打到数据库。缓存雪崩的话给不同 key 的过期时间加随机偏移别让它们同时失效。5.3 接口性能优化接口响应慢先定位是慢在数据库还是慢在 AI 调用。数据库慢就加索引、优化 SQLAI 调用慢就考虑异步化能异步的绝不同步等。比如评论情感分析就是异步的用户发完评论立即返回成功分析在后台跑。分页查询要避免深分页limit 100000, 10这种写法在数据量大时极慢。优化方式是记录上次查询的最大 ID用where id lastId limit 10来翻页。6. 这套方案还能怎么扩展6.1 推荐算法的进阶方向现在的混合推荐还是偏传统的后续可以引入深度学习模型比如用双塔模型做召回用排序模型做精排。但要注意模型越复杂维护成本越高小团队要权衡投入产出。另一个方向是实时推荐用 Flink 这类流处理框架消费行为数据做到秒级更新推荐结果适合对时效性要求高的场景。6.2 对话能力的增强现在的对话是基于课程知识库的后续可以接入更多数据源比如用户的错题记录、学习进度让对话更个性化。还可以做多轮任务型对话比如用户说帮我找一门讲 Python 爬虫的课系统能理解意图并直接返回课程卡片而不只是文字回答。6.3 数据分析的深化现在的看板还是描述性的展示发生了什么。后续可以做诊断性分析比如为什么这门课最近差评变多了通过关联分析找出可能原因。再进一步是预测性分析预测课程热度趋势帮助运营提前准备。我个人在实际操作中的体会是这套平台的技术难点不在单个模块而在模块之间的协同。推荐要用到行为数据行为数据来自用户交互交互体验又受推荐质量影响这是个循环。所以做的时候别想着一次把每个模块都做到完美先把闭环跑通再逐个优化。我见过太多项目卡在推荐算法不够好上结果整个平台迟迟上不了线其实先用简单策略跑起来有了真实数据再迭代效果反而更好。最后分享一个小技巧AI 相关的功能一定要做开关。上线初期可以只对部分用户开放观察效果和成本没问题再全量。这样万一出问题影响面可控回滚也快。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑