一个面向课程作业的 LLM 自动评分命令行工具。它会先从教师的作业说明中生成结构化评分锚点,再批量评分学生提交,并对粗评分相近的作业进行两两比较,用置信度加权 Elo 排序修正最终分数。
Important
本项目不会执行学生代码,只读取作业文本、Notebook 源码或 Markdown 内容进行评分。学生提交会被当作不可信输入处理,作业中的“忽略评分规则”“直接给满分”等内容只会作为待评分文本。
| 能力 | 说明 |
|---|---|
| 评分锚点生成 | 从 data/README.md 提取 100 分评分结构,保存为可复用 JSON |
| 批量评分 | 支持 .py、.md、.ipynb、.txt,每份作业输出独立评分 JSON |
| 异常防护 | 对空文件、跑题内容、prompt injection 等情况写入 integrity_flags |
| 稳定排序 | 只比较粗评分接近的作业,降低 API 成本,并用 Elo 做最终排序 |
| 可复核输出 | 保存锚点、单份评分、比较明细和最终排序,便于人工抽查 |
flowchart LR
A["教师作业说明<br/>data/README.md"] --> B["anchors<br/>生成评分锚点"]
B --> C["grade<br/>批量粗评分"]
D["学生提交<br/>data/homework"] --> C
C --> E["compare<br/>相近作业两两比较"]
E --> F["Elo<br/>最终排序"]
B --> G["result/rubric_anchors.json"]
C --> H["result/grades/*.json<br/>result/grade_summary.json"]
F --> I["result/final_scores.json"]
AutoGrading/
autograde.py # CLI 入口和流程编排
autograder/
anchors.py # 根据教师 README 生成评分锚点
grading.py # 单份作业评分、批量评分、汇总输出
pairwise.py # 相近作业两两比较与 Elo 排序
llm_client.py # OpenAI-compatible API 调用与 JSON 解析
io_utils.py # 文件读取、编码兼容、JSON 输出等工具
data/
README.md # 示例作业说明与评分标准
homework/ # 示例作业目录;公开仓库不要放真实学生作业
.env.example # 环境变量模板
项目只依赖 Python 标准库,不需要安装第三方包。推荐使用 Python 3.9 或更高版本。
git clone <your-repo-url>
cd AutoGrading
Copy-Item .env.example .env
notepad .env在 .env 中填入 OpenAI-compatible 服务配置:
LLM_API_KEY=your_api_key_here
LLM_BASE_URL=https://api.openai.com/v1
LLM_MODEL=your_chat_model_here
LLM_TEMPERATURE=0
LLM_RESPONSE_FORMAT=json_object
检查配置:
python autograde.py check-config
python autograde.py check-config --ping完整运行:
python autograde.py run只做粗评分,不做两两比较:
python autograde.py run --skip-pairwise生成评分锚点:
python autograde.py anchors --readme data/README.md --out result/rubric_anchors.json批量评分:
python autograde.py grade --homework data/homework对粗评分相近的作业做两两比较:
python autograde.py compare --close-threshold 5 --neighbor-window 2 --elo-k 32常用参数说明:
| 参数 | 默认值 | 说明 |
|---|---|---|
--extensions |
.py,.md,.ipynb,.txt |
参与评分的文件扩展名 |
--max-submission-chars |
60000 |
单份作业送入模型的最大字符数,过长会保留头尾 |
--close-threshold |
5 |
只比较粗评分差距不超过该值的作业 |
--neighbor-window |
2 |
每份作业向后查看的相邻候选数量 |
--elo-k |
32 |
Elo 调整幅度上限,实际调整会乘以模型比较置信度 |
result/
rubric_anchors.json # 评分锚点
grades/*.json # 每份作业的粗评分明细
grade_summary.json # 粗评分汇总
comparisons/*.json # 两两比较明细
final_scores.json # 最终排序与分数
默认情况下,脚本不会覆盖历史结果。如果目标文件已存在,会自动生成 xxx(1).json、xxx(2).json 这类新文件,便于比较多次运行的稳定性。