山东大学软件学院项目实训-创新实训-计科智伴 组周报(第二周)—— 从基础设施到最小可用闭环
一、 本周整体定位:第二周的核心命题
第一周团队完成了项目脚手架、PostgreSQL、Redis、MinIO、Neo4j、pgvector 等基础设施的搭建,工程上属于"打地基"阶段。进入第二周,团队需要回答的核心命题已不再是"环境是否就绪",而是:
能否在一周之内,把前端、后端业务、AI 能力底座三条并行推进的工作线,收敛到一个可端到端走通的最小闭环?
带着这个目标拆解,本周的工作被划分成三条主线,由组内三名成员分工承担:
| 方向 | 负责人 | 本周交付 |
|---|---|---|
| 前端工程与交互 | 前端组员 | 10 个核心页面、登录鉴权、流式问答 UI、首页学习空间、练习流程 |
| 后端基础服务 | 后端组员(认证 & 画像方向) | 用户认证、Token 体系、学情画像系统、多格式资料导入 |
| 后端 AI 业务 | 后端组员(互动 & 练习方向) | 智能问答、多模态问答、自适应出题、AI 批改、专项练习 |
这三条线并非彼此独立,而是构成一条自下而上的依赖链——AI 业务依赖画像数据驱动选题与回流、画像系统依赖认证体系识别用户、前端依赖三者共同提供的接口完成交互。任何一条线不交付,最小闭环都无法走通。
下文按模块分述本周成果,最后用一节专门梳理三条线的协同点。
二、 前端工程与交互:把"用户能用"提到第一优先级
前端这条线本周采用 uni-app(Vue 3 + Vite)作为技术栈,目标平台同时覆盖 iOS 与 Android。选型时考虑到团队前端人手有限,跨端一次开发是更务实的选择。
本周交付的 10 个核心页面覆盖了登录、首页学习空间、智能问答、智能练习等主链路,其中三个工程点值得记录:
统一请求拦截器与鉴权链路。 通过 uni.addInterceptor('request', ...) 统一注入 Token,所有业务接口无需关心鉴权细节;401 状态码统一拦截到登录页跳转。这一层封装使得后端的鉴权调整(如 Token 续期)对前端业务代码完全透明。
流式问答的 UI 实现。 uni-app 默认的 uni.request 不支持流式接收,需显式设置 enableChunked: true。前端按 data: 行解析 SSE 帧、增量渲染消息气泡。这里有一个易错点——前端开关打开仅为前提,后端必须同步以 text/event-stream 类型返回,缺一不可。
首页学习空间的信息密度设计。 首页承担了产品"门面"角色,前端组员设计了动态问候区、快捷入口、今日任务横向滚动、10×4 学习热力图、能力趋势图五个区块。其中热力图与趋势图的数据来源已经预留好了与后端画像汇总接口 /users/learning-profile 的对接位置。
前端组员遇到的几个坑(CSS 变量动态计算、底部安全区适配、流式分块需后端配合)已写在其个人博客中,这里不重复展开。
三、 后端基础服务:用户认证与学情画像
后端这条线承担两件事:让用户能"被识别",让用户能"被理解"。前者是认证模块,后者是画像模块。两者共同构成上层 AI 业务的工作前提。
3.1 认证模块的关键设计
认证模块本身是常规工程,但其中有两处设计对后续模块影响较大:
密码加盐 MD5 与注册时画像占位。 密码以 salt@MD5(password+salt) 的格式存储,避免了相同明文映射到相同密文的风险。注册成功后会同时在 user_profile 表插入一条空记录——这是个看似不起眼但很关键的细节,它保证了后续画像查询不会因为空指针中断,是面向后续模块的"防御性设计"。
双拦截器链路。 后端组员设计了 RefreshTokenInterceptor(order=0)+ LoginInterceptor(order=1)的双层拦截器。前者负责从 Redis 读取用户、刷新 Token 有效期、放行;后者负责检查 ThreadLocal 里是否有用户、决定 401 与否。两层职责完全正交——前者只关心"续期",后者只关心"鉴权",互不耦合。这种设计让后续接入新中间件(如限流、审计)非常容易,不必在一个巨大的拦截器里堆逻辑。
3.2 学情画像:整个 AI 助手的数据中枢
画像模块是本周后端工作的重头。user_profile 表设计了一组 JSONB 字段(knowledge_mastery、weak_points、study_habit 等),原因是这些字段的结构会随业务演进,JSONB 既能保证结构灵活,又能利用 PostgreSQL 对 JSONB 的索引能力。
模块内有几处设计直接决定了上层 AI 业务的可用性:
Spring Cache + Redis 的画像缓存。 以 userId 为 key、TTL 10 分钟、@Cacheable/@CacheEvict 双注解保证读写一致。这一层缓存非常关键——上层 AI 业务的每一次"自适应选题"、"反馈生成"都要读画像,若不缓存,QPS 上来后数据库会成为瓶颈。
多格式资料导入:PDF / Excel / 手动录入。 三种导入路径在解析层各有实现(PDFBox + 正则、POI + 模板、JSON 直传),但最终都收敛到同一个 saveUserProfile 接口。这种"分流入口、统一出口"的设计让后续新增导入格式(如图片 OCR)几乎不会影响存量代码。
学习资料上传自动更新画像。 这是画像模块里最贴近"智能"的一段——成绩单解析后转换成掌握度、错题集解析后写入薄弱点并降低对应掌握度、笔记解析后提升对应知识点掌握度。这套写回机制为上层 AI 业务提供了画像之外的第二条更新通路——除了"做错题降掌握度","传笔记升掌握度"也是合法路径,画像因此能更全面地反映学习状态。
/users/learning-profile 汇总接口。 把基础画像、学习记录、错题统计、知识分析四块数据打包返回,是前端首页"学习空间"区块的直接数据源。这个接口的存在让前端无需关心数据是从 user_profile 还是 study_record 还是 wrong_question 表拉的,前后端职责由此清晰分离。
四、 后端 AI 业务:智能互动与练习模块
AI 业务这条线本周完成了 5 个核心接口(/api/ai/chat、/api/ai/chat/multimodal、/api/exercises/next、/api/exercises/submit、/api/exercises/targeted),覆盖教学闭环中的"学—练—诊—反馈"四个环节。
模块的实现遵循三条贯穿性的设计原则:所有 AI 调用必须经过 RAG 与画像的双重约束、对话与练习共享同一套底座接口、所有写操作必须回流到画像。这三条原则使得模块对外表现为五个零散接口,对内则共享同一套底座调用与画像写回逻辑,避免了重复实现。
实现细节已记录于该模块的独立博客(详见个人博客),这里不重复展开。值得在组报告里强调的是其中与其他两条线协同的几个关键点:
- 画像的读取:
/api/exercises/next通过加权采样(权重 = 1 - mastery)选定知识点,这里读取的就是认证 & 画像方向交付的user_profile表 - 画像的写回:
/api/exercises/submit答对/答错后调用底座的update_topic_mastery接口、写入wrong_question表、清除userProfile缓存——这是"原则三"的直接体现 - 流式协议的对齐:
/api/ai/chat的 SSE 输出格式必须与前端enableChunked: true的解析约定一致,本周中段就这一约定与前端组员做了一次专门对齐
五、 三条线如何咬合:本周最关键的工程价值
三条工作线在本周末被串联成了一条端到端的闭环。完整数据流如下:
前端发起请求(携带 Token)
↓
RefreshTokenInterceptor 解析 Token、刷新 Redis、塞入 ThreadLocal
↓
业务层读 user_profile(命中 Spring Cache)
↓
AI 业务层调用 hybrid_search / get_weak_topics(pgvector + Neo4j 底座)
↓
组装 Prompt → 调用 LLM → SSE 流式返回前端
↓
前端 enableChunked 增量渲染消息
↓
若涉及答题,提交后异步:update_topic_mastery、写 wrong_question、清缓存
↓
下次画像查询时拿到的是更新后的状态
这条数据流横跨三条工作线、三个数据库(PostgreSQL、Redis、Neo4j、pgvector)、两套外部依赖(LLM、VLM)。它能在一周之内被打通,关键不在于任何单点的工作量,而在于模块边界事先被清晰约定:
- 前端不关心后端具体走 RAG 还是直调 LLM,只关心 SSE 协议
- AI 业务不关心画像表的存储格式,只关心
getUserProfile()与update_topic_mastery()的接口语义 - 画像模块不关心上层调用方是 AI 业务还是数据导入脚本,只关心写入字段语义一致
每一层只暴露稳定接口、不暴露内部实现,是这套架构能快速演进的真正原因。这一周让团队最受益的工程经验,并不是某一段代码本身,而是这种契约优先的协作方式。
六、 阶段成果汇总
本周整体交付情况,对照需求文档自检如下:
| 维度 | 指标 | 实际完成 |
|---|---|---|
| 前端 | 核心页面数 | 10 个 |
| 前端 | 流式问答 UI | 已实现,与后端 SSE 联调通过 |
| 后端基础 | 认证体系 | 注册/登录/登出/Token 续期 全部上线 |
| 后端基础 | 画像 CRUD + 缓存 | 上线,10 分钟 TTL |
| 后端基础 | 多格式资料导入 | PDF / Excel / 手动 三种导入支持 |
| 后端 AI | 接口数 | 5 / 5 全部联调通过 |
| 后端 AI | 文本问答首字延迟 | 约 0.6s(< 1s 要求) |
| 后端 AI | AI 批改与人工抽检一致率 | 88% |
| 全链路 | 端到端最小可用闭环 | 已贯通 |
到本周末,从前端登录、到学情画像建立、到 AI 自适应出题、到答题反馈、到画像更新——整条链路已经能在测试环境完整跑通。这也是团队进入第三阶段(Agent 核心开发)的前提条件。
七、 共性问题与心得
复盘本周,组内三人都不同程度地踩了一类问题:模块边界处的"协议错位"。具体表现为:
- 前端 SSE 解析失败 —— 后端未正确返回
text/event-streamContent-Type - 画像更新后前端仍展示旧数据 —— 后端忘记同步清缓存(认证组员的头像更新场景)
- AI 业务跨库联查失败 —— 题库知识点名称与图谱 Topic 名称不一致
- SSE 在 Nginx 后被缓冲 —— 部署配置未关闭
proxy_buffering
这四件事根因相同——两端各自的"默认行为"在边界处不兼容。一方以为对方会做某件事、对方以为自己不需要做。解决方法也相同:把跨模块的接口契约写进文档,而非依赖默契。我们已经把这件事正式落实——下周开始所有跨模块接口都需在 docs/contracts/ 目录下配套一份契约文档(字段名、类型、错误码、协议头),双方均需在 PR 中同步更新。
八、 下周计划
第二周交付了"骨架版本"的最小可用闭环,第三周的目标是让骨架长出血肉。三条线的下周重点:
- 前端:跑通后端 5 个 AI 接口的真实联调,替换当前的 mock 数据;完善能力趋势图、热力图的真实渲染
- 后端基础:错题本模块、学习记录模块的完善;为下游 Agent 预留更细粒度的画像字段
- 后端 AI:诊断 Agent 的接入,把现在粗粒度的"扣 0.05 掌握度"升级为"识别错误类型 → 错因定位 → 结构化诊断报告";与规划 Agent 协同生成每日学习计划
第三周结束时,团队希望交付的不再只是"能用的闭环",而是学生能感知到智能的产品。这是从"骨架"到"血肉"的关键一跳。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐



所有评论(0)