Metadata-Version: 2.1
Name: sxlog-teacher
Version: 1.2.0
Summary: 超星 AI 交互记录 · 教师端验证工具（验签、验链、行为取证、班级汇总、文件夹右键菜单）
Home-page: https://pypi.org/project/sxlog-teacher/
Author: 吴振谦（宁波大学科学技术学院）
Author-email: 38328063@qq.com
Maintainer: 吴振谦（宁波大学科学技术学院）
Maintainer-email: 38328063@qq.com
License: LicenseRef-Proprietary
Keywords: chaoxing,超星,verify,hash chain,hmac,education
Classifier: Operating System :: Microsoft :: Windows
Classifier: Programming Language :: Python :: 3
Classifier: Topic :: Education
Requires-Python: >=3.8
Project-URL: Homepage, https://pypi.org/project/sxlog-teacher/
Description-Content-Type: text/markdown

# sxlog-teacher · 超星 AI 交互记录验证与评阅工具（教师端）

一句话：**把学生交上来的记录文件，变成可核对的过程证据、可复核的评阅意见、可直接用的平时成绩。**

```bash
pip install sxlog-teacher
sxlog-teacher install-hook     # 注册文件夹右键菜单（免管理员权限）
```

之后对装着学生作业的文件夹点右键 →「SXLOG 验证学生提交（批量）」即可。

两条使用路线：

| 路线 | 适合 | 成本 |
|---|---|---|
| **验证 / 汇总**（`verify` / 右键菜单 / `gui`） | 只想知道"交没交、改没改、有没有互相抄" | **零成本**，全程离线 |
| **批改流水线**（`analyze` → `rubric` → `review` → `report`） | 想给学生写学情描述、学习建议，并出一份平时成绩 | ①③⑥ **零成本**；④⑤ 调用 DeepSeek，**按量计费** |

> ⚠️ 评阅意见、学情描述与学习建议全部由 AI 生成，**一律标注「AI 辅助评阅，须教师复核」**，
> **不单独作为成绩依据**。最终分数由教师认定，教师可修改或覆盖任何结论。

**作者**：吴振谦 · 宁波大学科学技术学院 · 38328063@qq.com

---

## 作者与项目信息

| 项目 | 信息 |
|---|---|
| **作者** | **吴振谦**（Wu Zhenqian） |
| **单位** | **宁波大学科学技术学院** |
| **联系邮箱** | **38328063@qq.com** |
| **教学场景** | 《电子系统项目开发与实践》等课程的过程性评价与作业追溯 |
| **配套包** | [`sxlog-student`](https://pypi.org/project/sxlog-student/) —— 学生端（记录插件安装器） |
| **许可** | 教学用途专有许可（LicenseRef-Proprietary） |

本包是学生端的**验证侧**：学生端负责如实采集与本地留存，本包负责独立复核 ——
两者共用同一套哈希链与签名实现（逐字节一致），因此教师端能验出任何事后改动。
判断权始终在教师手里：报告只呈现证据与风险提示，不代替教学判断。

---

## 三条使用路径

### 1. 右键菜单（最省事）

```
资源管理器 → 右键装着学生记录文件的文件夹（或文件夹空白处）
         → SXLOG 验证学生提交（批量）
```
会在该文件夹内生成 `SXLOG班级汇总_时间.html` 与 `.csv`，并自动用浏览器打开汇总报告。

### 2. 图形界面

```bash
sxlog-teacher gui "D:\作业收齐\第3次作业"
```
表格按风险排序（未通过置顶 → 高风险 → 中风险 → 低风险），**双击任意一行**打开该生的交互时间线报告。
点「生成班级汇总」出 HTML，点「导出 CSV」出 Excel 可直接打开的表格。

### 3. 命令行

```bash
sxlog-teacher verify "D:\作业收齐\第3次作业" --class-report 汇总.html --csv 汇总.csv --open
sxlog-teacher verify 张三_2024030118.txt --json # 单文件 + JSON 报告
sxlog-teacher verify . --quiet                  # 只输出一行一人的结论
```

## 验证逻辑（与插件端逐字节一致）

| 层 | 做法 | 能拦住什么 |
|---|---|---|
| ① 哈希链 | 每条记录哈希包含前一条哈希 | 删除 / 修改 / 插入任意一条记录 → 链断裂 |
| ② HMAC 签名 | 密钥 = `PBKDF2(教师私盐 \| 学号 \| 姓名, 15 万轮)` | 学生缺私盐，**即使自己重算整条哈希链也签不出来** |
| ③ 摘要复算 | 从记录重新统计并逐字段比对文件声明 | 手工改过 summary 的文件 |
| ④ 行为取证 | 粘贴占比、零击键长文本、击键间隔、输入法组合、AI→提交间隔、与 AI 回复相似度、复制行为 | 外部 AI 生成后粘贴、照抄 AI 答案 |
| ⑤ 跨文件比对 | 链尾哈希 / 会话 ID / **设备指纹** 查重 | 整份文件复制顶替、同一设备提交多个学号 |

**结论分级**：风险评分 ≥6 判「高」、≥3 判「中」；**完整性失败（签名/链不匹配）直接判高**，
不会出现"签名失败却显示风险低"这种误导性结论。

## 报告长什么样

**单份时间线报告**（自包含 HTML，学生 名_时间线.html）：
- 校验结论横幅 + 风险等级
- 统计指标：提问次数、打字/粘贴字符数、粘贴占比、击键总数、AI 平均响应时长、
  **AI 工具名与使用分布**、**设备指纹 / 设备哈希 / 本机标识**
- 交互密度图（每 5 分钟事件数）
- 完整交互记录：可按事件类型过滤、可全文搜索；学生提问/AI 回复/粘贴/复制/开始记录/设备信息分色显示

**班级汇总报告**：通过率、风险分布、每人一行（含 AI 工具与设备指纹），
以及查重与关联告警区。

**CSV**：UTF-8 BOM 编码，Excel 直接双击打开不乱码。

---

## 批改流水线（把记录变成评阅意见与平时成绩）

### 一条命令跑完纯本地部分

```bash
sxlog-teacher analyze "D:\作业收齐\第3次作业"      # 零成本、零外发，可以随便跑
```

它在作业目录下建一个 `_sxlog输出\` 子目录，**不移动、不修改任何学生原始提交**：

```
作业目录\_sxlog输出\
├── corpus.json          归并后的语料（脚本的唯一输入）
├── features.json        结构与行为特征 + 班级分位
├── digest.json          评阅材料的索引
├── 评阅材料\            每个单元一份 Markdown（可直接打开看）
└── 转换\                每个单元一个文件夹：时间线.html · 记录.md · parsed.json
```

### 批改粒度：先想清楚"一份材料对应什么"

```bash
sxlog-teacher analyze <目录> --group-by submission   # 默认：每次提交评一份
sxlog-teacher analyze <目录> --group-by student      # 一个学生合并评一份
```

实测 24 生 ×6 份的对比：

| 粒度 | 评阅单元 | 单份材料 | 总 token |
|---|---|---|---|
| 按单次作业（默认） | 144 | 均 **4025** tokens | 57.9 万 |
| 按学生合并 | 24 | 均 8002 tokens | 19.2 万 |

**按次的总量更大，但这是"每次作业一个分数"必须付的钱**；合并评只能给一个总评。
要出平时成绩就用按次。

### 三步出成绩（④⑤ 需要密钥）

```bash
# ④ 生成评分标准：把你的要求和作业文档交给它，它据此设计维度与档位
set DEEPSEEK_API_KEY=sk-xxxx
sxlog-teacher rubric <目录> --prompt "本次作业是共射放大电路分析，重点看是否追问到原理层面、是否用多个平台互相对照" --doc 作业要求.docx

# ⑤ 逐份评阅（可随时中断，重跑即从断点续）
sxlog-teacher review <目录> --concurrency 3

# ⑥ 出平时成绩（零成本，只读 review.json）
sxlog-teacher report <目录>
```

产物：

| 文件 | 内容 |
|---|---|
| `平时成绩.xlsx` | 5 页：评阅汇总（20 列）· 学情与建议 · 评分标准（申诉依据）· 评阅明细（逐条证据编号）· 班级统计 |
| `平时成绩.csv` | UTF-8 带 BOM，可直接导入教务系统 |
| `班级汇总.html` | KPI + 维度分布 + 等级分布 + 异常清单 + 逐生表（**零外链**，校园网可打开） |
| `指导报告\<学生>.md/.html` | 每人一份：学情描述 + 学习建议 + 评分依据（带证据编号） |

### 成本与边界（先看清再花钱）

- **先干跑**：`sxlog-teacher analyze <目录> --dry-run` 只估算不写文件，会告诉你大概要花多少 token。
- **不用模型也能用**：`--offline` 生成内置默认五维标准；不设 `DEEPSEEK_API_KEY` 时，
  所有纯本地步骤（归并 / 特征 / 材料 / 转换 / 汇总）照常可用，只是没有 AI 评阅意见。
- **余额不足会中途停**：DeepSeek 是预付费，余额耗尽会返回 402。工具会等回在飞的请求、
  保存已完成部分并标记中断；**充值后重跑同一条命令即从断点续**，不会重复计费
  （相同输入命中缓存）。
- **评分标准一改，旧分数作废**：每个评阅结果都记着评分标准的指纹，标准变了会自动重评 ——
  否则会出现"用 A 标准的分数、配 B 标准的档位说明"这种最难发现的错。

### 关于"把学生内容发给第三方模型"

- 发送的是**压缩后的评阅材料**（提问文本、AI 回复的结论句、学生在超星提交的作答、统计数字），
  **不是**原始记录文件，也**不含**设备指纹与安装标识。
- 发送前**默认去标识化**：学号与姓名替换为代号。
- 不调用模型时（`--offline` 或不设密钥）**没有任何内容离开本机**。
- 这一步已写入学生端的知情同意与隐私政策第七节，学生有权要求改用零外发模式。

### 评阅结果的可核对性

- 每条评分依据都引用**材料里真实出现过的编号**；引用不存在的编号会被标为无效并单独列出
  （这是防"模型编造证据"的关键一环，纯 Python 校验、零 token）。
- 统计分析类依据（如粘贴占比）走另一条同样可校验的通道 —— 它们不挂在某条记录下，
  要求学生引编号是过分的要求。
- 模型给出的分数若不在评分标准的档位里，该维度按 0 计并**点名**，不会悄悄取近似值。

## 私盐管理（务必遵守）

- `verify_sxlog.py`（本包 `verifier.py`）含**明文教师私盐**，**绝不能发给学生**，
  否则学生可以自行伪造签名，HMAC 这一层防御即告失效。
- 私盐每学期轮换一次，轮换时要**同时**更新插件端（`src/crypto.js` 的 `_S` 数组）与教师端，
  两端不同盐会导致全班被判"签名失败"。配套的插件源码工程提供了一键轮换命令并带一致性门禁。
- 旧学期的文件必须用**旧盐**验证，请按学期保留对应版本的验证工具。
- 也可用环境变量覆盖私盐而不用改代码：`set SXLOG_SALT=你的盐` 后再运行。

## 环境要求

- Python 3.8+（Windows 上建议使用自带 tkinter 的官方 Python，右键弹窗与图形界面依赖它）
- **只依赖标准库**：`hashlib / hmac / difflib / json / csv / tkinter / winreg / zipfile / urllib`——
  验证、分析、材料、Excel、GUI 全都不需要第三方包
- 批改流水线的 ④⑤ 两步需要环境变量 `DEEPSEEK_API_KEY`（走 `urllib` 直连，不需要 `openai` 包）；
  其余命令不需要任何密钥、不产生任何网络请求

## 命令速查

| 命令 | 说明 |
|---|---|
| `sxlog-teacher install-hook` | 注册文件夹右键菜单（HKCU，免管理员） |
| `sxlog-teacher uninstall-hook` | 删除右键菜单 |
| `sxlog-teacher status` | 查看右键菜单注册状态并回读校验 |
| `sxlog-teacher verify <路径>` | 命令行批量验证 |
| `sxlog-teacher gui [目录]` | 打开图形化工作台（验证 + 批改全流程） |
| `sxlog-teacher doctor` | 环境自检 |
| `sxlog-teacher hook-run <路径…>` | 右键菜单实际调用的入口（支持多选文件夹） |
| `sxlog-teacher merge <目录>` | ① 归并：按学号合并每个学生的多份提交（零成本） |
| `sxlog-teacher convert <目录>` | ② 转换：每个单元出时间线 HTML + 可读 Markdown + JSON（零成本） |
| `sxlog-teacher analyze <目录>` | ①+③ 归并 + 特征 + 评阅材料（**零成本、零外发**） |
| `sxlog-teacher rubric <目录>` | ④ 生成评分标准（**调用 DeepSeek**） |
| `sxlog-teacher review <目录>` | ⑤ 逐份评阅（**调用 DeepSeek**） |
| `sxlog-teacher report <目录>` | ⑥ 生成平时成绩 Excel / CSV / 班级汇总 HTML（零成本） |

流水线命令的参数与内层实现完全一致，`sxlog-teacher <命令> --help` 可看全部选项。

## 一条容易被忽略但很重要的提醒

**每次升级本工具后，请对上一学期已批阅过的作业做一次抽查复核。**
本工具的结论会随版本变化（评分标准、统计口径、材料构造都可能改进），
而学生看到的是**当时那一版**算出来的分数。升级后如发现某个学生的结论明显变化，
应能解释"为什么变了"，而不是悄悄覆盖 —— 那正是让学生不相信这套流程的做法。

---

## 关于"能否自动解密"

学生的记录文件（`.txt`）**不是加密文件**，而是"可读内容 + 签名保护"：正文是明文 JSON 的 base64，
教师端验证的是一次性验签与验链，不需要也不应该"解密"。这样设计有两个好处：
① 出现争议时任何一方都能直接查看原文，不需要密钥；
② 伪造成本远高于诚实提交（缺私盐无法重签）。验证过程全部在本地离线完成，不联网。

---

## 完整工作流示例（从收作业到出成绩）

```bash
# 0) 学生交上来的记录文件放进一个文件夹（文件名随意，按学号归并、不信任文件名）
set 作业=D:\作业收齐\第3次作业

# 1) 先验证：谁没交、谁改过、有没有互相抄（零成本）
sxlog-teacher verify "%作业%" --class-report "%作业%\汇总.html" --csv "%作业%\汇总.csv" --open

# 2) 看某人到底怎么做的（零成本）
sxlog-teacher convert "%作业%"          →  转换\<学生>\时间线.html

# 3) 归并 + 特征 + 评阅材料（零成本）
sxlog-teacher analyze "%作业%"

# 4) 定评分标准（调用 DeepSeek，一次约几分钱）
sxlog-teacher rubric "%作业%" --prompt "……本次作业的评分意图……"

# 5) 逐份评阅（调用 DeepSeek；可中断续跑）
sxlog-teacher review "%作业%" --concurrency 3

# 6) 出平时成绩与逐生指导报告（零成本）
sxlog-teacher report "%作业%"
```

不想敲命令就用 GUI：`sxlog-teacher gui "%作业%"` —— 同一套逻辑，按钮式工作台，
含粒度选项、评分标准编辑、逐行进度、实时 token 与费用显示。
