摘要第四周末我们立下一句 flag——下周开始让它真正聪明起来。本周就来兑现。团队从让系统稳定跑、能用正式进入让 AI 深度嵌入学习闭环的阶段目标是把智能这层从能调通推进到调得准、调得狠。三位组员分别围绕①错题本与智能诊断 Agent、②course-ai 后端线接通真实大模型 RAG 检索 多 Agent 调度、③登录 / 对话 / 密码重置的全链路前端接通展开。本周把用户做错题 → 诊断根因 → 更新画像 → 生成个性化计划 → 拆分任务这条 AI 学习闭环彻底打通同时让另一条后端线具备了真实大模型流式问答、知识库检索增强与意图调度的能力。一、本周整体定位从能稳定跑到真正聪明第四周已经把代码闭环、四层测试体系、前端体验三件事做稳能跑、能稳定跑、能让人用都已铺好。进入第五周团队的任务有三条主线三条线咬合在一起构成AI 真正参与学习的完整证据。第一把做错题变成学得到。落地错题本 智能诊断 Agent让每一次错误都被大模型分析根因、结构化回写画像并驱动 AI 重新生成学习计划与任务。这是第四周「下周计划」里诊断 Agent 与规划 Agent 正式接入的兑现。第二把另一条后端线 course-ai 从能编译、能跑推进到接真模型、能检索、会调度。接通 DashScope Qwen 的 SSE 流式问答、搭起 pgvector RAG 检索体系、再加一层多 Agent 意图调度让后端不只是会答而是先想清楚该让谁答、答的时候有没有据可依。第三把后端能力翻译成用户动作。把登录流程、流式对话渲染、密码重置三件套在 uniapp 前端真正接通让上面两条后端线的能力对用户可见、可用。本周交付如下方向负责人本周交付错题本 智能诊断 Agent AI 生成计划 / 任务本人错题本 5 接口、诊断 Agent异步 同步兜底 降级 重试、AiStudyPlanGenerator、AiTaskGenerator、画像掌握度按置信度衰减联动course-ai 后端线接通大模型 RAG 多 Agent 调度组员一195 个 Java 文件编译复活、SSE 真接 Qwen、14 个 endpoint 补齐、10 意图多 Agent 调度、pgvector DashScope 直连 RAG 闭环登录 / 对话 / 密码重置全链路前端接通组员二登录前置 画像感知跳转、fetchReadableStream解 SSE 打字机、密码重置三件套 ActionSheet、9 个notImplemented占位转真实路径下文按方向分述本周成果。二、错题本 智能诊断 Agent AI 生成计划 / 任务本人负责这是本周花时间最多的一块。诊断 Agent 涉及的逻辑比预想复杂——要调大模型、要解析 JSON、要更新画像、还要异步处理避免阻塞。核心是把用户做错题这个动作变成驱动整个自适应系统的数据源。2.1 错题本基础接口错题本模块对外提供 5 个 REST 接口代码在MistakeController接口方法功能/api/mistakesPOST添加错题触发异步诊断/api/mistakesGET错题列表分页可按知识点筛选/api/mistakes/{mistakeId}GET错题详情题目、正确答案、用户答案、诊断结果/api/mistakes/{mistakeId}/diagnosisGET诊断报告未诊断则同步触发一次/api/mistakes/weak-pointsGET薄弱知识点列表按错题数排序添加错题的关键设计是立即返回 后台异步诊断前端先展示诊断中再轮询详情拿结果不阻塞主流程PostMapping public Result addMistake(RequestBody MistakeAddRequest request) { Long userId UserHolder.getUser().getUserId(); WrongQuestion wrongQuestion new WrongQuestion(); wrongQuestion.setUserId(userId); wrongQuestion.setQId(request.getQId()); wrongQuestion.setUserAnswer(request.getUserAnswer()); wrongQuestionService.save(wrongQuestion); // 异步调用诊断 Agent添加错题后立即返回 diagnosisAgent.diagnoseAsync(wrongQuestion.getWqId(), userId, request.getQId(), request.getUserAnswer()); return Result.ok(Map.of(mistakeId, wrongQuestion.getWqId(), status, diagnosing)); }错题列表会从Question联查LearningResource取题干预览截前 50 字详情则返回完整题目、正确答案、解析、用户答案、知识点名称与诊断结果。2.2 智能诊断 Agent —— 本周的核心诊断 Agent 要做的事拿到一道错题用户答案、题目信息、知识点、用户画像调用大模型分析错误根因更新画像掌握度并记录诊断结果供前端展示。整体设计四点异步为主添加错题时走Async不阻塞主流程。同步兜底用户查诊断报告时若还没诊断完就同步触发一次diagnoseSync。降级机制大模型调用失败 / 超时自动降级为基于字符串相似度的规则诊断。重试机制大模型调用最多重试 3 次指数退避。提示词Prompt设计上给模型喂的不只是题面还包括所属知识点及 ID、从kp_relationship查到的前置知识点与易混淆知识点、用户当前对该知识点的掌握度、以及一张知识点 ID 映射表让模型返回具体 ID 而非名称。要求模型返回结构化 JSONerror_typeknowledge_gap / concept_confusion / logic_error / calculation_error / syntax_error、root_kp_id、explanation、confidence、suggested_actions。大模型调用与重试private String callModelWithRetry(String prompt) { for (int attempt 1; attempt 3; attempt) { try { return chatClient.prompt().user(prompt).call().content(); } catch (Exception e) { if (attempt 3) Thread.sleep((long) Math.pow(2, attempt - 1) * 1000); } } throw new RuntimeException(大模型调用失败); }诊断结果回来后updateUserProfileWithDiagnosis会把root_kp_id加入weakPoints并按置信度衰减掌握度——置信度越高扣得越狠但有 0.1 的下限保护double decayRate 0.05 * confidence; double newMastery Math.max(0.1, currentMastery * (1 - decayRate)); mastery.put(rootKpIdStr, newMastery);这样每次错题诊断都会让画像更精准地反映知识短板后续的计划与练习推荐也随之调整。若大模型不可用则降级到performRuleBasedDiagnosis按用户答案与标准答案的编辑距离判型相似度 0.8 → calculation_error 0.5 → concept_confusion否则 knowledge_gap保证 AI 挂了用户仍有基本反馈。2.3 AI 生成学习计划重构原来的计划生成是硬编码规则按薄弱点或目标分数定类型再固定分配 2 周 / 1 个月计划项简单遍历知识点。本周改成调大模型生成新增AiStudyPlanGenerator取用户画像年级、专业、目标分数、掌握度、薄弱点、学习习惯→ 构建提示词让模型分析每日可投入时长并产出 JSON 计划 → 解析后为每个计划项关联学习资源 → 按每日可用时长自动排日期 → 存study_plan表并失活旧计划。提示词里的硬约束包括计划类型WEAKNESS_FOCUS / TARGET_ORIENTED / COMPREHENSIVE由模型自行判断、每项预计学习时间不超过每天总时长的 60%、优先安排薄弱点并考虑前置依赖。2.4 AI 生成任务重构有了计划项还得拆成可执行任务。原来 1 个计划项对应 1 个任务太粗。本周写AiTaskGenerator让模型把每个计划项拆成 1~3 个具体任务学习 / 练习 / 复习每个任务含title/description/knowledgePoint/estimatedMinutes/practiceCount解析后补resourceId与taskDate再批量入库。于是学习 Java 多线程 60 分钟会被拆成看基础视频 25min 5 道选择题 20min 写一个生产者消费者示例 15min体验细腻很多。2.5 本周后端踩坑现象根因修复大模型返回 JSON 不纯带json代码块 / 注释模型输出习惯正则提取json包裹内容再取第一个{到最后一个}异步诊断里更新数据库不生效Async默认不在原事务中更新画像方法标Transactional(propagation REQUIRES_NEW)走独立事务高峰期大模型超时DashScope 并发限流3 次指数退避重试 最终失败降级规则诊断AI 生成计划的日期解析失败返回日期格式不一定是yyyy-MM-ddparseDateSafely失败用默认值JSON 清洗的核心两步Matcher matcher Pattern.compile((?:json)?\\s*([\\s\\S]*?)).matcher(cleaned); if (matcher.find()) cleaned matcher.group(1).trim(); int start cleaned.indexOf({); int end cleaned.lastIndexOf(}); jsonStr cleaned.substring(start, end 1);三、course-ai 后端线接通真实大模型 RAG 多 Agent 调度组员一负责与上面的主学习闭环并行组员一这周把另一条后端线course-aiSpring Boot 3.4 MyBatis-Plus Spring AI从刚接手时编译都过不去推进到接真模型、能检索、会调度。3.1 先让 195 个 Java 文件能编译首次mvn compile报出 130 个错误归类只有 5 个根因Lombok 硬编码1.18.22与 JDK 17 SB 3.4 不兼容和第四周 L1 撞上的JCTree$JCImport.qualid同源、BusinessException包从未创建、SubmitAnswerRequest整文件被注释、StudyPlanAIConfig的 Bean 重复 构造参数漂移、MinioService.uploadBytes未真迁入。最值钱的一刀是把 Lombok 的硬编码版本拿掉、交给 spring-boot-parent 统一管理为 1.18.3650 条找不到符号瞬间消失剩下 5 处真错误再各个击破。最终BUILD SUCCESS195 文件全量编译通过。经验是编译期问题先解决再谈别的——Lombok 失效让一大半错误都是假阳性。3.2 智能对话真接通 QwenSSE 流式后端早用 Spring AI 接通了 DashScope但前端还是setTimeout模拟。这周把后端 SSE 真正打通踩到一个字节级的坑坑 · SSE 规范要剥前导空格但 Spring 的输出不能剥接通后第一版输出变成HelloHello!Howcan...——词间空格全丢了。用od -c直查原始字节才确认Spring 把 token 原样拼在data:后面data: there里这个空格属于 token 本身。若按 SSE 规范strip one leading SPACE处理就会把所有词间空格吃掉。这和第四周排 SSE buffering 是一脉相承的经验不要按规范读要按字节读——Spring 这里就没按规范写。对策是不剥离、原样取raw.substring(5)。3.3 补齐 14 个后端 endpoint前端一堆notImplemented占位对应的后端路径压根不存在这周按模块一次性补齐 14 个错题状态 / 统计、练习 next / subjects / records、课程列表、对话 recommend / cancel / history、首页 home / heatmap / growth、报告 report、通知含新表 NotificationService.push()。顺带修了两个老 bugORDER BY RAND()MySQL 写法在 PG 报错改RANDOM()determineTargetDifficulty返回字符串而difficulty是 Integer永远查不到题——改成返回1/2/3。第二条和第四周 L4 抓出的kpName vs kpId是同一类毛病契约两端类型对不上接口看着 200数据却落不到点。3.4 多 Agent 智能调度项目里已有多个独立 agent / serviceTeachingAgent、AiChatService、MultimodalChatService、MistakeDiagnosisAgent、AiStudyPlanGenerator但全靠手动直接调用。这周在它们上面搭一层调度 Agent对用户原始输入做意图判别再路由POST /api/agent/dispatch → DispatcherAgent.classify() // 1) 强信号短路 → 2) LLM 分类 → 3) 兜底 → AgentOrchestrator.dispatch() ├── TeachingAgent.{generateExercises | gradeAnswer | ...} ├── AiChatService // CHAT ├── MultimodalChatService // MULTIMODAL_RECOGNITION ├── MistakeDiagnosisAgent // MISTAKE_DIAGNOSIS └── AiStudyPlanGenerator // STUDY_PLAN_GENERATE分类做成三段式以省钱省时强信号带hintIntent/attachmentUrls/extras.mistakeId直接短路命中、跳过 LLM~0ms否则把 10 种意图描述塞进 prompt 让 Qwen 输出{intent, confidence, reasoning, extractedParams}~800ms解析失败兜底走 CHAT。实测 8 条中英文混合 case 全过例如 give me 3 medium dynamic programming questions 命中EXERCISE_GENERATE并抽出{count:3, difficulty:2, knowledgePoint:dynamic programming}。3.5 RAG 检索体系数据源是data_crawler/crawl/cleaned/下 13 个已切好 chunks 的 JSON合计约 18,908 条数据结构 6042、算法 2832、操作系统 2402、数据库 2147 等。技术栈PostgreSQL pgvector欧氏距离-DashScopetext-embedding-v31024 维先取 topK × 3 召回再按 subject → course_id 过滤。三个非显然的坑坑一 · 维度错位表原是vector(768)v3 实际输出 1024 维。ALTER TYPE不支持趁 0 行窗口期DROP ADD COLUMN重建。坑二 · Spring AI 解不开 DashScope 响应OpenAiApi$EmbeddingList没标JsonIgnoreProperties而 DashScope 多返回一个顶层id字段触发UnrecognizedPropertyException。干脆自写 100 行 HTTP 客户端DashScopeEmbeddingClient绕开——三方 SDK 兼容性问题绕过比对抗便宜。坑三 · batch 上限是 10 不是 25实测超过 10 条返回batch size ... not be larger than 10把BATCH_SIZE改 10 即稳。导入器做了幂等chunk_id入source_id 唯一索引重跑 skip。验证从导入到回答导入github_database.json150 chunks后提问数据库事务的 ACID 分别指什么SSE 里先收到event:references带召回片段和 score再收到event:delta正文且 AI 开头明说结合了参考资料——RAG 真闭环。四、登录 / 对话 / 密码重置全链路前端接通组员二负责后端两条线在变强组员二这周把它们翻译成用户能直接操作的前端动作并在联调中协同定位了两个隐藏 bug。4.1 登录流程重构先登录、再画像、再首页把 App 启动落地页从 onboarding 问卷改成登录页注册做成顶部 Tab登录后调getProfile判断画像决定去向。判定逻辑放在前端只看目标分数或在学课程有任一即视为已建// login.vue isProfileBuilt(profile) { if (!profile) return false const hasTarget profile.targetScore ! null const hasCourses Array.isArray(profile.currentCourses) profile.currentCourses.length 0 return hasTarget || hasCourses }联调中暴露并与后端协同定位了两个坑其一浏览器跨域带authorization头会先发OPTIONS预检而LoginInterceptor没排除 OPTIONS预检返回 401浏览器视为失败真正的 GET/PUT 根本不发出——后端日志一片空白前端只见一个提交失败极难定位后端在拦截器头部放过 OPTIONS 后解决。其二/users/profile直接返回 ThreadLocal 里的登录快照导致 PUT 更新画像后再 GET 仍是旧值、isProfileBuilt永远 false改成按userId重查 DB 后正常。4.2 流式对话前端渲染把 chat.vue 里setTimeout模拟逐字的假渲染换成真 SSE用fetchReadableStream拿流按\n\n切事件、按event:/data:解析逐 token 推 chatStore 形成打字机效果并按后端约定的 session / references / delta / done / error 五类事件解耦引用卡片与回答正文的渲染。配合 3.2 的字节级坑修复词间空格不再丢失。4.3 密码重置三件套前端原忘记密码是个 toast 占位这周做成 ActionSheet 让用户在邮箱链接 / 短信验证码 / 管理员三条独立通路里三选一分别对接后端 4 个 reset 端点。后端侧配套了安全约束不暴露账号是否存在、验证成功即一次性消费、同手机号 60s 冷却、邮件 token 15min / 短信 code 5min。E2E 11 个场景全过含二次重放被拦、冷却生效等边界。4.4 占位转真实同步把api/index.js里 9 个notImplemented占位换成 3.3 补齐的真实路径余 3 个合理保留refreshToken后端用长 token 无需刷新、generateProfile注册即建画像、submitExercise空数组守卫。五、阶段成果自检与数据汇总指标需求第五周实际错题本接口完整度5 个5 个全部可用 ✅诊断 Agent 形态异步 兜底 降级异步为主 / 同步兜底 / 规则降级 / 3 次重试 ✅诊断回写画像自动衰减 加薄弱点newMastery currentMastery × (1 − 0.05 × confidence)下限 0.1 ✅AI 生成计划 / 任务取代规则AiStudyPlanGeneratorAiTaskGenerator上线 ✅course-ai 编译通过100%130 → 0195 文件 BUILD SUCCESS ✅真接大模型SSE 流式DashScope Qwen 逐 token 下发 ✅新增后端 endpoint补齐占位14 个废 9 个前端 stub ✅多 Agent 意图分类全过8 / 8 case中英混合✅RAG 检索闭环跑通references delta 同流已闭环 ✅RAG 已导入向量试水150 / 18,9080.8%密码重置 E2E全过11 / 11 ✅前端占位转真实—9 / 12余 3 个合理保留✅E2E 验证场景—40 条 curl 全 PASS ✅六、共性问题与心得如果说第四周的共性主题是让内部约定显式化、契约优先那本周三个方向的共同主题就是——把 AI 的不确定性关进确定性的笼子里。大模型是这周所有功能的核心引擎但它天生不可靠返回的 JSON 可能裹着 Markdown 代码块、可能限流超时、可能把意图判错、可能在并发下崩。三个方向不约而同地用同一套手段去驯服这种不确定性——诊断 Agent 用「正则清洗 JSON 3 次重试 规则降级」兜住模型的不稳定调度 Agent 用「强信号短路」在能确定的场景下根本不调模型把不确定性的暴露面缩到最小RAG 导入器用「source_id 唯一索引」让重跑变成无副作用操作连 SSE 都得用od -c按字节核对、而不是信任规范。凡是依赖模型的地方旁边必须有一条不依赖模型也能走通的退路这是本周最实在的工程体会。另一个延续第四周的体会是先有测试与契约再谈 AI 接入。第四周写好的四层测试和故障诊断手册这周在诊断 Agent、多 Agent 调度接入时直接派上用场——改完GradingService、TargetedPracticeService的输出契约跑一遍冒烟 闭环脚本就能知道有没有破坏既有链路而不是上线后才发现 mastery key 又对不上。七、下周计划本周让系统聪明了起来下周的重心是让这份聪明沉淀成可持续的工程能力——稳、准、可上线。第一CI/CD 收口。把第四周的 L1 L2 接进 GitHub Actions 每次 PR 自动跑L3 用 Newman 跑 Postman 集合纳入合并检查让本周新增的诊断 / 调度 / RAG 链路也进回归网。第二RAG 从试水到全量。当前只导了 150 / 18,9080.8%下周分批导入先覆盖最高频的 csdn_data_structure4940 github_offer195召回质量上加入 BM25 关键词召回 RRF 融合解决纯向量召回对专有名词不敏感的问题。第三多模态从 PDF 扩展到图像 手写。接入 qwen-vl覆盖印刷体公式、图表、手写题把上传习题照片 → 自动识别 → 诊断讲解打通成完整产品路径。第四临时方案工程化。密码重置邮件 / 短信从打日志接真实 SMTPQQ / Gmail 阿里云 SMSAgent cancel 从占位 ok 升级为维护MapsessionId, Disposable真断流AdminController加PreAuthorize(hasRole(ADMIN))收紧权限Schema 变更整理成 Flyway 迁移脚本。第五知识图谱与可视化。在诊断 Agent 沉淀的错因数据上做基于 Neo4j 的学习路径推荐并把学习效果做成可视化报告让用户直观看到自己的进步。至此计科智伴从能稳定跑走到了AI 真正参与每一次学习。下周开始让它聪明得稳、聪明得准。本周报聚焦各方向新增功能与关键技术决策详细 commit / 修复列表可参见各仓库 git log。
山东大学软件学院项目实训-创新实训-计科智伴 组周报(第五周)—— 错题诊断 Agent 落地、course-ai 接通大模型 + RAG + 多 Agent 调度、登录与对话全链路前端化
发布时间:2026/5/25 23:38:47
摘要第四周末我们立下一句 flag——下周开始让它真正聪明起来。本周就来兑现。团队从让系统稳定跑、能用正式进入让 AI 深度嵌入学习闭环的阶段目标是把智能这层从能调通推进到调得准、调得狠。三位组员分别围绕①错题本与智能诊断 Agent、②course-ai 后端线接通真实大模型 RAG 检索 多 Agent 调度、③登录 / 对话 / 密码重置的全链路前端接通展开。本周把用户做错题 → 诊断根因 → 更新画像 → 生成个性化计划 → 拆分任务这条 AI 学习闭环彻底打通同时让另一条后端线具备了真实大模型流式问答、知识库检索增强与意图调度的能力。一、本周整体定位从能稳定跑到真正聪明第四周已经把代码闭环、四层测试体系、前端体验三件事做稳能跑、能稳定跑、能让人用都已铺好。进入第五周团队的任务有三条主线三条线咬合在一起构成AI 真正参与学习的完整证据。第一把做错题变成学得到。落地错题本 智能诊断 Agent让每一次错误都被大模型分析根因、结构化回写画像并驱动 AI 重新生成学习计划与任务。这是第四周「下周计划」里诊断 Agent 与规划 Agent 正式接入的兑现。第二把另一条后端线 course-ai 从能编译、能跑推进到接真模型、能检索、会调度。接通 DashScope Qwen 的 SSE 流式问答、搭起 pgvector RAG 检索体系、再加一层多 Agent 意图调度让后端不只是会答而是先想清楚该让谁答、答的时候有没有据可依。第三把后端能力翻译成用户动作。把登录流程、流式对话渲染、密码重置三件套在 uniapp 前端真正接通让上面两条后端线的能力对用户可见、可用。本周交付如下方向负责人本周交付错题本 智能诊断 Agent AI 生成计划 / 任务本人错题本 5 接口、诊断 Agent异步 同步兜底 降级 重试、AiStudyPlanGenerator、AiTaskGenerator、画像掌握度按置信度衰减联动course-ai 后端线接通大模型 RAG 多 Agent 调度组员一195 个 Java 文件编译复活、SSE 真接 Qwen、14 个 endpoint 补齐、10 意图多 Agent 调度、pgvector DashScope 直连 RAG 闭环登录 / 对话 / 密码重置全链路前端接通组员二登录前置 画像感知跳转、fetchReadableStream解 SSE 打字机、密码重置三件套 ActionSheet、9 个notImplemented占位转真实路径下文按方向分述本周成果。二、错题本 智能诊断 Agent AI 生成计划 / 任务本人负责这是本周花时间最多的一块。诊断 Agent 涉及的逻辑比预想复杂——要调大模型、要解析 JSON、要更新画像、还要异步处理避免阻塞。核心是把用户做错题这个动作变成驱动整个自适应系统的数据源。2.1 错题本基础接口错题本模块对外提供 5 个 REST 接口代码在MistakeController接口方法功能/api/mistakesPOST添加错题触发异步诊断/api/mistakesGET错题列表分页可按知识点筛选/api/mistakes/{mistakeId}GET错题详情题目、正确答案、用户答案、诊断结果/api/mistakes/{mistakeId}/diagnosisGET诊断报告未诊断则同步触发一次/api/mistakes/weak-pointsGET薄弱知识点列表按错题数排序添加错题的关键设计是立即返回 后台异步诊断前端先展示诊断中再轮询详情拿结果不阻塞主流程PostMapping public Result addMistake(RequestBody MistakeAddRequest request) { Long userId UserHolder.getUser().getUserId(); WrongQuestion wrongQuestion new WrongQuestion(); wrongQuestion.setUserId(userId); wrongQuestion.setQId(request.getQId()); wrongQuestion.setUserAnswer(request.getUserAnswer()); wrongQuestionService.save(wrongQuestion); // 异步调用诊断 Agent添加错题后立即返回 diagnosisAgent.diagnoseAsync(wrongQuestion.getWqId(), userId, request.getQId(), request.getUserAnswer()); return Result.ok(Map.of(mistakeId, wrongQuestion.getWqId(), status, diagnosing)); }错题列表会从Question联查LearningResource取题干预览截前 50 字详情则返回完整题目、正确答案、解析、用户答案、知识点名称与诊断结果。2.2 智能诊断 Agent —— 本周的核心诊断 Agent 要做的事拿到一道错题用户答案、题目信息、知识点、用户画像调用大模型分析错误根因更新画像掌握度并记录诊断结果供前端展示。整体设计四点异步为主添加错题时走Async不阻塞主流程。同步兜底用户查诊断报告时若还没诊断完就同步触发一次diagnoseSync。降级机制大模型调用失败 / 超时自动降级为基于字符串相似度的规则诊断。重试机制大模型调用最多重试 3 次指数退避。提示词Prompt设计上给模型喂的不只是题面还包括所属知识点及 ID、从kp_relationship查到的前置知识点与易混淆知识点、用户当前对该知识点的掌握度、以及一张知识点 ID 映射表让模型返回具体 ID 而非名称。要求模型返回结构化 JSONerror_typeknowledge_gap / concept_confusion / logic_error / calculation_error / syntax_error、root_kp_id、explanation、confidence、suggested_actions。大模型调用与重试private String callModelWithRetry(String prompt) { for (int attempt 1; attempt 3; attempt) { try { return chatClient.prompt().user(prompt).call().content(); } catch (Exception e) { if (attempt 3) Thread.sleep((long) Math.pow(2, attempt - 1) * 1000); } } throw new RuntimeException(大模型调用失败); }诊断结果回来后updateUserProfileWithDiagnosis会把root_kp_id加入weakPoints并按置信度衰减掌握度——置信度越高扣得越狠但有 0.1 的下限保护double decayRate 0.05 * confidence; double newMastery Math.max(0.1, currentMastery * (1 - decayRate)); mastery.put(rootKpIdStr, newMastery);这样每次错题诊断都会让画像更精准地反映知识短板后续的计划与练习推荐也随之调整。若大模型不可用则降级到performRuleBasedDiagnosis按用户答案与标准答案的编辑距离判型相似度 0.8 → calculation_error 0.5 → concept_confusion否则 knowledge_gap保证 AI 挂了用户仍有基本反馈。2.3 AI 生成学习计划重构原来的计划生成是硬编码规则按薄弱点或目标分数定类型再固定分配 2 周 / 1 个月计划项简单遍历知识点。本周改成调大模型生成新增AiStudyPlanGenerator取用户画像年级、专业、目标分数、掌握度、薄弱点、学习习惯→ 构建提示词让模型分析每日可投入时长并产出 JSON 计划 → 解析后为每个计划项关联学习资源 → 按每日可用时长自动排日期 → 存study_plan表并失活旧计划。提示词里的硬约束包括计划类型WEAKNESS_FOCUS / TARGET_ORIENTED / COMPREHENSIVE由模型自行判断、每项预计学习时间不超过每天总时长的 60%、优先安排薄弱点并考虑前置依赖。2.4 AI 生成任务重构有了计划项还得拆成可执行任务。原来 1 个计划项对应 1 个任务太粗。本周写AiTaskGenerator让模型把每个计划项拆成 1~3 个具体任务学习 / 练习 / 复习每个任务含title/description/knowledgePoint/estimatedMinutes/practiceCount解析后补resourceId与taskDate再批量入库。于是学习 Java 多线程 60 分钟会被拆成看基础视频 25min 5 道选择题 20min 写一个生产者消费者示例 15min体验细腻很多。2.5 本周后端踩坑现象根因修复大模型返回 JSON 不纯带json代码块 / 注释模型输出习惯正则提取json包裹内容再取第一个{到最后一个}异步诊断里更新数据库不生效Async默认不在原事务中更新画像方法标Transactional(propagation REQUIRES_NEW)走独立事务高峰期大模型超时DashScope 并发限流3 次指数退避重试 最终失败降级规则诊断AI 生成计划的日期解析失败返回日期格式不一定是yyyy-MM-ddparseDateSafely失败用默认值JSON 清洗的核心两步Matcher matcher Pattern.compile((?:json)?\\s*([\\s\\S]*?)).matcher(cleaned); if (matcher.find()) cleaned matcher.group(1).trim(); int start cleaned.indexOf({); int end cleaned.lastIndexOf(}); jsonStr cleaned.substring(start, end 1);三、course-ai 后端线接通真实大模型 RAG 多 Agent 调度组员一负责与上面的主学习闭环并行组员一这周把另一条后端线course-aiSpring Boot 3.4 MyBatis-Plus Spring AI从刚接手时编译都过不去推进到接真模型、能检索、会调度。3.1 先让 195 个 Java 文件能编译首次mvn compile报出 130 个错误归类只有 5 个根因Lombok 硬编码1.18.22与 JDK 17 SB 3.4 不兼容和第四周 L1 撞上的JCTree$JCImport.qualid同源、BusinessException包从未创建、SubmitAnswerRequest整文件被注释、StudyPlanAIConfig的 Bean 重复 构造参数漂移、MinioService.uploadBytes未真迁入。最值钱的一刀是把 Lombok 的硬编码版本拿掉、交给 spring-boot-parent 统一管理为 1.18.3650 条找不到符号瞬间消失剩下 5 处真错误再各个击破。最终BUILD SUCCESS195 文件全量编译通过。经验是编译期问题先解决再谈别的——Lombok 失效让一大半错误都是假阳性。3.2 智能对话真接通 QwenSSE 流式后端早用 Spring AI 接通了 DashScope但前端还是setTimeout模拟。这周把后端 SSE 真正打通踩到一个字节级的坑坑 · SSE 规范要剥前导空格但 Spring 的输出不能剥接通后第一版输出变成HelloHello!Howcan...——词间空格全丢了。用od -c直查原始字节才确认Spring 把 token 原样拼在data:后面data: there里这个空格属于 token 本身。若按 SSE 规范strip one leading SPACE处理就会把所有词间空格吃掉。这和第四周排 SSE buffering 是一脉相承的经验不要按规范读要按字节读——Spring 这里就没按规范写。对策是不剥离、原样取raw.substring(5)。3.3 补齐 14 个后端 endpoint前端一堆notImplemented占位对应的后端路径压根不存在这周按模块一次性补齐 14 个错题状态 / 统计、练习 next / subjects / records、课程列表、对话 recommend / cancel / history、首页 home / heatmap / growth、报告 report、通知含新表 NotificationService.push()。顺带修了两个老 bugORDER BY RAND()MySQL 写法在 PG 报错改RANDOM()determineTargetDifficulty返回字符串而difficulty是 Integer永远查不到题——改成返回1/2/3。第二条和第四周 L4 抓出的kpName vs kpId是同一类毛病契约两端类型对不上接口看着 200数据却落不到点。3.4 多 Agent 智能调度项目里已有多个独立 agent / serviceTeachingAgent、AiChatService、MultimodalChatService、MistakeDiagnosisAgent、AiStudyPlanGenerator但全靠手动直接调用。这周在它们上面搭一层调度 Agent对用户原始输入做意图判别再路由POST /api/agent/dispatch → DispatcherAgent.classify() // 1) 强信号短路 → 2) LLM 分类 → 3) 兜底 → AgentOrchestrator.dispatch() ├── TeachingAgent.{generateExercises | gradeAnswer | ...} ├── AiChatService // CHAT ├── MultimodalChatService // MULTIMODAL_RECOGNITION ├── MistakeDiagnosisAgent // MISTAKE_DIAGNOSIS └── AiStudyPlanGenerator // STUDY_PLAN_GENERATE分类做成三段式以省钱省时强信号带hintIntent/attachmentUrls/extras.mistakeId直接短路命中、跳过 LLM~0ms否则把 10 种意图描述塞进 prompt 让 Qwen 输出{intent, confidence, reasoning, extractedParams}~800ms解析失败兜底走 CHAT。实测 8 条中英文混合 case 全过例如 give me 3 medium dynamic programming questions 命中EXERCISE_GENERATE并抽出{count:3, difficulty:2, knowledgePoint:dynamic programming}。3.5 RAG 检索体系数据源是data_crawler/crawl/cleaned/下 13 个已切好 chunks 的 JSON合计约 18,908 条数据结构 6042、算法 2832、操作系统 2402、数据库 2147 等。技术栈PostgreSQL pgvector欧氏距离-DashScopetext-embedding-v31024 维先取 topK × 3 召回再按 subject → course_id 过滤。三个非显然的坑坑一 · 维度错位表原是vector(768)v3 实际输出 1024 维。ALTER TYPE不支持趁 0 行窗口期DROP ADD COLUMN重建。坑二 · Spring AI 解不开 DashScope 响应OpenAiApi$EmbeddingList没标JsonIgnoreProperties而 DashScope 多返回一个顶层id字段触发UnrecognizedPropertyException。干脆自写 100 行 HTTP 客户端DashScopeEmbeddingClient绕开——三方 SDK 兼容性问题绕过比对抗便宜。坑三 · batch 上限是 10 不是 25实测超过 10 条返回batch size ... not be larger than 10把BATCH_SIZE改 10 即稳。导入器做了幂等chunk_id入source_id 唯一索引重跑 skip。验证从导入到回答导入github_database.json150 chunks后提问数据库事务的 ACID 分别指什么SSE 里先收到event:references带召回片段和 score再收到event:delta正文且 AI 开头明说结合了参考资料——RAG 真闭环。四、登录 / 对话 / 密码重置全链路前端接通组员二负责后端两条线在变强组员二这周把它们翻译成用户能直接操作的前端动作并在联调中协同定位了两个隐藏 bug。4.1 登录流程重构先登录、再画像、再首页把 App 启动落地页从 onboarding 问卷改成登录页注册做成顶部 Tab登录后调getProfile判断画像决定去向。判定逻辑放在前端只看目标分数或在学课程有任一即视为已建// login.vue isProfileBuilt(profile) { if (!profile) return false const hasTarget profile.targetScore ! null const hasCourses Array.isArray(profile.currentCourses) profile.currentCourses.length 0 return hasTarget || hasCourses }联调中暴露并与后端协同定位了两个坑其一浏览器跨域带authorization头会先发OPTIONS预检而LoginInterceptor没排除 OPTIONS预检返回 401浏览器视为失败真正的 GET/PUT 根本不发出——后端日志一片空白前端只见一个提交失败极难定位后端在拦截器头部放过 OPTIONS 后解决。其二/users/profile直接返回 ThreadLocal 里的登录快照导致 PUT 更新画像后再 GET 仍是旧值、isProfileBuilt永远 false改成按userId重查 DB 后正常。4.2 流式对话前端渲染把 chat.vue 里setTimeout模拟逐字的假渲染换成真 SSE用fetchReadableStream拿流按\n\n切事件、按event:/data:解析逐 token 推 chatStore 形成打字机效果并按后端约定的 session / references / delta / done / error 五类事件解耦引用卡片与回答正文的渲染。配合 3.2 的字节级坑修复词间空格不再丢失。4.3 密码重置三件套前端原忘记密码是个 toast 占位这周做成 ActionSheet 让用户在邮箱链接 / 短信验证码 / 管理员三条独立通路里三选一分别对接后端 4 个 reset 端点。后端侧配套了安全约束不暴露账号是否存在、验证成功即一次性消费、同手机号 60s 冷却、邮件 token 15min / 短信 code 5min。E2E 11 个场景全过含二次重放被拦、冷却生效等边界。4.4 占位转真实同步把api/index.js里 9 个notImplemented占位换成 3.3 补齐的真实路径余 3 个合理保留refreshToken后端用长 token 无需刷新、generateProfile注册即建画像、submitExercise空数组守卫。五、阶段成果自检与数据汇总指标需求第五周实际错题本接口完整度5 个5 个全部可用 ✅诊断 Agent 形态异步 兜底 降级异步为主 / 同步兜底 / 规则降级 / 3 次重试 ✅诊断回写画像自动衰减 加薄弱点newMastery currentMastery × (1 − 0.05 × confidence)下限 0.1 ✅AI 生成计划 / 任务取代规则AiStudyPlanGeneratorAiTaskGenerator上线 ✅course-ai 编译通过100%130 → 0195 文件 BUILD SUCCESS ✅真接大模型SSE 流式DashScope Qwen 逐 token 下发 ✅新增后端 endpoint补齐占位14 个废 9 个前端 stub ✅多 Agent 意图分类全过8 / 8 case中英混合✅RAG 检索闭环跑通references delta 同流已闭环 ✅RAG 已导入向量试水150 / 18,9080.8%密码重置 E2E全过11 / 11 ✅前端占位转真实—9 / 12余 3 个合理保留✅E2E 验证场景—40 条 curl 全 PASS ✅六、共性问题与心得如果说第四周的共性主题是让内部约定显式化、契约优先那本周三个方向的共同主题就是——把 AI 的不确定性关进确定性的笼子里。大模型是这周所有功能的核心引擎但它天生不可靠返回的 JSON 可能裹着 Markdown 代码块、可能限流超时、可能把意图判错、可能在并发下崩。三个方向不约而同地用同一套手段去驯服这种不确定性——诊断 Agent 用「正则清洗 JSON 3 次重试 规则降级」兜住模型的不稳定调度 Agent 用「强信号短路」在能确定的场景下根本不调模型把不确定性的暴露面缩到最小RAG 导入器用「source_id 唯一索引」让重跑变成无副作用操作连 SSE 都得用od -c按字节核对、而不是信任规范。凡是依赖模型的地方旁边必须有一条不依赖模型也能走通的退路这是本周最实在的工程体会。另一个延续第四周的体会是先有测试与契约再谈 AI 接入。第四周写好的四层测试和故障诊断手册这周在诊断 Agent、多 Agent 调度接入时直接派上用场——改完GradingService、TargetedPracticeService的输出契约跑一遍冒烟 闭环脚本就能知道有没有破坏既有链路而不是上线后才发现 mastery key 又对不上。七、下周计划本周让系统聪明了起来下周的重心是让这份聪明沉淀成可持续的工程能力——稳、准、可上线。第一CI/CD 收口。把第四周的 L1 L2 接进 GitHub Actions 每次 PR 自动跑L3 用 Newman 跑 Postman 集合纳入合并检查让本周新增的诊断 / 调度 / RAG 链路也进回归网。第二RAG 从试水到全量。当前只导了 150 / 18,9080.8%下周分批导入先覆盖最高频的 csdn_data_structure4940 github_offer195召回质量上加入 BM25 关键词召回 RRF 融合解决纯向量召回对专有名词不敏感的问题。第三多模态从 PDF 扩展到图像 手写。接入 qwen-vl覆盖印刷体公式、图表、手写题把上传习题照片 → 自动识别 → 诊断讲解打通成完整产品路径。第四临时方案工程化。密码重置邮件 / 短信从打日志接真实 SMTPQQ / Gmail 阿里云 SMSAgent cancel 从占位 ok 升级为维护MapsessionId, Disposable真断流AdminController加PreAuthorize(hasRole(ADMIN))收紧权限Schema 变更整理成 Flyway 迁移脚本。第五知识图谱与可视化。在诊断 Agent 沉淀的错因数据上做基于 Neo4j 的学习路径推荐并把学习效果做成可视化报告让用户直观看到自己的进步。至此计科智伴从能稳定跑走到了AI 真正参与每一次学习。下周开始让它聪明得稳、聪明得准。本周报聚焦各方向新增功能与关键技术决策详细 commit / 修复列表可参见各仓库 git log。