# 基于LLM的自动试卷生成工具 **Repository Path**: Echoza/TestPaperG ## Basic Information - **Project Name**: 基于LLM的自动试卷生成工具 - **Description**: 开源软件开发导论课程项目,选题为基于LLM的自动试卷生成工具。 - **Primary Language**: Java - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 1 - **Created**: 2026-04-04 - **Last Updated**: 2026-04-21 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # TestPaperG - 试卷生成智能体系统 ## 项目概述 TestPaperG 是一个基于 Spring Boot 和大语言模型(LLM)的智能试卷生成系统。用户可以通过简单的 REST API 调用,让 AI 自动根据给定的知识点、题型偏好和难度要求,生成结构化的试卷内容(包括题目、答案和解析),支持 A/B 双卷模式。 --- ## 技术栈 | 分类 | 技术/工具 | 版本/说明 | |------|-----------|-----------| | 核心框架 | Spring Boot | 3.3.4 | | 开发语言 | Java | 17 | | ORM框架 | MyBatis Plus | 3.5.7 | | 数据库 | H2 Database | 文件型数据库(`./data/paper_db`) | | 模板简化 | Lombok | 可选依赖,简化 POJO 代码 | | 参数校验 | Spring Validation | 请求参数校验 | | JSON处理 | Jackson | Spring Boot 内置 JSON 处理 | | LLM集成 | LangChain4j + 通义千问百炼 | 1.0.0 + langchain4j-community-dashscope:1.0.0-beta5 | | 模型 | qwen3.6-flash | 阿里云百炼平台 | --- ## 项目结构 ``` TestPaperG/ ├── pom.xml # Maven 依赖配置 ├── src/ │ ├── main/ │ │ ├── java/org/example/ │ │ │ ├── PaperApplication.java # Spring Boot 启动类 │ │ │ ├── HelloController.java # 测试控制器 │ │ │ ├── config/ │ │ │ │ ├── LlmConfig.java # LLM Bean 配置(LangChain4j 1.0+) │ │ │ │ └── LlmProperties.java # LLM 配置属性类 │ │ │ ├── agent/ # 试卷生成智能体核心模块 │ │ │ │ ├── PaperModifyAgent.java # 试卷修改 Agent 接口(AiServices) │ │ │ │ ├── controller/ │ │ │ │ │ ├── PaperAgentController.java # 生成控制器 │ │ │ │ │ ├── PaperModifyController.java # 修改控制器 │ │ │ │ │ └── PdfExportController.java # PDF 导出控制器 │ │ │ │ ├── config/ │ │ │ │ │ └── PaperModifyAgentConfig.java # AiServices 配置 │ │ │ │ ├── service/ │ │ │ │ │ ├── PaperAgentService.java # 核心业务逻辑 │ │ │ │ │ ├── PaperModifyService.java # 修改业务逻辑 │ │ │ │ │ └── PdfGenerationService.java # PDF 生成服务 │ │ │ │ ├── prompt/ │ │ │ │ │ ├── PaperPromptBuilder.java # Prompt 工程构建 │ │ │ │ │ └── PaperAgentPrompt.java # Agent Prompt 定义 │ │ │ │ ├── llm/ │ │ │ │ │ ├── LlmClient.java # LLM 客户端(LangChain4j 1.0+) │ │ │ │ │ └── LlmGenerationResult.java # LLM 生成结果模型 │ │ │ │ ├── tools/ │ │ │ │ │ ├── PaperTools.java # 生成 Agent 工具集 │ │ │ │ │ ├── PaperModifyTools.java # 修改 Agent 工具集 │ │ │ │ │ └── ToolCallLog.java # 工具调用日志 │ │ │ │ ├── dto/ │ │ │ │ │ ├── PaperGenerateRequest.java # 生成请求 DTO │ │ │ │ │ ├── PaperGenerateResponse.java # 生成响应 DTO │ │ │ │ │ ├── PaperModifyRequest.java # 修改请求 DTO │ │ │ │ │ └── PaperModifyResponse.java # 修改响应 DTO │ │ │ │ ├── parse/ │ │ │ │ │ ├── PaperParseResult.java # 解析结果模型 │ │ │ │ │ └── PaperJsonParser.java # JSON 解析器 │ │ │ │ ├── format/ │ │ │ │ │ └── PaperTextFormatter.java # 试卷文本格式化 │ │ │ │ └── compare/ │ │ │ │ ├── PaperSimilarityResult.java # 相似度结果 │ │ │ │ └── PaperSimilarityComparator.java # 相似度比较器 │ │ │ └── paper/ │ │ │ ├── controller/ │ │ │ │ └── PaperRecordController.java # 试卷记录控制器 │ │ │ ├── service/ │ │ │ │ └── PaperRecordService.java # 试卷记录服务 │ │ │ └── persistence/ │ │ │ ├── entity/ │ │ │ │ └── PaperGenerationRecord.java # 试卷记录实体 │ │ │ └── mapper/ │ │ │ └── PaperGenerationRecordMapper.java # MyBatis Mapper │ │ └── resources/ │ │ └── application.yml # 应用配置文件 │ └── test/ │ └── java/org/example/ # 测试代码目录 └── data/ # H2 数据库文件目录 └── paper_db.mv.db ``` --- ## 快速开始 ### 环境要求 - JDK 17 或更高版本 - Maven 3.6+ ### 运行步骤 **1. 克隆并进入项目目录** ```bash cd TestPaperG ``` **2. 配置 LLM API Key(可选)** 编辑 `src/main/resources/application.yml`,填入你的通义千问百炼 API Key: ```yaml langchain4j: community: dashscope: chat-model: api-key: "your-api-key-here" model-name: qwen3.6-flash-2026-04-16 ``` **3. 编译打包** ```bash mvn clean package -DskipTests ``` **4. 运行应用** ```bash mvn spring-boot:run ``` 或直接运行 JAR 包: ```bash java -jar target/TestPaperG-1.0-SNAPSHOT.jar ``` **5. 访问服务** - 服务地址: http://localhost:10000 - H2 控制台: http://localhost:10000/h2-console - JDBC URL: `jdbc:h2:file:./data/paper_db` - 用户名: `sa` - 密码: `password` --- ## API 文档 ### 基础测试接口 #### GET /hello 健康检查接口,返回当前配置的模型信息。 **响应示例:** ```json { "message": "Hello! Current model: qwen3.6-flash" } ``` --- ### 试卷生成接口 #### POST /api/agent/papers/generate 生成试卷的核心接口。 **请求头:** ``` Content-Type: application/json ``` **请求体参数:** | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | `subject` | String | 是 | 科目名称,如"高等数学" | | `title` | String | 是 | 试卷标题,如"2024-2025学年第一学期期末考试" | | `knowledgePoints` | List\ | 是 | 知识点列表,如\["函数极限","导数运算"\] | | `totalScore` | Integer | 是 | 试卷总分,如 100 | | `durationMinutes` | Integer | 是 | 考试时长(分钟),如 120 | | `questionTypeCounts` | Object | 是 | 题型数量分布(见下方结构) | | `scoreDistribution` | Object | 否 | 各题型分值分布(见下方结构) | | `difficultyLevel` | Integer | 否 | 难度等级(1-5),默认为 3 | | `generateAB` | Boolean | 否 | 是否生成 A/B 双卷,默认 false | | `includeAnswer` | Boolean | 否 | 是否包含答案解析,默认 true | | `reminders` | String | 否 | 额外要求或提醒 | **题型数量分布结构(questionTypeCounts):** ```json { "SINGLE_CHOICE": 15, "MULTIPLE_CHOICE": 5, "TRUE_FALSE": 10, "FILL_BLANK": 10, "ESSAY": 2, "CALCULATION": 3 } ``` 支持的题型:`SINGLE_CHOICE`(单选)、`MULTIPLE_CHOICE`(多选)、`TRUE_FALSE`(判断)、`FILL_BLANK`(填空)、`ESSAY`(简答/论述)、`CALCULATION`(计算) **分值分布结构(scoreDistribution):** ```json { "SINGLE_CHOICE": 2, "MULTIPLE_CHOICE": 4, "TRUE_FALSE": 1, "FILL_BLANK": 3, "ESSAY": 8, "CALCULATION": 10 } ``` **请求示例:** ```json { "subject": "高等数学", "title": "2024-2025学年第一学期期末考试", "knowledgePoints": ["函数极限", "导数运算", "微分中值定理", "不定积分"], "totalScore": 100, "durationMinutes": 120, "questionTypeCounts": { "SINGLE_CHOICE": 10, "MULTIPLE_CHOICE": 5, "TRUE_FALSE": 10, "FILL_BLANK": 5, "CALCULATION": 4 }, "scoreDistribution": { "SINGLE_CHOICE": 3, "MULTIPLE_CHOICE": 4, "TRUE_FALSE": 1, "FILL_BLANK": 5, "CALCULATION": 10 }, "difficultyLevel": 3, "generateAB": false, "includeAnswer": true, "reminders": "选择题部分请使用标准格式,答案解析要详细" } ``` **cURL 调用示例:** ```bash curl -X POST http://localhost:10000/api/agent/papers/generate \ -H "Content-Type: application/json" \ -d '{ "subject": "高等数学", "title": "2024-2025学年第一学期期末考试", "knowledgePoints": ["函数极限", "导数运算"], "totalScore": 100, "durationMinutes": 120, "questionTypeCounts": { "SINGLE_CHOICE": 5, "FILL_BLANK": 3 } }' ``` --- #### GET /api/agent/status 查询智能体状态。 **响应示例:** ```json { "status": "ready", "model": "qwen3.6-flash-2026-04-16", "llmProvider": "qwen-bailian" } ``` --- ### 试卷修改接口 #### POST /api/agent/papers/modify 通过 AI Agent 修改试卷内容。 **请求体参数:** | 参数 | 类型 | 必填 | 说明 | |------|------|------|------| | `recordId` | Long | 是 | 试卷记录 ID | | `modificationPrompt` | String | 是 | 修改要求描述 | **请求示例:** ```json { "recordId": 1, "modificationPrompt": "把第3题的难度调高,增加一道计算题" } ``` --- ## 配置说明 ### 核心配置文件 `src/main/resources/application.yml` ```yaml server: port: 10000 spring: application: name: TestPaperG datasource: url: jdbc:h2:file:./data/paper_db # H2 文件数据库路径 driver-class-name: org.h2.Driver username: sa password: password h2: console: enabled: true # 启用 H2 控制台 settings: web-allow-others: true # 允许远程访问 mybatis-plus: configuration: map-underscore-to-camel-case: true # 下划线转驼峰 # LangChain4j DashScope 配置(langchain4j 1.0+ 使用 langchain4j-community) langchain4j: community: dashscope: chat-model: api-key: your-api-key-here model-name: qwen3.6-flash-2026-04-16 temperature: 0.4 top-p: 0.8 max-tokens: 8000 llm: provider: qwen-bailian model: qwen3.6-flash-2026-04-16 ``` ### LLM 配置属性说明 | 配置项 | 说明 | 默认值 | |--------|------|--------| | `langchain4j.community.dashscope.chat-model.api-key` | 通义千问百炼 API Key | 必填 | | `langchain4j.community.dashscope.chat-model.model-name` | 使用的模型名称 | `qwen-plus` | | `langchain4j.community.dashscope.chat-model.temperature` | 生成温度(0-1),越高越有创意 | 0.7 | | `langchain4j.community.dashscope.chat-model.top-p` | Top-p 采样参数 | 0.8 | | `langchain4j.community.dashscope.chat-model.max-tokens` | 最大生成 token 数 | 4096 | --- ## 核心模块设计 ### 1. LLM 客户端层 (`agent/llm/`) 采用 LangChain4j 1.0+ 的 `ChatModel` API: - **`LlmClient`**: LLM 客户端,通过 `QwenChatModel` 调用 DashScope API - **`LlmGenerationResult`**: LLM 生成结果的数据模型 ```text ┌─────────────────────┐ │ QwenChatModel │ │ (langchain4j 1.0+) │ └──────────┬──────────┘ │ ▼ ┌─────────────────────────────────┐ │ 通义千问百炼 API │ │ (dashscope.aliyuncs.com) │ └─────────────────────────────────┘ ``` ### 2. Agent 层 (`agent/`) 使用 LangChain4j `AiServices` 构建 Agent: - **`PaperModifyAgent`**: 通过 `@SystemMessage` 定义 Agent 行为,支持工具调用 - **`PaperModifyTools`**: 提供 `fetchPaperById`、`saveModifiedPaper`、`listRecentPapers` 等工具 - **`PaperModifyAgentConfig`**: 使用 `AiServices.builder().chatModel(...).tools(...)` 构建 ### 3. Prompt 工程层 (`agent/prompt/`) **`PaperPromptBuilder`** 负责构建高质量的 Prompt: - 将用户请求转换为结构化的自然语言 Prompt - 指定输出格式为标准 JSON - 包含题型、分值、知识点等约束条件 - 添加系统角色和输出格式说明 **`PaperAgentPrompt`** 定义 Agent 的 `@SystemMessage` 和 `@UserMessage` 注解。 ### 4. 业务服务层 (`agent/service/`) - **`PaperAgentService`**: 核心试卷生成业务逻辑 - **`PaperModifyService`**: 试卷修改业务逻辑,调用 Agent 执行 - **`PdfGenerationService`**: PDF 文件生成服务 --- ## 业务流程 ``` ┌──────────────┐ │ HTTP │ │ Request │ └──────┬──────┘ │ ▼ ┌──────────────────────────────────────────────────┐ │ PaperAgentController │ │ (参数校验 + 路由) │ └──────────────────────┬───────────────────────────┘ │ ▼ ┌──────────────────────────────────────────────────┐ │ PaperAgentService │ │ 1. 构建 Prompt (PaperPromptBuilder) │ │ 2. 调用 LLM (LlmClient → QwenChatModel) │ │ 3. 解析 JSON 结果 │ │ 4. 组装响应数据 │ └──────────────────────┬───────────────────────────┘ │ ▼ ┌─────────────────────────────────┐ │ 通义千问百炼 API │ │ (dashscope.aliyuncs.com) │ │ qwen3.6-flash 模型 │ └─────────────────────────────────┘ ``` --- ## 扩展指南 ### 更换模型 在 `application.yml` 中修改 `model-name`: ```yaml langchain4j: community: dashscope: chat-model: model-name: qwen-plus # 更换为其他支持的模型 ``` ### 添加新的 LLM 提供商 1. 引入对应的 `langchain4j-community-*-spring-boot-starter` 2. 在 `application.yml` 中配置对应的命名空间 3. 在 `LlmConfig` 中注册对应的 `ChatModel` Bean ### 添加新的工具 在 `PaperModifyTools` 或 `PaperTools` 中添加 `@Tool` 注解的方法,`AiServices` 会自动将其暴露给 Agent 调用。 ```java @Tool("工具描述") public ReturnType toolMethod(ParamType param) { // 工具实现 } ``` --- ## 待完成功能(TODO) - [ ] 支持更多模型(如 qwen3.6-plus、qwen3-vl 等) - [ ] 实现 A/B 卷差异度校验与自动重生成 - [ ] 增加结果落库与生成历史记录 - [ ] 补充单元测试和联调测试用例 - [ ] 添加更多 LLM 提供商支持(如 OpenAI、Claude 等) --- ## 数据库说明 项目使用 H2 文件数据库,数据库文件位于 `./data/paper_db.mv.db`。 **H2 控制台访问信息:** - URL: http://localhost:10000/h2-console - JDBC URL: `jdbc:h2:file:./data/paper_db` - 用户名: `sa` - 密码: `password` --- ## 开发说明 ### 代码规范 - 使用 Lombok 简化 POJO 代码 - Controller 层进行参数校验(使用 `@Valid` 注解) - Service 层处理业务逻辑 - DTO 类使用 JSR-303 校验注解 ### 调试建议 1. 启用 H2 控制台查看数据库状态 2. 查看应用日志了解 LLM 调用详情 3. 在 `application.yml` 中设置 `langchain4j.community.dashscope.chat-model.api-key` 为空可进入错误模式 --- ## License 本项目仅供学习和研究使用。