AIGrader:一个 AI 作业批改平台的 Java EE 课设实战
AIGrader:一个 AI 作业批改平台的 Java EE 课设实战
教师布置作业,AI 秒级批改,学生即时查看并订正,教师复核确认——一个完整的作业批改闭环。
目录
这个项目是什么
AIGrader 是一个基于 AI 的中小学作业批改平台。教师在线布置作业,学生在线答题,AI 自动批改并生成评语,学生查看结果后可以订正,教师最终复核确认。
核心闭环:教师布置 → AI 秒级批改 → 学生查看与订正 → 教师复核。
技术栈
| 层级 | 技术 |
|---|---|
| 后端框架 | Spring Boot 3.4.5 + Java 21 + Maven |
| AI 引擎 | Spring AI 1.0.0-M6 + DeepSeek(支持动态切换模型) |
| 安全认证 | Spring Security + JWT(无状态 Token) |
| 数据库 | PostgreSQL 16 + pgvector 扩展 |
| 缓存 | Redis 7(DB=2) |
| 前端框架 | React 18 + Vite + TypeScript |
| UI 组件 | Ant Design 5 |
| 图表 | Recharts 2.15 |
| 状态管理 | Zustand |
项目地址:github.com/xiaodangjia105/AIGrader
这是我的 Java EE 课程设计项目,一个人完成的全栈开发。后端 63 个 Java 文件,前端 21 个 TS/TSX 文件,9 张数据库表,30+ 个 REST API。
功能全景
系统有三种角色:教师、学生、管理员。每个角色看到的界面和能做的事完全不同。
教师端
| 功能 | 说明 |
|---|---|
| 作业管理 | 创建作业、从题库选题组卷、查看布置历史 |
| AI 批改结果查看 | 查看每个学生的 AI 批改结果,含分数、评语、扣分原因 |
| 批改复核 | 对 AI 批改结果进行人工修正,调整分数或评语 |
| 个性化评语 | AI 根据学生历史表现生成个性化评语,教师可编辑后发送 |
| 班级统计 | 查看班级完成率、平均分、分数分布 |
学生端
| 功能 | 说明 |
|---|---|
| 查看作业 | 查看教师布置的待完成作业列表 |
| 在线答题 | 支持选择题、判断题、填空题、简答题、作文题 |
| 查看批改结果 | 即时查看 AI 批改的分数、评语和正确答案 |
| 错题订正 | 对错误答案进行订正,系统记录订正历史 |
| 学习报告 | AI 分析薄弱知识点,生成个性化学习建议 |
管理后台
| 功能 | 说明 |
|---|---|
| 题库管理 | 题目的 CRUD 操作,支持 JSON/CSV 批量导入 |
| 用户管理 | 查看和管理所有用户 |
| AI 配置 | 动态切换 AI 模型和 API Key,无需重启服务 |
| AI 准确率趋势 | 跟踪 AI 批改的准确率变化 |
技术架构
后端采用标准的 Spring Boot 分层架构:
- Controller 层(8 个控制器):处理 HTTP 请求,参数校验,调用 Service
- Service 层(10 个服务):核心业务逻辑,事务管理
- Repository 层(9 个仓库):JPA 数据访问,自动建表
- Entity 层(9 个实体):数据库表映射
- DTO 层(12 个对象):数据传输对象,隔离内部模型和 API 契约
前端结构:
- Pages:按角色分组——教师端 5 页、学生端 5 页、管理后台 4 页
- Components:共享组件(表格、表单、图表)
- Services:API 调用层,Axios + JWT 拦截器
- Store:Zustand 状态管理
数据库有 9 张表,其中 PostgreSQL 的 pgvector 扩展用于存储和检索向量数据(支持未来的智能题目推荐功能)。Redis 用于 JWT Token 黑名单和会话缓存。
核心模块:AI 批改引擎
这是整个系统最核心的部分。不同题型的批改逻辑完全不同——选择题可以精确匹配,填空题需要模糊匹配,主观题需要 AI 理解语义。用一个统一的接口处理所有题型,是策略模式的典型应用场景。
策略模式设计
public interface GradingStrategy {
/**
* 批改一道题
* @param question 题目信息(题干、正确答案、分值)
* @param answer 学生答案
* @return 批改结果(分数、评语、扣分原因)
*/
GradingResult grade(Question question, String answer);
}
三个实现类:
- ChoiceGradingStrategy(选择题/判断题):精确匹配答案,不需要调 AI。分数要么满分要么零分。
- FillBlankGradingStrategy(填空题):先精确匹配,失败后调 AI 做语义相似度判断。比如答案是"二氧化碳",学生写了"CO2",也算对。
- SubjectiveGradingStrategy(简答题/作文题):调 DeepSeek API,让 AI 根据评分标准打分。
工厂模式根据题型分发:
public class GradingStrategyFactory {
private final Map<QuestionType, GradingStrategy> strategies;
public GradingStrategy getStrategy(QuestionType type) {
GradingStrategy strategy = strategies.get(type);
if (strategy == null) {
throw new IllegalArgumentException("不支持的题型: " + type);
}
return strategy;
}
}
Prompt 工程
主观题批改的关键在 Prompt 设计。PromptTemplateService 按学科组织 Prompt 模板,不同学科的评分标准不同:
- 数学:看计算过程是否正确、步骤是否完整、最终答案是否准确
- 语文:看表达是否通顺、逻辑是否清晰、是否有错别字
- 英语:看语法是否正确、词汇是否恰当、表达是否地道
AI 要求返回结构化的 JSON:
{
"score": 85,
"maxScore": 100,
"comment": "解题思路正确,但第三步计算有误",
"deductions": [
{"reason": "第三步符号错误", "points": 10},
{"reason": "缺少单位", "points": 5}
]
}
结构化输出的好处:前端可以直接渲染每个扣分项,学生能清楚看到哪里扣了分、为什么扣。
降级策略
AI 调用可能失败(网络超时、API 限流)。系统做了降级处理:AI 不可用时,主观题给默认分数并标记"待人工复核",不会阻断整个批改流程。
核心模块:个性化评语与学习报告
个性化评语(CommentService)
传统做法:教师手动写评语,工作量大,而且很难做到个性化。
AIGrader 的做法:AI 根据学生的答题历史和成绩趋势自动生成评语。Prompt 里包含学生最近 5 次作业的成绩、本次作业的得分、错误题目类型等上下文,让 AI 生成有针对性的评语。
比如一个学生上次考了 60 分,这次考了 85 分,AI 会生成"进步明显,尤其是应用题部分有了很大提升,继续保持"。如果一个学生连续三次在几何题上丢分,AI 会建议"几何部分需要加强,建议复习三角形全等的判定条件"。
教师可以编辑 AI 生成的评语后再发送给学生。
学习报告(ReportService)
学习报告是学生端的核心功能。ReportService 分析学生的所有答题记录,生成:
- 薄弱知识点分析:按题目标签统计正确率,找出正确率最低的知识点
- 成绩趋势:最近 N 次作业的分数变化曲线
- AI 学习建议:根据薄弱知识点,推荐具体的复习方向
报告数据用 Recharts 在前端渲染成图表,学生一目了然。
核心模块:动态模型切换
AiConfigService 实现了一个不需要重启服务就能切换 AI 模型的能力。
配置存储在数据库的 ai_config 表中,包含:
- 当前使用的模型名称(如
deepseek-chat) - API Key
- API Base URL
- 模型参数(temperature、max_tokens 等)
管理后台的"AI 配置"页面可以修改这些配置,保存后立即生效。下次 AI 调用时,AiConfigService 从数据库读取最新配置,用 Spring AI 的统一接口创建新的客户端实例。
这个设计的好处:
- 不重启切换模型:DeepSeek 不稳定时,可以切到通义千问或 Kimi
- API Key 轮换:Key 过期或泄露时,直接在界面上换
- 参数调优:调整 temperature 来控制 AI 评分的稳定性
Spring AI 的价值在这里体现得很明显——它提供了统一的 AI 调用接口,切换底层模型只需要改配置,代码不需要动。
核心模块:认证与权限
JWT 无状态认证
系统使用 Spring Security + JWT 实现无状态认证。用户登录后签发 Token,后续请求通过 Token 认证,服务端不存储会话状态。
三种角色的权限隔离:
| 角色 | 能访问的 API |
|---|---|
| 教师 | /api/assignments/**、/api/grading/**、/api/statistics/** |
| 学生 | /api/submissions/**、/api/student/** |
| 管理员 | /api/admin/**、/api/questions/** |
用 @PreAuthorize 注解在 Controller 方法上声明权限:
@PreAuthorize("hasRole('TEACHER')")
@PostMapping("/assignments")
public ResponseEntity<ApiResponse<Assignment>> createAssignment(...) { ... }
Token 黑名单
JWT 签发后到过期前无法单方面废止。系统用 Redis 实现了 Token 黑名单:用户登出时,把 Token 的唯一标识加入 Redis,设置过期时间等于 Token 剩余有效期。验证 Token 时先查黑名单,命中则拒绝。
前端实现
技术选型
前端用 React 18 + TypeScript + Vite 构建,UI 组件库选 Ant Design 5。状态管理用 Zustand——比 Redux 轻量得多,一个文件就能定义一个 store,不需要 action、reducer、middleware 那一套。
页面结构
frontend/src/pages/
├── LoginPage.tsx # 登录页(共用)
├── teacher/
│ ├── AssignmentPage.tsx # 作业管理
│ ├── GradingPage.tsx # 批改结果查看
│ ├── ReviewPage.tsx # 批改复核
│ ├── StatisticsPage.tsx # 班级统计
│ └── CommentPage.tsx # 个性化评语
├── student/
│ ├── HomeworkPage.tsx # 作业列表
│ ├── AnswerPage.tsx # 在线答题
│ ├── ResultPage.tsx # 批改结果
│ ├── CorrectPage.tsx # 错题订正
│ └── ReportPage.tsx # 学习报告
└── admin/
├── QuestionPage.tsx # 题库管理
├── UserPage.tsx # 用户管理
├── AiConfigPage.tsx # AI 配置
n └── AccuracyPage.tsx # AI 准确率趋势
API 调用层
Axios 实例配置了 JWT 拦截器:
- 请求拦截:自动从 Zustand store 读取 Token,附加到请求头
- 响应拦截:遇到 401 自动跳转登录页,清除本地 Token
所有 API 调用统一封装在 services/api.ts 中,按模块分组(auth、assignment、submission、grading 等)。
图表
Recharts 用于两个核心场景:
- 班级统计:柱状图展示分数分布,折线图展示平均分趋势
- 学习报告:雷达图展示各知识点掌握程度,折线图展示成绩变化
总结与收获
这个课设让我从零搭建了一个完整的全栈应用,覆盖了后端开发、前端开发、AI 集成、数据库设计、安全认证等多个方面。
几个关键收获:
策略模式的实际应用。AI 批改引擎用策略模式处理不同题型,比 if-else 链清晰得多,新增题型只需要加一个实现类。
Prompt 工程的重要性。AI 批改的质量取决于 Prompt 的设计。结构化输出(JSON)让前端可以直接渲染,不需要再做文本解析。
Spring AI 的价值。统一的 AI 调用接口让模型切换变得很简单——改配置就能切模型,代码不需要动。
无状态认证的取舍。JWT 让后端可以水平扩展,但 Token 无法主动失效,需要额外引入 Redis 黑名单。没有银弹,只有 trade-off。
当前的局限:只支持单 Sheet 的作业模板、AI 调用有延迟(批量批改时较慢)、大数据量下性能有待优化。后续计划支持多 Sheet、批量转换和本地模型。
项目地址:github.com/xiaodangjia105/AIGrader
觉得有用的话,点个 Star 支持一下。
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)