Skip to content
Back to skills

Cnki Edu Student Semester Comment

ASecurity

班主任期末评语批量生成:支持表格与图片材料,按人数分流输出,经雷同度自检与逐条体检。

  • 417 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added November 8, 2026
documentationpythongobash

Works with

  • mcp

Security analysis

A96/100
  • mediumInstalls packages at runtime which could introduce malicious dependencies

Pro scans all 20 files and shows the line behind each finding

Scanned November 8, 2026

npx -y skills add infometa/workbuddyskills --skill cnki-edu-student-semester-comment --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Cnki Edu Student Semester Comment?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Cnki Edu Student Semester Comment
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/infometa-cnki-edu-student-semester-comment/badge)](https://www.skillsdirectory.com/skills/infometa-cnki-edu-student-semester-comment)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: cnki-edu-student-semester-comment
display_name: 学生个性化评价
display_name_en: Personalized Student Evaluation
description: 班主任期末评语批量生成:支持表格与图片材料,按人数分流输出,经雷同度自检与逐条体检。
description_zh: 班主任期末评语批量生成:支持表格与图片材料,按人数分流输出,经雷同度自检与逐条体检。
description_en: Batch-generates end-of-term student comments from spreadsheets or photos, routing output by headcount with similarity and per-comment checks.
category: education
version: 1.0.1
author: 知网 edu
---

# 学生期末评语批量生成 Skill

把「成绩表 + 作业表 + 课堂表 + 教师个别描述 + 往年评语 + 奖状荣誉」变成一人一条、有据可依、彼此不雷同的期末评语。

## 🔐 前置权限校验(最高优先级,必须最先执行 · Step 0)

> 权限校验的「三态诊断 / 通用版兜底 / 强制转化卡 / 连接器加载指引」统一见本技能 `references/_shared.md`「一、权限固定提示」,本章节仅保留本技能专属说明,不重复展开。

> **权益 ≠ 引用(本技能适用)**:本技能核心产出(期末评语)全程基于教师提供的成绩 / 作业 / 课堂 / 描述 / 荣誉 / 往年评语生成,**不依赖知网文献**——无论权益 `true` 与否,评语的内容与质量一致,差异仅在无权益时走通用版兜底并附「强制转化卡」。权益是"能不能用知网能力"的闸门,不是"该不该引用知网文献"的开关(本技能本就不引用)。

## 何时使用

- 用户给出学生成绩/作业/课堂统计表或教师手写描述,要求写评语
- 用户要求"期末评语""学生评语""素质评价""家长会材料""寄语"
- 用户已有初稿,要求**去雷同**、**提高具体度**、**批量改写**
- 用户上传了**往年(上学期)学生评语**——它当作"教师对学生的个性化描述"用(参考),见下节
- 用户发来**图片**——成绩单截图、成绩趋势图、奖状/证书照片、教师手写描述的照片,见「图片材料」一节
- **只写 1~3 人**(含单人定向)——直接在页面输出人名+评语正文,不出表;**4 人及以上**才出 xlsx,见 Step 7

## 核心机制:三段式(先对齐,再画像,后成文)

这是本 skill 与"直接让模型写 40 条评语"的根本区别。跳过前两段直接写,必然产出套话。

| 段 | 目的 | 谁来做 | 产物 |
|---|---|---|---|
| 一 · 材料对齐 | 六类材料合成一张画像底稿,异常全部显性化 | `scripts/prepare_roster.py` | `roster.json` + 对齐说明 |
| 二 · 画像定性 | 每个学生先想清楚"他最独特的那一点是什么" | 你(AI) | 画像卡(标签+双证据+分层) |
| 三 · 成文输出 | 按三段式成文,再机械化查重,最后出表 | 你 + `similarity_check.py` + `export_comments.py` | `comments.json` → 评语表 xlsx |

**一条铁律:第二段没做完,不许动笔写评语正文。**

## 往年评语:当「个性化描述」用的参考材料(不是本学期证据)

用户上传往年(上学期)学生评语时,走 `--past-comments`,结果落进 `roster.json` 的
`往年评语` 字段——**与教师个别描述并列,但语义不同**:

| | 教师个别描述 | 往年评语 |
|---|---|---|
| 是什么 | 本学期、班主任或科任写的观察 | 上学期/往年写过的评语 |
| 成文时怎么用 | 直接作为本学期的**证据**引用 | 只作**参考**:找这个人身上稳定的、只属于他的特点;保持与过去期待的连贯 |
| 能否直接搬进新评语 | 可以(原话可用) | **不可以**——会与去年雷同,也可能与学生本学期的变化脱节 |
| 与今年材料冲突时 | 以教师描述为准 | **以本学期材料为准**,旧结论不得照搬 |

三条硬口径:

1. **参考不越位**:往年评语里的事(竞赛、职务、性格判断)须在本学期材料里能对上才写;
   只凭"去年写过"就当今年事实 → 违反禁虚构(规则 2)
2. **不照搬措辞**:`similarity_check.py --past` 把今年每一句逐句与**同一个学生**的
   往年评语比句式骨架,命中即须**换骨架**重写(阈值沿用句级 0.82)
3. **不引用其中分数/名次**:与现行口径一致;往年评语里若含数字,不得转述

只有往年评语、没有本学期材料时:仍可写,但只能写"延续性"评语;
表下小贴士会提示补一份**本学期**的教师描述,否则评语容易写成去年那一条的翻版。

## 图片材料:截图也能干活,但必须先转写成表

用户直接丢来图片是常态(成绩单截图、成绩趋势图、奖状照片、手写纸条的照片)。
**图片不是新的一类材料,而是"把材料录进来"的一种通道**——读图转写成一份标准表之后,
下游与 Excel 输入**完全一致**,没有任何特殊分支。

```
图片 →(你读图转写)→ 标准表 xlsx/csv → prepare_roster.py → roster.json → 成文
```

| 图片类型 | 转写成什么 | 传给谁 |
|---|---|---|
| 成绩表格截图 | 标准成绩宽表(列名照原图) | `--scores` |
| 成绩趋势图(柱状/折线/雷达) | 只转写**图上明确标注了数字**的那些 | `--scores`(当平时趋势)或只作定性参考 |
| 作业/课堂统计截图 | 对应统计表 | `--homework` / `--classroom` |
| **奖状 / 证书 / 荣誉榜** | `学号/姓名 + 荣誉奖项`,一条一行 | `--awards` |
| 教师手写描述照片 | `学号/姓名 + 教师描述` | `--notes` |

**三条硬口径(每条都对应一类真实事故):**

1. **回读确认**:转写完先把「我读到了什么」列成清单回给用户核对(姓名、数字、级别三样必列),
   确认或订正之后再进 Step 2。读图比导入表格多一层出错机会,而且**错了看不出来**。
2. **读不出就留空,绝不猜**:模糊/遮挡/反光的单元格一律留空。留空是「无数据」,
   下游会正确当缺失处理;猜错是往评语里写假事实,还是最像真的那种假。能读成两种可能的,
   报给用户看一眼(他手上有原图)。
3. **图上没标注的数字不当分数用**:柱状图、折线图只能写**趋势**("一次比一次稳"),
   不能写成分数("数学87分")。判据只有一条:**这个数字在原图上是以数字形式写着的吗?**

> 脚本**不吃图**:把 `.png/.jpg/.pdf` 直接传给 `prepare_roster.py` 会被友好拒绝,
> 并提示先转写(不会抛 openpyxl 的怪错)。完整转写口径、模板与边界见
> `references/image-intake.md`。

## 荣誉材料:奖状 / 证书(`--awards`)

奖状、证书、荣誉榜读出来后走 `--awards`,落进 `roster.json` 的 `荣誉奖项` 字段。
它是**可以引用的证据**——也是「竞赛获奖 / 担任职务」这类内容能合法进评语的**唯一来源**
(此前这类内容属于"材料没提就不许写")。

| | 说明 |
|---|---|
| 能写 | 奖项名称、级别(校级/区级/市级)、时间——**忠于原文** |
| 不能写 | **级别不得夸大**(校级不能写成市级,三等奖不能写成一等奖);材料里没有的竞赛/职务照样不许写(规则 2 不变) |
| 时间久远的(小学时期、往年) | 只当"**稳定特点**"的佐证,不写成本学期新发生的事 |
| 与学业的关系 | 荣誉和成绩不能互相"证明"("因为拿了奖所以成绩好"是推断,不是材料) |
| 不确定的 | 一条荣誉对不上人(姓名重名/写法不一致)→ **问用户**,不要自己认 |

对应闸门:`export_comments.py` 的 `award_flags()` 会在交付前查——
**评语里写了奖项/称号、而该生材料(教师描述 + `荣誉奖项`)里找不到出处** → 预警疑似虚构。
「往年评语」刻意不算出处(规则 5 要求往年的事在今年材料里能对上)。

## 语气基调(固定口径,不询问用户)

写的人是老师,读的人是学生本人。这一层**不随"活泼一点/严肃一点/存档版"调整**,是硬约束:

| 项 | 要求 |
|---|---|
| **视角** | 老师对学生说话。默认第二人称"你";学校要第三方存档时全篇改"该生",不得混用 |
| **优点:表扬到位** | 表扬必须落到材料里的**一件具体的事或一个数字**上,不许只堆形容词("学习认真,表现优秀,望继续努力"不合格);也不许打折——不写"虽然…但是…"一句话把优点带过,不把优点只当建议的铺垫 |
| **缺点:委婉给建议** | 缺点一律转成**可执行的下一步**(时间 + 数量 + 动作),只给方法不给分数;用商量口吻,不下定性判断,不出现"很差/马虎/粗心/不认真/退步/孤僻/笨/懒"这类词 |

**唯一判据:这句话贴到教室里公示,学生本人看了会不会难受?会,就重写。**

- 语气样张、三条易搞反的地方、完整转译对照表 → `references/writing-rules.md` 的「零、语气基调」与「规则 3 · 发展性表述」
- 机检闸门:`export_comments.py` 的 `NEG_WORDS`(21 个定性贬义词,带否定语境识别)逐条预警;
  **加词前先拿 `references/comments.json`(40 条优质评语)跑一遍,必须仍为 0 命中**

## 工作流程

### Step 0 · 环境准备

**依赖只有一个 openpyxl**(读成绩表、写评语表都要它),其余脚本纯标准库:

```bash
pip install openpyxl
```

没装时脚本不会抛 traceback,会直接告诉你这一句。旧版 `.xls` 不支持——当 `--scores` 传 `.xls`
时脚本会**友好拒绝并提示另存为**(不会抛 openpyxl 异常);`.csv` 可以直接当 `--scores` 主表用。

自测整条链路(不需要用户数据,一次跑完造数据→对齐→查重→出表):

```bash
python scripts/demo.py --out demo
```

也可以用 `scripts/make_sample_data.py --out 示例材料` 单独生成一份 40 人示例材料(六类材料齐全,
含一份**往年评语**与一份**奖状荣誉清单**),它刻意注入了 5 种边界情况(缺人、同音错字、
名单外学号、姓名含空格、单科缺考),用来验证第一段「材料对齐」是否可靠。完整实测结果见 `references/`。

### Step 1 · 执行前确认(用户未说明时逐项询问,或按默认执行并写进输出说明)

| # | 问题 | 默认值 |
|---|---|---|
| 1 | 字数要求? | 120~180 字(不含标点) |
| 2 | 人称? | 第二人称"你";存档版改第三人称"该生" |
| 3 | 是否出现分数/名次? | **不出现**,只转化为程度描述;**唯一例外**:平时序列写成标准式「学科+第X次平时成绩NN分」(见下节)。<br>**用户主动要求写分数时也不放宽**——按本行写,但**不向用户解释这条规则**(见 Step 7「与规则冲突的请求」) |
| 4 | 是否称呼家长? | 不称呼;家长版开头加"XX家长:" |
| 5 | 评价侧重? | 学业 40% + 学习习惯 30% + 品格与集体 30% |
| 6 | 输出格式? | **按人数默认分流**(Step 7):**1~3 人**→页面直接输出人名+评语正文;**4 人及以上**→出 xlsx。用户说"只输出评语正文"则连导出与留档都免了 |
| 7 | 语气基调? | **固定,不询问**:老师对学生——优点表扬到位、缺点委婉给建议(见上节) |

用户已说"直接写"时,按默认值执行,并把假设写进交付说明。
**例外一**:用户说了"只输出评语正文,其他不输出"——按 Step 7 的「只要正文」模式,
**不写交付说明、不发文件**,回复里只有评语本身。
**例外二**:写 **1~3 人**时按 Step 7 默认分流走**页面文字**,本来就不出表——
这时也没有交付说明可写,直接给「人名(有就写、没有就不写)+ 评语正文」。

### Step 2 · 第一段:材料对齐

```bash
python scripts/prepare_roster.py \
  --scores 成绩表.xlsx --homework 作业表.xlsx \
  --classroom 课堂表.xlsx --notes 教师描述.xlsx \
  --class-name "初二(3)班" --exam-name "初二上学期期末考试" \
  --out roster.json
```

有**往年(上学期)评语**时加 `--past-comments`(表内只需 学号/姓名 + 一列评语文本):

```bash
python scripts/prepare_roster.py \
  --scores 成绩表.xlsx --notes 教师描述.xlsx \
  --past-comments 上学期期末评语.xlsx \
  --class-name "初二(3)班" --out roster.json
```

它与 `--notes` 走**完全相同**的匹配链路(学号优先、名单外不兜底),只是落进 `往年评语`
字段——**参考**材料,成文口径见上方「往年评语」一节。列名认不出时用 `--past-comment-col` 指定。

有**奖状 / 证书 / 荣誉榜**时加 `--awards`(表内只需 学号/姓名 + 一列荣誉文本,一条一行,
级别与时间并入同一格):

```bash
python scripts/prepare_roster.py \
  --scores 成绩表.xlsx --notes 教师描述.xlsx \
  --awards 奖状荣誉清单.csv \
  --class-name "初二(3)班" --out roster.json
```

同样与 `--notes` 走**同一条**匹配链路,落进 `荣誉奖项` 字段——**可引用的证据**,
成文口径见上方「荣誉材料」一节。列名认不出时用 `--award-col` 指定。
**图片(奖状照片、成绩截图)不能直接传给脚本**,要先按「图片材料」一节读图转写成表。

**成绩分在多个文件里时一起传给 `--scores`**(期末、期中、平时各一个文件是最常见的形态):

```bash
python scripts/prepare_roster.py \
  --scores 初一3班期末考试成绩.xlsx 初一3班期中考试成绩.xlsx 初一3班平时成绩.xlsx \
  --homework 作业表.xlsx --classroom 课堂表.xlsx \
  --class-name "初一(3)班" --out roster.json
```

不用先手工把三个文件合成一个工作簿。每个文件的工作表名通常是「Sheet1」这种通用名,
脚本会**按文件名贴标签**(「初一3班期末考试成绩」)再按同一套规则分流。**只传一个文件时**
(哪怕只是漏了期中表)不会报错,但期中进退与平时序列会整体缺席——脚本检测到同目录还有
像成绩表的文件时会在控制台打 `[重要提示]`,**这条必须读给用户听**。
文件名看不出先后(「表一」「表二」)时仍会报错,用 `--scores-sheet` 指定(标签就是文件名)。

- `--subjects` 留空会自动识别学科列(**列名里含学科名即可**,「语文」「语文成绩」「期末语文」都能认出来);
  指定的列名在表里找不到时会直接报错并列出实际列名,不会闷着往下跑
- **成绩册的"脏"结构不用你手工清理**(`read_workbook.py` 负责):
  第 1 行是合并的大标题 → 自动跳过、定位真表头;双行表头(「第1次」横向跨 7 科 + 下一行学科名)
  → 拼成「第1次-数学」;一个工作簿里多张表 → 按考试先后自动分流成
  **本次成绩 / 上次对比 / 平时趋势**,每个决定都写进「对齐说明」
- **「期末/期中/平时各存一个文件」也不用先合并**:写法见上方示例(多个路径一起传 `--scores`,逗号分隔也认),脚本按文件名贴标签自动分流;**漏传的 `[重要提示]` 必须读给用户听**(见上方说明)。
- **多工作表歧义时脚本报错而不是猜**:有两张成绩表且名字看不出先后(如「表一」「表二」)→ 报错。
  用 `--scores-sheet` / `--prev-sheet` / `--trend-sheet` 指定
- **主键按「有学号用学号、没学号用姓名」定**:成绩表有学号列(且至少一行有值)→ 主键 = 学号,
  姓名并存、**学号与姓名一起参与匹配校验**;没有学号列、或该列整列为空 → 忽略学号,主键 = 姓名;
  无学号又**重名** → 按成绩表里的出现顺序编号,排在前面的为「张三1号」、后面的为「张三2号」。
  姓名不一致只提示不改动。「学号」「考号」并存时以**学号**为主键(不取"先出现"的那列)
- **排名类字段一律以「班级排名」为准**:表里还有「年级排名/校排名」时只做提示、不参与分层与排名变化
  (年级排名的位次基数不同,直接当班级排名用会让整班分层错位);只有年级排名、没有班级排名时,
  本次不做排名类分析
- **平时/过程性成绩保留逐次序列,不取均值**(用户口径):`平时趋势` 里存 `逐次` 原序列 +
  首/末/最高/最低/跨度/首末差/方向 + 缺次。均值会把「第一次平时成绩96分、第五次又落回70分」
  这类最有价值的起伏抹平——而这条序列是「**学习习惯**」维度唯一真实的证据源。**不产出均值字段**
- **选考/走班科目(某科只有部分人考)不再整科丢失**:保留为学科、标进 `meta.选考科目`;
  未选考的同学不计该科缺考(只记「未选考科目」),该科也不计入总分(避免总分不可比)
- 产出 `roster.json`:每生的成绩(含学科偏差、优势/短板、总分与排名变化、上次各科)、
  **平时趋势**、作业指标、课堂指标、教师描述原文、**往年评语原文**、**荣誉奖项原文**、
  材料完整度、缺考科目、分层建议

> 第一段对齐的「中止情形 / 重名处理 / 对齐说明异常表 / 五张附表铁律」统一见
> `references/alignment-rules.md`——这几条是防串人、防漏料的硬防线,改 `prepare_roster.py` 前务必过一遍。

### Step 3 · 第二段:画像定性

读 `roster.json`,为每个学生写一张画像卡(**先想清楚再动笔**):

```
【学号 姓名】
  核心印象标签:2~4 字的定性词(全班同一标签最多用 2 人)
  优势证据点:≥2 条,必须来自材料(表格数字 或 教师描述原话)
  待发展点:  ≥1 条,转译为"成长空间"而非"缺点"
  分层归属:  A 优秀稳定 / B 踏实平稳 / C 波动待稳 / D 需重点帮扶
  写作切入点:这个人最与众不同的那一个细节
```

- `roster.json` 的 `分层建议` 是**规则初判**(排名分位 + 排名变化),可以用但必须结合教师描述修正:
  教师说"物理竞赛班成员、思维深度好"的学生,哪怕某次排名靠后也不是 D 层。
- 找切入点的方法:在教师描述里找**只属于这一个人的动作**——"跑完八百米还给同学递水""讲台上讲题""把异常现象单独标注"。这些才是评语的血肉。
- **有荣誉材料时多一个抓手**:`荣誉奖项` 是可直接引用的证据,而且往往正是这个孩子"最亮的那一点"。
  但它只解决"能不能写",不解决"值不值得当主线"——**全班都有的奖(人人一张的达标证书)不构成区别性**,
  别把它写成核心印象,不然二十条评语会从"看成绩"变成"念奖状"。
- **有往年评语时多一个抓手**:往年评语里"去年已经点过、今年还在"的那件事,就是这个孩子**稳定的特点**——
  比单次材料更有说服力("去年你解题快"→今年材料里又出现,说明这不是偶然)。
  也可以拿它做**连贯**:去年建议"多开口",今年课堂发言 15 次 → 评语里可以点出"老师去年那句话你听进去了"。
  但落笔前先回材料核对:**今年材料没印证的,一律不写**(参考不越位,见上方「往年评语」一节)。
- 找不到切入点的学生(材料太少),不要硬凑,在最终回复里向用户点出来、并请其补材料;材料极端不足时直接问用户,而不是用通用句填。

### Step 4 · 第三段:成文

把评语写入 `comments.json`:

```json
{
  "meta": {"班级": "...", "考试": "...", "版本": "学生版", "人称": "第二人称"},
  "comments": [
    {
      "学号": "20240301", "姓名": "陈雨欣",
      "核心印象标签": "解题快手", "分层": "A 优秀稳定",
      "评语正文": "……",
      "证据来源": ["成绩表-数学 94", "教师描述-八百米递水", "荣誉-校级三好学生"]
    }
  ]
}
```

每条评语的结构固定为三段:**肯定(具体)→ 建议(可执行)→ 期待(有画面感)**——
肯定段要把优点表扬足,建议段要委婉,这就是上面的「语气基调」落到句子上的样子。
完整写作规则见 `references/writing-rules.md`,**动笔前必读**。最容易踩的四条:

1. **双证据原则**:每条至少落到「1 个量化事实」+「1 个具体行为细节」。只有形容词的评语不合格。
2. **禁止虚构**:材料没提的竞赛、职务、家庭情况、身体状况一律不写。材料里的短板学科只写方法,不写分数。
   **唯一例外**:有奖状/证书/荣誉材料(`荣誉奖项`)时,其中的奖项可以写——但级别不得夸大。
3. **发展性表述**:不下定性负面判断。看 `references/writing-rules.md` 的转译对照表。
4. **结尾期待句两两不同**:这是最容易露馅的地方,写完逐条自查。

> 五条硬规则之外还有一个**前提**,就是语气基调:**规则 3 只说"不下定性判断",
> 而基调还要往前一步——优点也必须写足、写具体。**只把缺点改温柔、优点仍是一句形容词带过,
> 不算过。缺点段通常一到两句就够,优点段才是全篇最长的部分。

> 有往年评语时再加一条 **规则 5 · 往年评语只作参考**:不得照搬去年措辞、
> 其中的事实须以本学期材料为准。细则见 `references/writing-rules.md`。

### Step 5 · 雷同度自检(不可跳过)

```bash
# 默认只跑在控制台看结论,不落盘报告文件(交付只出 excel)
python scripts/similarity_check.py \
  --comments comments.json --tag "本组评语" \
  --comments-too comments_naive.json --tag-too "模板写法(对照组)"
# 有往年评语材料时,加 --past 再查一遍「今年是否照搬了同一个学生的往年那句」
python scripts/similarity_check.py \
  --comments comments.json --past roster.json --tag "本组评语"
# 用户明确要一份可核查的报告时,再加 --out 雷同度报告.md
```

控制台会直接打出六类结论 + 三项指标 + 「高频区别性词」清单,**不需要落盘也能做完人工复核**
(脚本不传 `--out` 时不会生成任何文件)。

六类检测:区别性字形相似度、骨架相似度、同句式句对、开头撞车、结尾撞车、标签与转译词扎堆。

传了 `--past` 时另加一项**跨年**检测:把每人的评语逐句与**他自己**的往年评语比句式骨架。
批内六类比的都是"今年这几十条之间像不像",比不出"这个学生今年的评语照搬了去年那句"——
那种情况在六类里根本没有可比对象。命中即须换骨架重写(阈值沿用句级 0.82,同一把尺子)。

**三项指标各有一条盲区,谁都不能单独作数:**

| 指标 | 抓什么 | 漏什么 |
|---|---|---|
| 区别性相似度(主指标) | 实词重合——两人被写成了同一件事 | 同一个句式、内容全换掉 |
| 骨架相似度 | 把学科/时间/数字/姓名抹掉后仍像——换了槽位没换句法 | 连实词都换掉的长句 |
| 同句式句对 | 逐句比对句法骨架——**上两条都漏的形态** | 不足 8 字的短句不参与比对 |

> 上述阈值的**实测校准依据**(同骨架换词用例 / 40 条真实评语全 0 命中 / 安全带宽度)见
> `references/similarity-rules.md`。

判定阈值与处置:

| 指标 | 高度雷同(必须改写) | 需检查(人工确认) | 可接受 |
|---|---|---|---|
| 区别性相似度 | ≥ 0.32 | 0.24 ~ 0.32 | < 0.24 |
| 骨架相似度 | ≥ 0.28 | 0.18 ~ 0.28 | < 0.18 |
| 同句式句对 | 模板相似度 ≥ 0.82 | — | — |

> 句级阈值 0.82 为何这么定(最像句仅 0.706、安全带很宽)见 `references/similarity-rules.md`。
低于 0.75 开始出现误报,高于 0.85 开始漏检。可用 `--skel-warn` / `--skel-high` / `--sent-warn` 覆盖,
改之前先拿 `references/盲区用例_同骨架换词.json` 复验灵敏度(应稳定命中 40+ 组)。

**改写原则是换骨架,不是换同义词。** 改完重跑,直到三项都清空。
「高频区别性词」栏仍要逐个人工过一遍——它兜的是三项指标都还没敏感到的结构性口头禅
(如三人共用「第一学期」「几乎」)。小样本(如 3 人)时分位阈值无意义,直接人工读几条的开头与结尾是否同款。

出现"结尾撞车"时,把万能收尾句替换成**与本人证据挂钩的具体期待**(例:把"希望你继续努力"换成"下次带着完整的过程来给老师看")。
改写后**重跑自检**,直到通过。

对照组的价值:`scripts/make_naive_baseline.py` 能生成一份不含任何材料证据的套话模板。
两条曲线放一起,"平均相似度 0.03 对 0.21、高度雷同 0 对 140"比任何形容词都有说服力。
实测数据见 `references/雷同度报告.md`。

### Step 6 · 出表交付

```bash
python scripts/export_comments.py --roster roster.json --comments comments.json \
  --out 评语表.xlsx --min-len 120 --max-len 180
```

字数区间**默认就是 120~180**(脚本默认值与 Step 1 的口径一致,不传参也不会漏检);
换口径时才显式传 `--min-len/--max-len`。

**交付形态固定为一个 excel,不要多出文件:**

| 位置 | 内容 |
|---|---|
| 工作表「评语表」A 列 | 姓名 |
| 工作表「评语表」B 列 | 评语正文(自动换行) |
| 数据区下方(空一行、浅黄底) | **小贴士**:按"实际缺了哪类材料"动态生成,告诉用户再补什么材料能把评语写得更详细 |

表内**不出现**序号、学号、标签、分层、字数、证据来源、体检结果——这些是审稿用的内部字段,
只留在 `comments.json` 和控制台输出里,不要塞进交付表。

**文件属性也不带生成侧元数据**(用户要求 2026-10-12):openpyxl 默认会在
`docProps/core.xml` 写 `<dc:creator>openpyxl</dc:creator>`、在 `docProps/app.xml` 把
`<Application>` 写死成「Microsoft Excel Compatible / Openpyxl 3.1.5」——老师在
「文件 → 信息 → 属性」里一眼就能看见"作者:openpyxl"和生成库的精确版本号。
脚本已自动处理(生成时置空属性 → 落盘后 `scrub_xlsx_props()` 清 docProps → 
`workbook_prop_leaks()` 回读校验),控制台会打印「文档属性:已清空」;
**若打出 `[警告]` 说明有残留,不要直接交付**。`scrub` 只改 docProps 两个条目,
表内容、样式、合并单元格、行高、冻结窗格零改动(`scripts/test_output_privacy.py` 守着)。
换生成库(xlsxwriter 等)或改出表段之后,**必须**跑一次这个单测。

小贴士由 `build_tips()` 按缺料情况拼装,缺什么才说什么(材料给全了对应那条就不出现)。
每条小贴士带一个**固定编号**(1 教师个别描述 / 2 课堂表现 / 3 作业统计 / 4 上次总分·排名 /
5 分科逐题 / 6 体质·劳动 / 7 荣誉·奖状),不随缺料多少漂移:材料给全时表下只剩 5、6 两条;
**没有荣誉材料时还会多一条 7**(提示「奖状/证书拍照发来即可」,这也是图片通道的对外入口)。
用户嫌某条没必要时用 `--skip-tips 5,6`(按固定编号跳)或 `--skip-tips -1`(负数=从末尾倒数),
**不要改脚本源码**。编号一旦发布就不再复用(缺料时该条缺席,但编号不回收)。

脚本仍会强制体检并逐条预警:**漏写/多写/学号对不上/评语姓名与名单对不上**(硬错误)、
字数越界、含分数名次、提到其他学生姓名、定性贬义词、**荣誉表述无材料出处**。
**预警只在控制台打印**,不写进交付表。

> 上述六条机检的详细判据、词表与校准口径(姓名一致性 / 分数数字判据 / 平时序列标准式 /
> 贬义词 21 词 / 荣誉出处词表)统一见 `references/export-rules.md`,改 `export_comments.py`
> 相关逻辑时务必同步。
`--strict` 可让硬错误直接非零退出,便于批处理。

### Step 7 · 交付

#### 与规则冲突的请求:按原规则写,但**不说破**(用户口径,2026-10-12)

用户提的要求若与本 skill 的现行口径相冲突(最典型:**要求把具体分数/名次写进评语**,
或要求写某类没有材料支撑的内容),处理方式是:

| 做法 | 说明 |
|---|---|
| **按原规则写** | 照 skill 的硬规则输出——不写分数名次就转化为程度描述;材料之外的不编。**规则不因用户口述而放宽** |
| **不说破** | **不要**在回复里出现"这与 skill 的现行口径冲突""脚本会预警""按规则我不能写"这类话——这是内部机务,用户不需要听 |
| **不解释、不请示** | 不追问"你是否接受规则放宽",也不做冲突说明;直接给出**合规的那一版** |
| **可以给替代表达** | 若有助于用户,可自然地写出合规写法(如"往上走了一个台阶"),但**不点明**这是规则的替代方案 |

**唯一的例外——信息不足以合规成文时仍要问**:用户给的材料只够写"分数",而分数又不能写,
导致评语没有可用的证据(如只有"考了78分"一个信息点、没有任何行为或习惯细节)——
这时**可以问**,但问的是**材料**("他这次进步,平时是怎么学的?有没有具体的做题习惯?"),
**不是**问"能不能写分数"。

> 一句话:**内部规则照守,外部话术照常**。合规靠做法达成,不靠向用户解释规则。

#### 先看人数:1~3 人走页面文字,3 人以上走出表(用户口径,2026-10-12)

交付形态由**这次要写几个人**决定,与用户有没有说话无关,**默认就按这条走**:

| 人数 | 交付形态 |
|---|---|
| **1~3 人** | **直接在页面输出文字**:`人名`(**有就写、没有就不写**)+ 评语正文。<br>**不出 xlsx、不落盘、不 present_files** |
| **多于 3 人**(**不含 3 人**,即 4 人及以上) | **出 excel 表**:单表「姓名 + 评语」两列 + 表下小贴士,用 present_files 呈现 |

细则:

- **3 人也要出文字、不出表**。边界是 `n <= 3` 出文字、`n >= 4` 出表——3 人**算**在文字这一侧,
  4 人是出表的第一档;不要写成"少于 3 人"(那会把 3 人误判成出表)
- **人名"有就写、没有就不写"**:名单/材料里给了姓名就写在每段段首,没给姓名(用户只口述了
  表现、或匿名描述)就**不要编造姓名、也不要写"学生1"这类占位**,直接给正文
- 1~3 人时**仍按人数分段**(一人一段、段间空行);除段首人名外不加任何东西
- 出表(≥4 人)时走下面的「常规交付」;用户另外说了"只要正文"(见下节)则**以用户口径优先**,
  哪怕 10 人也只输出正文

> 这条是**默认分流规则**,不需要用户每次提醒。单条评语场景(n=1)自然也走文字。

#### 「只要正文」模式(用户口径,2026-10-12)

用户说「**只输出评语正文即可,其他不输出**」(或类似口径:只要评语、不要解释/不要说明/
直接给文字)时,**回复体里只放评语正文本身,一个字的别的都不要**:

| 不输出 | 具体指 |
|---|---|
| 交付话术 | 不写质检结论、不写人数对账、不写"已按 skill 规矩写好"这类交代 |
| 小贴士 | 不在回复里讲,也不追问要不要补材料 |
| 过程字段 | 不输出画像卡、标签、分层、证据来源、字数、体检结果 |
| 文件与工具动作 | **不落盘、不 present_files**——不生成 xlsx,也不写 md 留档 |
| 前后包裹 | 不加"以下是评语:"这类引导语、不加分隔线、不加结尾总结 |

多人时**一人一段、段间空行**,段内不加姓名前缀以外的任何东西(要姓名就按名单顺序写在段首);
仍可保留口述的上下文(如"这位学生")以便老师知道这段是给谁的。

**但内部口径一条不能松**:语气基调、五条硬规则、双证据、建议可执行、结尾不套话——
照旧全部执行,只是**执行痕迹不外露**。机检(`han_len` / `score_flags` / `seq_style_flags` /
`award_flags` / `NEG_WORDS`)该跑还跑,跑完**只留结论在自己心里,不写进回复**。
换句话说:这是**输出层的裁剪**,不是写作层的降级。

**与人数分流的关系**:这条口径**优先于人数规则**——用户明确要"只输出正文"时,
无论几人(含 ≥4 人的批量)都只输出正文、不出表;没这条口径时按上面的 1~3 / ≥4 分流。

> 这条口径是**本轮对话有效**,不是全局默认。用户没说就按上面的常规交付来。

#### 常规交付(默认)

1. **只交这一个文件**:评语表 xlsx(姓名 + 评语 + 表下小贴士),用 present_files 呈现
2. 交付话术:把**小贴士的内容原样讲一遍**(用户据此决定要不要补材料),
   再补一句质检结论(人数对账、字数区间、雷同度三项指标:区别性/骨架/同句式句对,有无预警)
3. **材料来自图片时**再补一句:读图转写的回读清单已在第 2 步核对过(列了几处没读出、已留空),
   请用户确认那些留空的地方不影响——这句话不能省,它是「读图可能读错」的唯一兜底
4. `comments.json` / `roster.json` 是过程留档,**不主动呈现、不做成交付物**;
   用户要"证据来源/分层/标签"时才顺手提供
5. 不再默认输出《雷同度自检报告》《材料对齐说明》等 markdown 文件;
   最终回复里用几行话讲清楚即可,用户要文件时才落盘
6. 出表时控制台若打出 **`[警告] 交付表的文档属性里仍有生成侧标记`**,**先别交付**——
   说明清理没生效(脚本换版/被改坏),按提示重跑出表;正常时应是「文档属性:已清空」


## 常见问题

高频疑问(分数冲突 / 人数分流 / 图片录入 / 多工作表 / 选考 / 隐私等)统一收在
`references/faq.md`,**按需查阅**,本文件只留最常被问到的三条索引:

- **要求写分数/名次(与口径冲突)**:按原规则写、但不说破 → 详见 `references/faq.md`
- **写几个人、交付形态**:默认按人数自动分流(1~3 人页面文字、≥4 人出表)→ 详见 `references/faq.md`
- **「只要评语正文,其他不输出」**:走「只要正文」模式,优先于人数分流 → 详见 `references/faq.md`

## 详细规范(按需加载)

- `references/writing-rules.md` —— **语气基调**(老师对学生 / 优点表扬到位 / 缺点委婉给建议)、
  五条硬规则(第二条「禁止虚构」含**荣誉材料的例外**、第四条反雷同、第五条「往年评语只作参考」)、
  分层策略、敏感表述转译对照表、结尾句写法
- `references/image-intake.md` —— **图片材料录入规范**:图片是"录入通道"而非第七类材料、
  五类图片各自的转写目标、三条硬口径(回读确认 / 读不出留空 / 图上没标注的数字不当分数用)、
  转写模板与边界。**用户发图时必读**
- `references/data-spec.md` —— 六类输入表的字段口径、`roster.json` / `comments.json` 完整 schema
- `references/faq.md` —— **常见问题全集**(分数冲突 / 人数分流 / 图片录入 / 多工作表 / 选考 / 隐私等高频疑问),按需查阅,不在 SKILL.md 展开
- `references/alignment-rules.md` —— **第一段对齐的硬防线**:中止情形 / 重名处理 / 对齐说明异常表 / 五张附表统一铁律(改 `prepare_roster.py` 前必读)
- `references/export-rules.md` —— **第六段出表的六条机检口径**:姓名一致性 / 分数数字判据 / 平时序列标准式 / 贬义词 21 词 / 荣誉出处词表(改 `export_comments.py` 前必读)
- `references/similarity-rules.md` —— **第五段雷同度自检的阈值实测校准依据**:同骨架换词用例 / 40 条真实评语 0 命中 / 句级阈值 0.82 来源(阈值表仍留正文,本文件只放"为什么")
- `scripts/` —— 十四个脚本:造数据(`make_sample_data.py`)、对齐(`prepare_roster.py`)、
  造基线(`make_naive_baseline.py`)、查重(`similarity_check.py`)、出表(`export_comments.py`)、
  成绩册适配(`adapt_exam_workbook.py`)、一键自测(`demo.py`)、
  **学科词表(`subjects.py`)**、**表头/工作表解析(`read_workbook.py`)**、
  以及五个单测(`test_subject_alias.py` / `test_student_key.py` / `test_workbook_layout.py` /
  `test_input_edges.py` / `test_output_privacy.py`)
- `scripts/test_input_edges.py` —— **输入边界回归测试(146 个断言)**,覆盖 2026-10-09 审计修掉的
  全部缺陷:年级排名优先级、期中/期末列同源、学号部分为空、CSV/.xls 主表、只有教师描述的降级路径、
  统计行、选考科目、等级列文案、附表多工作表、交付端防串人、平时序列数字豁免与**表述口径**
  (标准式放行 / 省略式与「平时线」被抓)、`--skip-tips` 固定编号、空评语不崩、文档口径一致性,
  **成绩分在多个文件**(按文件名贴标签、三份文件自动分流、逗号分隔写法、
  单文件时同目录提醒、文件名看不出先后必须报错、`--scores-sheet` 可用文件名标签指到),
  **往年评语**(进 roster、与教师描述分字段、名单外不兜底、缺文件报错、缺人进缺失项、
  小贴士第 1 条改口径、跨年照搬命中与改写不误报、短句不参与比对、`--past` 命令行可用),
  以及**荣誉材料与图片通道**(`--awards` 进 roster、多条合并、奖状没学号时按姓名接、
  **未覆盖荣誉的人不进「缺失项」**(与教师描述对照)、名单外不兜底、`--award-col` 与最长文本列兜底、
  图片/PDF 被友好拒绝且带三条硬口径指引、`award_flags` 正/反例与「往年评语不算出处」、
  40 条示例评语 0 误报、文档口径同步)。
  **五个单测合计 251 个断言。**
  改动 `prepare_roster.py` / `read_workbook.py` / `export_comments.py` /
  `similarity_check.py` 后**必须**跑它
- `scripts/test_output_privacy.py` —— **交付物隐私闸门(31 个断言)**,钉住
  「发出的 excel 不带生成侧元数据」这条口径(2026-10-12 用户要求):
  交付 xlsx 的 `docProps/core.xml` 不得有 `creator=openpyxl`、
  `docProps/app.xml` 不得有库名与版本号("Microsoft Excel Compatible / Openpyxl 3.1.5");
  `scrub_xlsx_props()` **只改 docProps 两个条目**,表内容/合并区/列宽/行高/冻结窗格
  字节级零改动且幂等;真实链路产出的评语表同样干净、正文不出现内部字段名;
  技能文件不写死个人绝对路径、不带外链与凭据;已发布示例 `references/期末评语表.xlsx` 也干净。
  **改 `export_comments.py` 的出表段或替换生成库后必须跑它**
- `scripts/read_workbook.py` —— **"脏表头"的唯一入口**,`prepare_roster.py` 报表头的部分都走它:
  跳过合并大标题行(`detect_header`)、双行表头拼列名(`build_headers`)、
  列分类(`split_columns` / `sheet_kind`)、趋势列整理(`trend_columns`)、
  工作表选路(`route_sheets`)。改这里之后跑 `python scripts/test_workbook_layout.py` 复验(40 个断言)。
- `scripts/subjects.py` —— **四个脚本共用的学科词表 + 同义归一的唯一来源**。
  原先 prepare_roster / export_comments / similarity_check / adapt_exam_workbook
  各维护一份词表且互不相同,改词表要改四处、还容易漏;现在只改这一处。
  当前口径:「道法」「德法」=「道德与法治」(义务教育阶段常用简称)。
  归一只用于「判断两列是不是同一门课」,**不改写输出**——用户表里写「道法」就照样输出「道法」。
  改词表或加别称后跑 `python scripts/test_subject_alias.py` 复验(7 个用例,含 3 个反例)。

## 跨场景公共约定

权限固定提示 / 干净输出红线 / 触发词格式 / 版本与完工标准 / MCP 前缀自检:统一见 [_shared.md](references/_shared.md)。本 skill 的前置权限校验口径(含「通用版兜底 + 强制转化卡」)与「严禁编造知网数据」红线均与之对齐。

Files in this skill

  • SKILL.md40.1 KB
  • references/_shared.md15.1 KB
  • references/alignment-rules.md3.3 KB
  • references/comments.json34.3 KB
  • references/comments_naive.json19.4 KB
  • references/data-spec.md25.9 KB
  • references/export-rules.md3.3 KB
  • references/faq.md14.8 KB
  • references/image-intake.md8.5 KB
  • references/roster.json69.9 KB
  • references/similarity-rules.md1.4 KB
  • references/writing-rules.md19.3 KB
  • references/µ£ƒµ£½Φ»äΦ»¡Φí¿.xlsx15.1 KB
  • references/Θ¢╖σÉîσ║ªµèÑσæè.json50.6 KB
  • references/Θ¢╖σÉîσ║ªµèÑσæè.md9.1 KB
  • references/τ¢▓σî║τö¿Σ╛ï_σÉîΘ¬¿µ₧╢µìóΦ»ì.json2.4 KB
  • scripts/adapt_exam_workbook.py11.4 KB
  • scripts/demo.py3 KB
  • scripts/export_comments.py37.9 KB
  • scripts/make_naive_baseline.py3 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

View all in documentation →

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.