作品集 | AI 编程教学平台 — 从 RAG 到 Agentic RAG 的全栈实战
项目概述AI 编程教学平台 是一个面向高校 C 语言课程的智能教学辅助系统,由我独立完成全栈开发(后端 + 前端 + AI 集成 + 运维部署)。项目从 2025 年 9 月启动,持续迭代至今。 核心功能 模块 功能描述 作业批改 学生提交 C 代码 → AI 自动评分 + 错误分析 + 改进建议 RAG 知识库 教师上传教学资料 → 智能分块 → 向量检索 → AI 精准答疑 AI 对话 SSE 流式对话,KaTeX 数学公式渲染,代码高亮 学情分析 成绩分布、知识掌握热力图、学生成长曲线、教案生成 QQ 机器人 OneBot 协议接入,作业截止提醒、成绩推送、群内 AI 答疑 班级管理 教师创建班级、邀请学生、发布作业任务、查看提交情况 架构总览1234567891011121314151617181920┌──────────────────────────────────────────────────────────┐│ Vue 3 前端 (SPA) ││...
建站首发:Markdown语法开篇
Markdown 语法开篇本文适用于新手快速入门 Markdown,是搭建博客的必备基础。 1. 标题示例# 一级标题 ## 二级标题 ### 三级标题
AI 教学平台 — 从 RAG 到 Agentic RAG 的全链路实战与面试复盘
项目亮点本项目是一个基于 Spring Boot + Vue 3 的 AI 教学平台,核心亮点: 自建 RAG 全链路:本地 ONNX Embedding(bge-small)+ pgvector + 双路检索(向量 + 关键词)+ RRF 融合 + Reranker 精排 + Query Rewrite,不是调包 Demo Agentic RAG:通过 MCP Tool Server 注册 5 个工具,LLM 自主决策检索知识库、查成绩、看作业、查课表、获取时间 本地模型部署:DJL + ONNX Runtime + bge-small-zh-v1.5(Embedding)+ bge-reranker-base(Reranker),多源镜像自动下载 + 哈希降级 智能分块策略:文档类型检测 → 结构切割 → 语义边界切割 → 滑动窗口 → 上下文引用 DAG 工作流引擎:GRADE → ERROR_ANALYSIS → SUGGESTION,条件路由 + 失败回退 + 类型安全状态 分布式基础设施:Bucket4j 令牌桶限流 + 布隆过滤器防穿透 + Cache-Aside...
智能教学平台开发日志 — Tool Calling 接入与项目工程化
今日工作内容教学平台的 AI Agent 从「手动拼上下文」进化为「LLM 自主决策的 Tool Calling」模式,同时补齐了 Docker 容器化、单元测试、压测等工程化工作。 遇到的坑与解决方案1. LangChain4j 1.13.0 OpenAiChatModel 的 HTTP 客户端 BUG现象:调用 OpenAiChatModel.chat() 时抛出 Invalid HTTP method。 原因:LangChain4j 1.13.0 的 OpenAiChatModel 内部使用 JdkHttpClient 发送非流式请求,但在 Java 21 + Spring Boot 4 环境下存在兼容性问题,HTTP 方法无法正常设置。 解决:弃用 OpenAiChatModel,直接用已有的 RestClient 手工实现 tool_calls 循环。核心改动: 123456789101112131415// 手工实现 tool_calls 循环,不依赖 OpenAiChatModelfor (int round = 0; round < MAX_TOOL_RO...
从 Spring AI 叛逃到 LangChain4j 的一天
起:一个看似简单的决定我有个后端项目 firedemo,用 Spring AI 2.0-M1 对接 OpenClaw Gateway 做 AI 作业批改。用得其实很薄——就一个 ChatClient 发 HTTP 请求,连 Function Calling 都没碰。 “换成 LangChain4j 吧,Agent 编排更成熟,简历上也好看。” 换依赖而已,能有多难? 承:五连坑坑一:Jackson 双版本打架1Could not initialize class tools.jackson.databind.json.JsonMapper$Builder Spring Boot 4 用 Jackson 3(tools.jackson),LangChain4j beta1 拖了个 openai4j → Retrofit → Jackson 2.x(com.fasterxml.jackson)。虽然包名不同,但 classpath 上有两个 Jackson 就是炸。 修:升到 1.0.0-beta3——这个版本去掉了 openai4j,自带了 JDK HttpClient。但坑...
记一次RAG知识库混乱与前端连环bug的救火之旅
开场:一颗定时炸弹事情从一个看似简单的测试开始—— 学生 QQ 里问”龙空灵喜欢什么?”,结果 RAG 检索到了龙空灵私人知识库里”爱玩 CS2、想吃 Java 实习”的内容。 私人知识库居然对学生可见。 这不叫知识库,这叫朋友圈。 第一关:全库检索,来者不拒问题检查 VectorStoreService 的 SQL: 1SELECT ... FROM document_chunk ORDER BY embedding_vec <=> ?::vector LIMIT ? 没有 WHERE,没有 user_id,没有 kb_id。所有人敞开大门,随便搜。 解决 document_chunk 加 user_id 列,迁移脚本回填存量数据 VectorStoreService.similaritySearch() / keywordSearch() 加权限过滤 SQL: 12WHERE (user_id = ? AND kb_id IS NULL) -- 私人文档 OR kb_id IN (?) -- 已加入的...
教学仪表盘热力图重构——从AI驱动到教师驱动的知识点管理系统
背景教学数据中心的热力图原本是 AI 批改作业时自动生成 的:AI 按闭包知识点列表返回 knowledgePoints(掌握度),后端存入 homework_knowledge 表,前端只读渲染。老师无法干预热力图内容。 本次重构目标:把热力图从 AI 自动生成的静态展示,变成老师驱动的动态管理系统——老师创建知识点,AI 批改时按老师定义的知识点对错误进行分类,热力图变成错误聚合 + 交互式筛选入口。 数据流改造对比12旧:AI 批改 → knowledgePoints(封闭列表) → homework_knowledge → 热力图新:老师创建知识点 → AI 批改(传入知识点列表) → errors[].knowledgePoint → submission_errors → 热力图 → 点击弹窗看具体错误 核心改动1. 数据库 操作 表名 说明 新建 teacher_knowledge 老师自定义知识点(class_id, name, color, sort_order) 新建 submission_errors 错误分类明细(error_text,...
知识库目录树与共享功能实现全记录
概述本文记录了为作业批改系统实现知识库模块的全过程,包括目录树浏览、文件管理、共享知识库协作功能,以及期间遇到的各种问题和解决方案。 最终效果:用户可以创建个人知识库目录树,上传文件、管理文件夹;同时支持创建共享知识库,多人协作上传和管理文档。 一、目录树知识库(初版)需求将知识库管理页面改为类似腾讯 ima 的目录树形式,支持: 文件夹/文件的无限层级嵌套 展开折叠 右键菜单(新建子文件夹、重命名、删除) 拖拽排序 搜索过滤 右侧文档内容预览 技术选型项目已集成 Element Plus,直接使用 el-tree 组件而非手写递归组件。 功能 实现 目录树渲染 el-tree + children 递归 右键菜单 @node-contextmenu + 自定义浮层 拖拽排序 draggable + @node-drop 搜索过滤 filter-node-method 行内重命名 双击 → el-input 内联编辑 文件上传 el-upload 拖拽模式 文档预览 后端 Tika 解析 + 前端 Markdown 渲染 后...
C语言作业智能批改与学情分析平台 — 项目汇报
一、项目定位一个面向 C 语言教学的全链路智能平台:学生提交代码 → AI 自动批改 → 多维度学情分析 → QQ 群实时通知 → RAG 知识库辅助教学决策。 一句话:把教师从重复批改中解放出来,把教学决策从”凭感觉”变成”看数据”。 二、核心业务流程12345678910111213141516171819202122232425262728293031323334学生提交代码(QQ/Web) │ ▼ 文件名解析 ─── 学号_姓名_班级_作业名.c (正则提取,无需登录) │ ▼ 提交次数校验(最多3次) + 班级校验 │ ▼ Redis Stream 异步队列 │ │ ▼ ▼ AI 批改 定时提醒(QQ群+私聊) (OpenClaw 24h/1h截止预警 Agent) 全员完成播报 │ ▼ JSON 结构化结果 ├── totalScore / overallComment ├── strength...
Spring Boot 分层限流实战 — 网关层 Bucket4j 令牌桶 + 方法层 Redis Lua 滑动窗口
背景项目中已有基于 @RateLimit 注解的方法级限流,通过 Redis Lua 滑动窗口实现。但它存在两个问题: 入口即 Controller:限流在 AOP 切面触发,恶意请求已经走完了 Filter Chain、Security 上下文构建等流程 不支持突发流量:滑动窗口是严格的计数限流,超了就拒,无法应对合理突发 因此引入网关层令牌桶作为第一道防线,与方法层滑动窗口形成二级分层限流。 架构设计12345678910111213141516171819请求进入 │ ▼┌─────────────────────────────────────────┐│ ① TokenBucketInterceptor (网关层) │ Bucket4j 分布式令牌桶│ 维度:IP + URI │ 粗粒度防刷,支持突发│ 存储:Redis (Redisson CAS) ││ 顺序:order(0) 最先执行 │└───────────────┬──...




