项目概述

AI 编程教学平台 是一个面向高校 C 语言课程的智能教学辅助系统,由我独立完成全栈开发(后端 + 前端 + AI 集成 + 运维部署)。项目从 2025 年 9 月启动,持续迭代至今。

核心功能

模块 功能描述
作业批改 学生提交 C 代码 → AI 自动评分 + 错误分析 + 改进建议
RAG 知识库 教师上传教学资料 → 智能分块 → 向量检索 → AI 精准答疑
AI 对话 SSE 流式对话,KaTeX 数学公式渲染,代码高亮
学情分析 成绩分布、知识掌握热力图、学生成长曲线、教案生成
QQ 机器人 OneBot 协议接入,作业截止提醒、成绩推送、群内 AI 答疑
班级管理 教师创建班级、邀请学生、发布作业任务、查看提交情况

架构总览

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
┌──────────────────────────────────────────────────────────┐
│ Vue 3 前端 (SPA) │
│ Element Plus + KaTeX + Pinia + SSE 流式对话 │
└────────────────────┬─────────────────────────────────────┘
│ HTTP / SSE
┌────────────────────▼─────────────────────────────────────┐
│ Spring Boot 4.0 + Java 21 │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌─────────────┐ │
│ │ 作业模块 │ │ RAG 模块 │ │ MCP 工具 │ │ OneBot 集成 │ │
│ └──────────┘ └──────────┘ └──────────┘ └─────────────┘ │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌─────────────┐ │
│ │ 限流模块 │ │ 缓存模块 │ │ 异步队列 │ │ 工作流引擎 │ │
│ └──────────┘ └──────────┘ └──────────┘ └─────────────┘ │
└───────┬──────────────┬──────────────┬────────────────────┘
│ │ │
┌───────▼──────┐ ┌─────▼──────┐ ┌───▼──────────┐
│ PostgreSQL │ │ Redis │ │ OpenClaw │
│ + pgvector │ │ + Redisson │ │ Gateway │
│ + Flyway │ │ + Bucket4j │ │ (LLM 编排) │
└──────────────┘ └────────────┘ └──────────────┘

技术亮点详解

一、完整 RAG 检索链路(7 步管线)

这不是调包 Demo——从 Embedding 到精排全链路自研:

1
2
3
4
5
文档上传 → 智能分块 → 本地向量化 → pgvector 存储

用户提问 → Query 改写 → 双路召回 → RRF 融合 → Reranker 精排 → LLM 生成

RagTrace 全链路日志

1. 智能文档切割

  • 自动识别 Markdown / 代码 / 对话 / 通用 4 种文档类型
  • 按结构(标题层级、函数定义、对话轮次)+ 语义边界(余弦相似度 < 0.6 判定为主题切换)双重切割
  • 滑动窗口 + 上下文引用保留语义连贯性

2. 本地 ONNX Embedding

  • DJL 加载 bge-small-zh-v1.5,ONNX Runtime 纯 CPU 推理
  • 384 维向量,单条 30ms,无 GPU 依赖、无外部 API 费用
  • 多源镜像自动下载 + SHA-256 哈希降级保证模型高可用

3. pgvector 向量检索

  • PostgreSQL 原生 pgvector 扩展 + IVF-Flat 索引加速近似最近邻搜索
  • 支持用户级隔离(WHERE user_id = ?),防止知识库越权

4. 双路召回 + RRF 融合

  • 向量检索 + PostgreSQL tsvector 全文检索双路并行
  • Reciprocal Rank Fusion 归一化:score = Σ 1/(k+rank),k=60
  • 比线性加权更稳定,不依赖不同检索路的绝对分数量纲

5. Cross-Encoder Reranker 精排

  • 本地 ONNX 部署 bge-reranker-base,对 RRF Top-N 逐条精排
  • Query-Document 联合编码,比 Bi-Encoder 更精准
  • 单条 80ms,候选集控制在 20 条内,延迟可控

6. LLM Query 改写

  • 短 query(<15 字)或包含指代词(”这个””上次那个”)时触发
  • LLM 将口语化问题改写为检索友好的关键词
  • 失败时降级为原始 query,不影响主流程

7. RagTrace 全链路可观测

  • 每一步耗时、召回量、精排 Top-N 文档名和分数记录为结构化 JSON
  • 数据模型对齐 RAGAS 评估标准(Context Precision / Context Recall),可无缝对接 LangFuse

二、MCP 工具协议实现

基于 Anthropic MCP (Model Context Protocol) 规范,自研工具注册与调用机制:

工具名 功能 Agent 使用场景
queryClassStatus 查询班级学习概况 “C101 班学得怎么样?”
queryHomeworkTasks 查询作业任务列表 “最近有什么作业?”
queryStudentStats 查询学生成绩 “张三成绩怎么样?”
searchKnowledge 知识库语义检索 “指针和数组有什么区别?”
getCurrentTime 获取当前时间 “今天是几号?”

LLM 自主决策何时调用哪个工具,工具返回结果后 LLM 基于实时数据生成回答,实现 Agentic RAG

三、分布式系统基础设施

缓存穿透防护链

  • Redis BloomFilter 预加载全量班级 ID(启动时加载,误判率 3%)
  • Cache-Aside 模式 + Redisson 分布式锁控制 Miss 单源回源
  • Caffeine 本地缓存 + Redis 远程缓存两级架构

Bucket4j 分布式令牌桶限流

  • 基于 Redis 的接口级限流,AOP 切面无侵入
  • 匿名/认证用户差异化策略,/api/homework/submit 单独 5次/分钟
  • 令牌桶 vs 滑动窗口——突发流量友好,允许短时超发

Redis Stream 异步批改队列

  • 学生提交 → 入库(PENDING) → 入队 → 秒回”已收到”
  • 消费者异步调用 LLM 批改 → 写结果 → 状态流转为 COMPLETED
  • 接口响应时间从 30~300s 优化到 200ms 以内

Java 21 Virtual Threads

  • 启用 spring.threads.virtual.enabled=true
  • IO 密集型任务(LLM 调用、DB 查询、Redis 操作)吞吐量显著提升
  • Tomcat 请求线程、@Async 方法、WebFlux 调度线程全部切换为虚拟线程

四、工程化实践

数据库

  • Flyway 版本化迁移,SQL 脚本可追溯可回滚
  • PostgreSQL + pgvector 向量索引 + tsvector 全文索引
  • Schema 设计含完整字段注释(COMMENT ON TABLE/COLUMN

安全

  • Spring Security + JWT 无状态认证
  • 路由级权限控制(教师端/学生端分离)
  • API 请求频率限制

前端

  • Vue 3 + TypeScript + Element Plus + Pinia 状态管理
  • KaTeX 数学公式实时渲染(支持 LaTeX 在线编辑)
  • SSE 流式对话 + Markdown 渲染 + 代码高亮
  • 路由守卫 + 登录拦截 + AI 回复中断确认

运维

  • Docker 容器化部署
  • JMeter 压力测试
  • Swagger/Knife4j API 文档

踩坑与收获

1. LangChain4j 框架坑

从 Spring AI 叛逃到 LangChain4j 经历五连坑:

  • Jackson 双版本冲突(tools.jackson vs com.fasterxml.jackson
  • BOM 覆盖 Netty 版本导致 Spring Boot 4 不兼容
  • API 大换血(ChatLanguageModelChatModel
  • JDK HttpClient 发 HTTP/2 Upgrade 头被 OpenClaw Gateway 拒绝
  • 流式调用超时不稳定

最终方案:LangChain4j 只做 OpenAI 协议兼容的薄封装,核心逻辑(Tool Calling 循环、RAG 管线)全部自研,不依赖框架黑盒。

2. 知识库越权 Bug

RAG 检索无 user_id 过滤 → 私人知识库内容被学生搜到。修复方案:

  • document_chunk 表加 user_id 列 + Flyway 迁移回填
  • 检索 SQL 加权限过滤条件
  • 共享知识库与个人知识库独立隔离

3. QQ 机器人消息丢失

OpenClaw OneBot 插件每次处理消息时重载 → dispatcher 回调被销毁 → Agent 回复无法投递。定位到是插件加载时机问题,不是超时问题。


技术栈总结

分层 技术
后端框架 Spring Boot 4.0.4 + Java 21
ORM MyBatis-Plus 3.5.15
数据库 PostgreSQL 16 + pgvector + Flyway
缓存 Redis + Redisson + Caffeine
AI 框架 LangChain4j 1.13.0 + DJL 0.28.0 + ONNX Runtime
AI 模型 bge-small-zh-v1.5 (Embedding) + bge-reranker-base (Reranker)
限流 Bucket4j-Redis
文档解析 Apache Tika 2.9
前端 Vue 3 + TypeScript + Element Plus + Pinia + KaTeX
消息推送 OneBot / Napcat QQ 机器人
API 文档 SpringDoc OpenAPI + Knife4j
部署 Docker
测试 JMeter

项目链接