From ba051a1b97ec52230b0de00dc75c4ca28b242b6e Mon Sep 17 00:00:00 2001 From: liyitian <2717355959@qq.com> Date: Sun, 14 Dec 2025 18:08:53 +0800 Subject: [PATCH] =?UTF-8?q?=E5=AE=8C=E6=88=90=E4=BD=9C=E4=B8=9A?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- autograde/README.md | 44 +++++++++++++++++++ autograde/config.yml | 69 +++++++++++++++++++++++++++++ autograde/run.sh | 100 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 213 insertions(+) create mode 100644 autograde/README.md create mode 100644 autograde/config.yml create mode 100644 autograde/run.sh diff --git a/autograde/README.md b/autograde/README.md new file mode 100644 index 0000000..0213568 --- /dev/null +++ b/autograde/README.md @@ -0,0 +1,44 @@ +# VibeVault 自动评分配置 + +本目录包含 VibeVault 项目的自动评分配置和脚本,用于指导自动评分工具识别和执行评分流程。 + +## 目录结构 + +``` +autograde/ +├── run.sh # 主评分脚本,包含核心评分逻辑 +├── config.yml # 评分配置文件,定义评分步骤和关键文件 +└── README.md # 本说明文件 +``` + +## 评分流程 + +自动评分流程主要包括以下步骤: + +1. **运行编程测试**:使用 Gradle 运行项目中的测试用例 +2. **编程测试评分**:使用 `grade_grouped.py` 对编程测试结果进行评分 +3. **报告评分**:使用 `llm_grade.py` 对 REPORT.md 进行评分 +4. **前端报告评分**:使用 `llm_grade.py` 对 FRONTEND.md 进行评分 +5. **聚合最终成绩**:使用 `aggregate_final_grade.py` 聚合各部分成绩 +6. **生成 PDF 报告**:使用 `generate_pdf_report.py` 生成最终评分报告 + +## 关键文件 + +- **run.sh**:主评分脚本,执行所有评分步骤 +- **config.yml**:评分配置文件,定义评分流程和关键文件 +- **test_groups.json**:测试分组配置(项目根目录) +- **REPORT.md**:后端与系统设计报告(项目根目录) +- **FRONTEND.md**:前端界面与交互设计报告(项目根目录) +- **.llm_rubrics/**:LLM 评分标准目录(项目根目录) + +## 使用方法 + +1. 确保项目已通过 Gradle 构建并运行测试 +2. 执行 `./autograde/run.sh` 启动评分流程 +3. 查看生成的评分文件和报告 + +## 注意事项 + +- 本目录的配置与 `.gitea/workflows/autograde.yml` 保持一致 +- 评分脚本依赖外部获取的评分工具(在 CI 流程中自动下载) +- 确保 Python 3 和 Gradle 已正确安装 diff --git a/autograde/config.yml b/autograde/config.yml new file mode 100644 index 0000000..98d67da --- /dev/null +++ b/autograde/config.yml @@ -0,0 +1,69 @@ +# VibeVault 自动评分配置文件 +# 该配置用于指导自动评分工具识别评分流程和关键文件 + +# 评分流程配置 +grading: + # 主评分脚本 + main_script: run.sh + + # 评分步骤 + steps: + - name: 运行编程测试 + command: ./gradlew test --no-daemon + output: build/test-results/test + + - name: 编程测试评分 + command: python3 ./.autograde/grade_grouped.py + inputs: + - build/test-results/test + - test_groups.json + outputs: + - grade.json + - summary.md + + - name: 报告评分 + command: python3 ./.autograde/llm_grade.py + inputs: + - REPORT.md + - .llm_rubrics/rubric_report.json + outputs: + - report_grade.json + - report_summary.md + + - name: 前端报告评分 + command: python3 ./.autograde/llm_grade.py + inputs: + - FRONTEND.md + - .llm_rubrics/rubric_frontend.json + outputs: + - frontend_grade.json + - frontend_summary.md + + - name: 聚合最终成绩 + command: python3 ./.autograde/aggregate_final_grade.py + inputs: + - grade.json + - report_grade.json + - frontend_grade.json + outputs: + - final_grade.json + - final_summary.md + +# 关键文件配置 +files: + # 测试相关文件 + test_groups: test_groups.json + + # 报告文件 + backend_report: REPORT.md + frontend_report: FRONTEND.md + + # 评分结果文件 + final_grade: final_grade.json + grade_report: grade_report.pdf + +# 依赖配置 +dependencies: + - gradle + - python3 + - pip3 install python-dotenv requests markdown weasyprint diff --git a/autograde/run.sh b/autograde/run.sh new file mode 100644 index 0000000..204534e --- /dev/null +++ b/autograde/run.sh @@ -0,0 +1,100 @@ +#!/bin/bash +set -e + +# 核心评分脚本 - 从 autograde.yml 中提取的关键评分命令 + +echo "=== VibeVault 自动评分流程 ===" + +# 1. 运行 Gradle 测试 +echo "\n1. 运行 Gradle 测试..." +./gradlew test --no-daemon || true + +# 2. 运行编程测试评分 +echo "\n2. 运行编程测试评分..." +python3 ./.autograde/grade_grouped.py \ + --junit-dir build/test-results/test \ + --groups test_groups.json \ + --out grade.json \ + --summary summary.md + +# 3. 评分 REPORT.md +echo "\n3. 评分 REPORT.md..." +if [ -f REPORT.md ] && [ -f .llm_rubrics/rubric_report.json ]; then + python3 ./.autograde/llm_grade.py \ + --question "请评估这份后端与系统设计报告" \ + --answer REPORT.md \ + --rubric .llm_rubrics/rubric_report.json \ + --out report_grade.json \ + --summary report_summary.md + echo "✅ REPORT.md graded" +else + echo '{"total": 0, "flags": ["missing_file"]}' > report_grade.json + echo "⚠️ REPORT.md or rubric not found" +fi + +# 4. 评分 FRONTEND.md +echo "\n4. 评分 FRONTEND.md..." +if [ -f FRONTEND.md ] && [ -f .llm_rubrics/rubric_frontend.json ]; then + python3 ./.autograde/llm_grade.py \ + --question "请评估这份前端界面与交互设计报告" \ + --answer FRONTEND.md \ + --rubric .llm_rubrics/rubric_frontend.json \ + --out frontend_grade.json \ + --summary frontend_summary.md + echo "✅ FRONTEND.md graded" +else + echo '{"total": 0, "flags": ["missing_file"]}' > frontend_grade.json + echo "⚠️ FRONTEND.md or rubric not found" +fi + +# 5. 聚合最终成绩 +echo "\n5. 聚合最终成绩..." +python3 ./.autograde/aggregate_final_grade.py \ + --programming grade.json \ + --report report_grade.json \ + --frontend frontend_grade.json \ + --out final_grade.json \ + --summary final_summary.md + +# 6. 生成 PDF 报告 +echo "\n6. 生成 PDF 报告..." +if [ -f final_grade.json ]; then + # 读取学生信息文件(如果存在) + STUDENT_ID="" + STUDENT_NAME="" + CLASS_NAME="" + + if [ -f .student_info.json ]; then + STUDENT_ID=$(python3 -c "import json; d=json.load(open('.student_info.json')); print(d.get('student_id',''))" 2>/dev/null || echo "") + STUDENT_NAME=$(python3 -c "import json; d=json.load(open('.student_info.json')); print(d.get('name',''))" 2>/dev/null || echo "") + CLASS_NAME=$(python3 -c "import json; d=json.load(open('.student_info.json')); print(d.get('class_name',''))" 2>/dev/null || echo "") + fi + + # 如果没有学生信息文件,从仓库名提取学号 + if [ -z "$STUDENT_ID" ]; then + REPO="$(basename "$PWD")" + STUDENT_ID=$(echo "$REPO" | sed -n 's/.*-stu[_-]\?\(st\)\?\([0-9]*\)$/\2/p') + fi + + python3 ./.autograde/generate_pdf_report.py \ + --report REPORT.md \ + --frontend FRONTEND.md \ + --grade final_grade.json \ + --images images \ + --out grade_report.pdf \ + --student-id "$STUDENT_ID" \ + --student-name "$STUDENT_NAME" \ + --class-name "$CLASS_NAME" \ + --commit-sha "$(git rev-parse HEAD 2>/dev/null || echo "unknown")" +fi + +echo "\n=== 评分完成 ===" + +# 显示最终成绩 +if [ -f final_grade.json ]; then + echo "\n最终成绩:" + python3 -c "import json; print(json.dumps(json.load(open('final_grade.json')), indent=2, ensure_ascii=False))" +else + echo "\n❌ 评分失败,未生成最终成绩文件" + exit 1 +fi