Files
ClassFeedback/.pi/skills/class-feedback-report/SKILL.md

232 lines
18 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
name: class-feedback-report
description: 按班组整理 OJ 课堂反馈:自动定位课程与章节、拉取全班逐生逐次提交(代码+编译报错+状态),产出「第N次提交错在哪 → 整体分析 → 建议」的学生诊断报告草稿(MD+HTML+PDF),供带班教师审核后使用。老师说「引导我进行操作」「帮我处理本项目」「整理课堂反馈」「学生分析报告」时使用本技能;引导模式会带着老师一步步完成环境检查、账号配置与报告生成。
---
# Skill: 班级课堂反馈与提交诊断
按班级生成每位学生的提交诊断报告(第一次提交错在哪、第二次错在哪……整体分析、建议),
数据全部来自 HydroOJ 课程插件的只读 API,**评价与建议由 AI 起草、教师审核后才能发给学生/家长**。
关键词:`课堂反馈`、`提交诊断`、`错误分析`、`班级报告`、`学生分析`、`整理反馈`、`引导我进行操作`、`帮我处理本项目`
## 操作引导模式(老师第一次使用,或说「引导我进行操作」「帮我处理本项目」时从这里开始)
面向不熟悉命令行的老师:AI 按下面清单**逐步执行并代替老师敲命令**,每完成一步简短汇报再进行下一步。
老师只需要回答问题(用哪个站、账号密码、哪个班级)。
1. **仓库准备(第一次必做,老师只回答问题)**:问老师姓名/工号 → 仓库地址默认
`https://git.qonnwolf.com/<工号>/ClassFeedback`(**机构仓库名统一 ClassFeedback**,
git 服务 git.qonnwolf.com)。
- 已有本地克隆 → 进入仓库目录 `git pull`;
- 没有 → 引导老师在 git.qonnwolf.com 网页生成**访问令牌**(设置 → 应用 → 访问令牌,
勾选 repository 读写),令牌让老师填进仓库根 `.env` 的 `GIT_TOKEN`(见第 3 步),
然后 `git clone https://git.qonnwolf.com/<工号>/ClassFeedback`(公共克隆不需要令牌,
推送时才用),新老师还没有仓库 → 引导网页建仓(名字必须是 ClassFeedback)或
本地 `git init` + `remote add origin` + 首推;
- 结构自检:`.claude/memory/class/`、`skills/class-feedback-report/`、
`AGENTS.md`、`CLAUDE.md`、`.gitignore`、`.env` 缺失则按包内 `repo-template/` 补建
(`.env` 从 `.env.example` 复制,填好后永不入库)。
2. **环境自检**(自动执行,无需老师操作):`node -v` 需 ≥18;确认本 skill 的
`scripts/fetch-class-data.mjs`、`scripts/check-login.mjs`、`scripts/mkpdf.mjs` 存在;
Windows 确认 Edge 已安装(PDF 用)。有缺项先解决缺项再继续。
3. **配置凭据(.env,一次性;站点固定为 qonnwolf)**:脚本自动读取仓库根 `.env`,
请老师自行编辑填写以下字段(**推荐老师自己填,密码不经过对话**;老师愿意口述时
AI 可代填,填完提醒「.env 不入库」):
```ini
OJ_BASE_URL=https://oj.qonnwolf.com
OJ_USERNAME=你的OJ用户名
OJ_PASSWORD=你的OJ密码
GIT_USER=你的工号
GIT_TOKEN=你的访问令牌
GIT_REPO_URL=https://git.qonnwolf.com/你的工号/ClassFeedback
```
填好后运行 `node scripts/check-login.mjs`(脚本自动读 .env,无需命令行传凭据)验证;
输出 `OK|登录成功…` 才继续;失败按「异常处理」回应老师。
令牌的 git 配置一次性执行:
`git remote set-url origin https://<GIT_USER>:<GIT_TOKEN>@git.qonnwolf.com/<工号>/ClassFeedback`
(存在本地 .git/config,不入库),之后 `git push` 不再需要令牌。
4. **收集班级组名**:请老师提供完整班组名(如「克力周日0830CSP02」)。
老师不确定时:先跑 fetch(不带 --group 会报错,带 --group 才扫课程),或用
`GET /course/api/list` 列出课程标题让老师指认,再从课程页确认组名。
6. **确认章节与花名册(先取小组成员,再分析)**:跑 fetch 后,向老师展示并请其确认:
「班组-课次号」标识(如 克力周日0830CSP02-04)、章节名、**班组花名册(N 人 + 姓名列表)**,
以及班组花名册(N 人 + 姓名列表)。老师确认无误后才进入逐生分析写报告;成员有出入时先解决报名/分组问题。
⚠️ **报告编号用「课次号」(第几次课),不用 OJ 章节号**——章节号(章节标题前缀数字,如「03 二维数组」)
是教材进度,课次号是实际上课序数,两者常差 1~2,混用会与内部正本 `YYYYMMDD_课程编号-课次.md` 对不上。
7. **执行生成(每个学生五件事,缺一不可)**:
① 家长版报告 md/html → `.claude/memory/class/<班组>/<学生名>/<姓名>-<班组>-<课次号>-反馈报告.{md,html}`;
② PDF 同目录本地生成(git 忽略,不入库);
③ **内部课评正本** → 同目录 `feedback/YYYYMMDD_课程编号-课次.md`
(校宝核查口径:每位学生每次课有且仅有一个文件;请假加 `(请假)`、补课加 `(补课-去XX)`;
内容为简明事实:日期、班组、状态、本讲要点、订正情况);
④ **更新画像** → `.claude/memory/class/<班组>/<学生名>/profile.md`(追加本讲表现要点、刷新能力评估);
⑤ 班级汇总 → `.claude/memory/class/<班组>/summaries/YYYYMMDD_班组-课次号_班级反馈.md`。
8. **git 同步**:`git add .claude/memory/class .claude/skills docs`(*.pdf 被 .gitignore 自动排除)→
`git commit -m "课评: <班组>-<课次号> <日期>"` → `git push`;
推送失败(令牌过期/无权限)→ 引导老师重新生成令牌并更新凭据。
9. **交付**:汇报每个学生三件套的文件路径 + 内部正本 + 画像更新情况 + 班级汇总,
并**明确提醒:家长版报告是草稿,审核措辞后才能发学生/家长**。
异常处理(引导模式中随时可能触发):
- 登录失败 → 请老师核对账号密码;确认是教师账号或拥有该班成绩查看权限(普通学生账号不行)。
- 「没有找到包含班组的课程」→ 班组名不全或该班不在所选站;列出可见课程标题协助老师确认。
- analysis 响应慢 → 正常现象(全班粒度重接口),等待即可,不要并发重试。
## 前置条件(跳过引导、直接使用时自行满足)
- Node 18+(自带 fetch);出 PDF 需要 Edge 或 Chrome 浏览器;git(同步课评仓库)。
- **凭据统一放仓库根 `.env`**(从 `.env.example` 复制;已被 .gitignore 排除,绝不提交):
```ini
OJ_BASE_URL=https://oj.qonnwolf.com
OJ_USERNAME=你的OJ用户名
OJ_PASSWORD=你的OJ密码
GIT_USER=你的工号
GIT_TOKEN=你的访问令牌
GIT_REPO_URL=https://git.qonnwolf.com/你的工号/ClassFeedback
```
OJ 账号需要「教师或授权校区查看者」权限(普通学生账号只能看到自己的数据)。
脚本自动向上查找并加载 `.env`;环境变量 `COURSE_API_USERNAME/PASSWORD` 可临时覆盖。
- 凭据只在 `.env` 和 git 凭据里,**不得写进命令行参数、报告或日志**。
## 安装(项目级,随仓库走)
**方式 A(推荐)**:老师直接克隆自己的 ClassFeedback 仓库——新仓库模板已自带本技能
(`skills/class-feedback-report/`),克隆即用。
**方式 B(存量仓库补装)**:把 `class-feedback-report/` 文件夹复制到**项目仓库**的
`skills/` 目录下(与 `.claude/memory/class/` 同在 `.claude/` 内),并在仓库根的 `AGENTS.md` /
`CLAUDE.md` 写明「本项目技能在 skills/ 目录」。**不要装到用户级目录**(~/.zcode、~/.claude)——
技能必须随项目仓库走,老师换 agent、换电脑都只要拉仓库。
## API 使用速查
本 skill 全部基于课程插件的只读 JSON 接口(完整文档见 [docs/API.md](docs/API.md))。
鉴权方式:先 `POST /login`(JSON:`uname` + `password`)拿 `sid` Cookie,后续请求带
`Cookie: sid=...` 和 `Accept: application/json`;脚本自动从仓库根 `.env` 读取凭据。
| 接口 | 用途 | 权限 |
| --- | --- | --- |
| `GET /course/api/list?page=N` | 列出可见课程(定位班组所在课程) | 已登录 |
| `GET /course/api/detail/:cid` | 课程与章节结构 | 可访问该课程 |
| `GET /course/api/v1/courses/:cid/students?group=班组名` | 按班组拉花名册 | 教师或授权查看者 |
| `GET /course/api/v1/courses/:cid/sections/:csid/feedback/overview?group=` | 章节班级统计(完成率、首刷率) | 教师或授权查看者 |
| `GET /course/api/v1/courses/:cid/sections/:csid/feedback/students?group=&limit=100` | 逐生统计信号 | 教师或授权查看者 |
| `GET /course/api/v1/courses/:cid/sections/:csid/feedback/students/:uid` | 单生逐题证据(无代码) | 教师或授权查看者 |
| `GET /course/api/analysis/:cid/:csid?withCode=true&withHistory=true` | **全班提交历史+代码+编译报错**(重接口,每次运行只调一次) | 教师或授权查看者 |
| `GET /p/<pid>` | 客观题题干与选项(HTML,脚本已自动解析) | 可见该题 |
注意:`withHistory=true` 必须带上,否则 history 全空;响应为全章节全班粒度(数百 KB),按需使用。
## 使用流程
### 1. 抓取班级数据(脚本自动完成)
```bash
node "<skill目录>/scripts/fetch-class-data.mjs" \
--group="克力周日0830CSP02" \
--base-url="https://oj.qonnwolf.com" \
--out="F:\HydroOJ\artifacts\class-feedback\digest-<班级名>.json"
```
- 脚本自动:定位含该班组的课程(多门时优先「秋季」并在 stderr 提示)、选最后一个有提交活动的章节、
拉花名册、调 `analysis?withCode=true&withHistory=true` 一次性取全班提交历史;
**自动识别客观题**(提交内容是答案卷的题)并抓取题干与选项存入 `objective[pid].questions`
(每个问题含 `no/text/options[]`,katex 拆行已合并处理)。
- 可选参数:`--course=<cid>` 指定课程、`--section=<csid>` 指定章节、`--uid=<uid>` 只整理某个学生。
- 产出 digest JSON:每生 `{stats 信号, problems:[{pid,title,submissions:[{seq,status,score,errorHead,code}]}]}`。
### 2. 阅读原料,逐生写诊断
读 digest(大班可分生读取)。**一名学生一个 MD 文件 + 一个自包含 HTML 文件**(内嵌 CSS,可直接转发/打印)。
每个非 AC 提交都要给出**人话结论**,判定规则:
| 状态 | 判定方法 | 人话示例 |
| --- | --- | --- |
| CE | 直接读 `errorHead`(gcc 报错带行号) | 变量没有定义 / 少分号 / 函数名写错(print→printf)/ 重复定义 / 输入输出符号写反 |
| WA | 读 `code` 对照题意;有 AC 版时做 diff,差异处即病因 | 数组开小了 / 边界条件差一个等于号 / 输出少换行 / 变量没初始化 / 输出没按题意保留小数位 |
| TLE | 读 `code` 看循环 | 循环条件写错死循环(`1<=T` 恒真)/ 方向写反 / 漏读入起点 / 算法太慢 |
| RE | 读 `code` | 数组越界 / 除零 |
**多鼓励**:报告必须有「🌟 值得表扬的地方」卡片放在最前;一遍通过的题写「一遍通过,非常不错!」;
订正到底的写韧劲;AC 版代码写得好的点名夸(如「min 用得干脆利落」)。表扬必须基于事实,不许编造。
整体分析先扬后抑:亮点在前,习惯问题在后;建议用编号列表给可执行动作。
**客观题(选择/判断)特殊处理——不写提交历史,直接给错题+题目分析+选项**:
这类题学生只能提交对/错,会反复试答案,所以报告直接列出「答错的题」:
1. 取标准答案:用该题**全部学生 AC 卷交叉比对**(≥2 人一致即认定),无需教师提供答案。
2. 学生 WA 卷与标准答案逐题 diff → 得出每题「答错次数」和「答案轨迹」。
3. 题干与选项直接用 digest 的 `objective[pid].questions`(脚本已抓取);若缺失再手工
GET `<base-url>/p/<pid>` 提取。
4. 每道错题输出:题干原文 + **完整选项(逐项列出)** + 你的答案轨迹 + 正确答案 + 考点分析
(一段人话讲透为什么;选项里的陷阱项要点名,如「−1.2 是诱导你按小数除法算的」)。
5. 开头加一句提示:「客观题不建议反复提交试答案,错的就是没弄懂的知识点」。
**整体分析**要跨题目归纳习惯问题,可用的典型模式:
- 多题首刷全 CE → 没编译就直接提交,粗心;
- 变量未声明/未初始化反复出现 → 声明与初始化意识弱;
- WA 集中在边界/格式 → 审题不细,输出格式(换行、小数位)没对题面;
- 反复「交一发试试」→ 概念不清靠猜,订正态度好但方法不对;
- 大量提交后全部 AC → 订正能力强(要点名表扬的亮点);
- 一次通过率高 → 基础扎实(可建议进拓展)。
### 3. 按固定模板输出报告(一人一 MD + 一 HTML)
**MD 结构**(顺序固定):
```markdown
# 学生提交诊断报告 · <姓名>
> 班级/章节/日期/审核稿声明 + 📊 总览(进度、首刷%、提交次数)
## 🌟 值得表扬的地方 ← 放最前,2~4 条事实型表扬
## 💻 编程题逐题诊断 ← 每题一个小节:第一次提交…第N次提交:通过 + 📌复盘框
## 📝 选择题 · 错题分析 ← 只列答错的题:题干/答案轨迹/正确答案/考点分析
## 📝 判断题 · 错题分析 ← 同上
## 📖 整体分析 ← 先扬后抑
## ✅ 给<姓名>的建议 ← 3~4 条可执行动作
```
**HTML**:与 MD 同名 `.html`,自包含单文件(内嵌 CSS、无外部依赖、可打印)。**受众是家长**,设计以
「读起来舒服、看得懂」为先(v2 定稿规范,经用户确认):
- **样式参考(必须先读)**:`samples/report-sample.html` 与 `samples/report-sample.md`——
生成任何报告前先读样例,**完整复用其 CSS、卡片结构、徽章配色与文案语气,只替换内容**,
确保所有 AI 产出的报告观感一致。
- 暖色纸感背景(#faf8f4)+ 白卡片,基础字号 ≥16.5px、行距 ≥1.9;max-width 820px;移动端断点适配;
- 🌟表扬绿卡前置;📊完成情况用**进度条**可视化(课堂/作业/拓展),**不带图例行**;
- 编程题时间线的状态徽章用**家长能懂的话**:✍️ 写错语法(CE)/ 🔄 结果不对(WA)/ ⏱️ 运行超时(TLE)/ 🎉 通过(AC);
- 客观题错题卡:题干引用块 + **选项逐项格子**(正确选项绿框 ✓、孩子错选橙框)+ 答案轨迹 + 💡考点黄框;
- 结尾「📖 老师的整体评价」**先扬后抑**;「接下来要养的小习惯」**每个分点独立成行**(①②③各一段);
- **不要**「写给家长的话」导读卡、不要「在家可以这样帮孩子」模块、不要小图标图例(用户已确认去掉);
- 「教师审核稿」提示缩为一行小字置顶(不放大横幅),术语尽量翻译成生活语言;
- **PDF 导出(v2 定稿:单页长图式,标准宽 **660px**,桌面布局、单页无分页)**:`scripts/mkpdf.mjs <html> <pdf>`
两遍法——先用无头 Edge 在 660px 视口量内容真实高度,再以 `@page{size:660px <高度+120>px; margin:0}`
输出**一整页** PDF(零页边距、颜色保真、自动剔除悬浮按钮与审核稿行)。
用法:`node scripts/mkpdf.mjs 报告.html 报告.pdf`(中文路径已内置 ASCII 临时名处理)。
- **交付三件套与命名(用户定稿)**:每名学生 3 个文件、**统一命名**
`<姓名>-<班组>-<课次号>-反馈报告.{md,html,pdf}`,
例:`王凯平-克力周日0830CSP02-04-反馈报告.md / .html / .pdf`。
**「班组-课次号」(如 克力周日0830CSP02-04)必须同时出现在文件名和报告标题里**——它说明
是哪个班、**第几次课**;章节名(如「二维数组图形」)写在报告标题的副行。
⚠️ **课次号 = 本学期第几次课(与内部正本 `YYYYMMDD_课程编号-课次.md` 一致),不是 OJ 章节号**。
OJ 章节号(章节标题前缀数字)只可在报告内文提及(如「OJ 章节:03 二维数组」),不得用于文件名。
班级汇总命名 `<班组>-<课次号>-反馈汇总-<日期>.md`。
同时生成班级汇总 MD(整体表 + 共性问题 + 教师跟进优先级),命名
`<班级>-<章节>-反馈汇总-<日期>.md`;全部产物建议放同一个输出目录(如 `class-feedback\`),
三件套命名以「**姓名-课程阶段-章节-反馈报告**」为准。
### 4. 审核红线(必须写进每次交付说明)
- 报告是**草稿**,发送给学生/家长前必须由带班教师审核措辞;
- 诊断只写事实与学习习惯(变量没定义、没编译就交),**不写人身评价**(笨/懒/不认真听讲);
- 代码、编译报错、答错的具体选项属于教学敏感数据,报告不要发到学生群,只给教师本人;
- 一个学生的报告不要引用其他学生的成绩做对比排名。
## 依赖与已知边界
- 课程插件须 ≥ C2.3(feedback v1 + analysis withCode/withHistory),qonnwolf 已验证(2026-09-09)。
- `analysis` 是整章节全班粒度的重接口(可达数百 KB),一次运行只调一次,不要按学生循环调用。
- WA/TLE 的「题意对照」依赖 AI 读代码推断;拿不准的结论在报告中用「疑似」标注,由教师定夺。
- 测试点级别的输入输出细节 API 不提供,如需可让教师去 OJ 记录页(用首刷 `rid`)人工查看。