如果要在学校工作里选出一项最无意义、最辛苦、最无聊的,我会选生记簿检查。
在初中,学生综合素质评价(生活记录簿)并不那么重要,但在高中它与升学直接相关,因此极其重要。
问题在于,这样的生记簿检查最终找的无非就是简单的错别字、禁止填写用语、拼写等。
这篇文章就是从这样的疑问开始的。
现在这种简单检查,是不是已经可以交给 AI 来做了?
1. 利用 AI 生成生记簿的局限

高中老师都很清楚,用手写的生记簿和交给 AI 生成的生记簿,从文体开始就不一样。
尤其是最近随着升学趋势,流行的写法是把具体观察与教师评价连贯地写出来,这时候如果交给 AI,就会出现如下文体:
在解题过程中,认真核对条件并建立算式,能检查计算结果的态度有所观察。
在式子的变形或图像解析过程中,表现出试图用依据进行说明的态度,能够较为清晰地展现得出结果之前的思维流程,展现了以推理为中心的问题解决能力。
表现出区分计算失误与概念应用差异的努力,通过反复学习,在解决类似问题时准确度有所提升。
关注文本中的表达来推断意义,并联系自身经验扩展思维。
AI 写作的特点是,很难看出学生具体学到了什么、获得了什么。
例如像思维的流程、以推理为中心的问题解决能力、扩展思维这样的描述,教师很难轻易理解到底想说什么。
还有像……的态度有所观察这类文体也非常别扭。
这些部分正是迫使老师只能手写填写生活记录簿的原因。
于是教师们主要就去找错别字、双空格、禁止使用用语等。
2. 用 chatGPT、NotebookLM 不行吗?

当然,利用网页上提供的一般性 LLM 也可以进行生记簿检查。
问题在于可输入文本长度有限,而且对话进行得越久,就越会遗忘最初给定的提示词(prompt)。
因此中间会出现必须不时重新输入一开始的提示词的问题。
那么,是否可以每次都像第一次对话那样重新输入提示词来检查呢?
3. 数据清洗

想要把这种生记簿分析自动化,最大的障碍就是工作门户系统。
上图是从 NEIS 下载生记簿后,对数据格式用虚拟数据再现的样子。
下面附上示例链接。
数据结构真的是糟糕透顶。
接下来要给每一行都标上科目、学期、编号等标签,并把像 8 月和第 12 列那样被截断的部分接起来。
然后删除页码和重复的目录部分。
关于代码的说明已写在注释里。
import pandas as pd
from pathlib import Path
# 먼저 폴더 생성해 줌
cwd = Path.cwd()
resultFolter = cwd / "result"
resultFolter.mkdir(exist_ok=True)
targetFolder = cwd / "target"
# 타겟 폴더안의 .xlsx 파일을 for문으로 돈다.
for file in targetFolder.glob("*.xlsx"):
# 일단 4줄 뛰어넘고, 쓸데없는 null행과 열들은 잘라낸다.
df = pd.read_excel(file, skiprows=4)
df = df.iloc[:, :6]
stNumCol = [i for i in df.columns if "번" in i][0]
subjectNmae = [i for i in df.columns if "과" in i][0]
df.drop(df[df[subjectNmae] == subjectNmae].index, inplace=True)
df.dropna(subset=stNumCol, inplace=True)
df.reset_index(drop=True, inplace=True)
# 열을 돌면서 비어있는 행들을 모두 채워준다.
dropRowIndex = []
for i in range(len(df)):
rowSubNmae = df.iloc[i, 0]
rowGrade = df.iloc[i, 1]
rowClass = df.iloc[i, 2]
rowStNum = df.iloc[i, 3]
rowStName = df.iloc[i, 4]
rowInnerText = df.iloc[i, 5]
if i == 0 :
continue
if pd.isna(rowSubNmae):
df.iloc[i, 0] = df.iloc[i - 1, 0]
if pd.isna(rowGrade):
df.iloc[i, 1] = df.iloc[i - 1, 1]
if pd.isna(rowClass):
df.iloc[i, 2] = df.iloc[i - 1, 2]
if pd.isna(rowStNum):
df.iloc[i, 3] = df.iloc[i - 1, 3]
# 만약 글이 쪼개져 있으면 두 행의 내용을 합쳐주고 하나는 지운다.
# 굳이 dropRowIndex를 만들어 추가한 다음에 지우는 이유는
# for문이 실행되는 동안 df의 길이변화가 일어나지 않도록 하기 위함이다.
if df.iloc[i, 3] == df.iloc[i-1, 3]:
dropRowIndex.append(i)
df.iloc[i-1, 5] = df.iloc[i-1, 5] + df.iloc[i, 5]
df.drop(dropRowIndex, inplace=True)
df.reset_index(drop=True, inplace=True)
df.to_excel(cwd / "교과세특 학년별 과목별_정제.xlsx", index=False)经过这样一次清洗后,数据就会像下面这样整洁。
现在就可以利用这些数据向 AI 发起审查请求了。

4. 提取提示词(prompt)

所有检查的基准都是提示词,因此这是整个设计过程中最需要费心的部分。
从网上下载 PDF 形式的生活记录簿填写要领来制作提示词,是最稳妥的做法。
从上述网站下载文件后,交给人工智能,让它根据我想检查的部分来帮我制作提示词。
然后用该提示词进行 API 请求测试。
下面保留一部分提示词内容。
prompt = """
너는 학생부 세부능력 및 특기사항 검수 전문가다.
입력 JSON 데이터 중 “세부능력 및 특기사항(세특)” 항목만 점검하시오.
[기재 유의어 → 대체 표현 치환 규칙]
다음에 해당하는 경우, 표준 대체 표현으로 반드시 수정한다.
- Google(구글), NAVER(네이버), Daum(다음) 등 → 포털사이트
- Google Classroom(구글 클래스룸), EBS 온라인클래스 등 → 학습 플랫폼 / 원격 학습플랫폼
...중략...
[예외적 허용 항목 — 아래는 수정하지 않음]
- 단순 지명, 국가명, 산업명(학교 특정·진학 연계가 불가능한 경우)
- 교육부/교육청 등 공교육기관 명시
- 교내 수행평가·지필평가의 “정량 미제시” 성취 표현
- 수업 중 개념/원리 학습(예: Z점수 개념 이해, 반도체 공정 원리)
- 일상생활 경험(아르바이트 등)이 학습 연결 맥락일 때
- 일반 공간(아파트 등) 언급
- 미래형 포부/계획(‘가고 싶다’, ‘탐색 중’, ‘꿈꾸고 있다’)
- 독서 제목 및 저자 / 인용문 (‘ ’ 사용 가능)
- 단순 정보 제공이나 개념 학습의 수치(예: 최저임금 1만원, GDP 성장률 2%)는 금지 항목이 아님.
[판정 기준]
- “과거형 실적”이면 수정
- “미래 포부/계획/탐색”이면 유지
- 반드시 앞, 뒤 문맥 기반으로 판단할 것
"""5. 代码
在 OpenAI 官网可以看到简单的示例。
可以以如下代码为基础,或利用 AI 边写边问的“vibe coding”方式来构建 API 请求。
我觉得如果能以表格形式而不是自然语言来接收 AI 的回答会最干净利落。
生记簿检查完后,向同事老师传达相关内容时,消息的形式通常如下:
科目 | 学号 | 姓名 | 修改前 | 修改后 | 修改事由 |
|---|---|---|---|---|---|
地球科学1 | 10100 | 사공힘센 | ~을 함으로써 | ~을 함으로서 | 助词修改 |
生命科学2 | 10300 | 남궁캥거루 | 학생 으로 수업 중 | 학생으로 수업 중 | 空格修改 |
可以像这样强制规定响应格式。
问题在于,如果一次性检查全部科目,token 长度会过长。
为防止这一点,需要按科目拆分内容,在用 pandas 整理响应后再一次性保存。
# 먼저 파일을 과목별로 묶어 jsonDtat로 만든다.
data = df[df["과 목"] == sub]
jsonData = data.to_json(orient="records", force_ascii=False)
# AI에게 응답을 강제하도록 구조를 설계한다.
response = client.responses.create(
model="gpt-5.2",
input=[{
"role": "user",
"content": [
{"type": "input_text", "text": prompt},
{"type": "input_text", "text": jsonData}
]
},
],
text={
"format":{
"type": "json_schema",
"name": "response_format",
"strict": True,
"schema": {
"type": "object",
"properties": {
"rows": {
"type": "array",
"items": {
"type": "object",
"properties": {
"subjectName": {"type": "string"},
"studentName": {"type": "string"},
"before": {"type": "string"},
"after": {"type": "string"},
"edit": {"type": "string"},
"editReason": {"type": "string"}
},
"required": ["subjectName", "studentName", "before", "after", "edit", "editReason"],
"additionalProperties": False
}
}
},
"required": ["rows"],
"additionalProperties": False
}
}
}
)
responseJson = json.loads(response.output[0].content[0].text)["rows"]这样发出一次请求并整理响应后,就可以看到如下内容。

6. 反复修改提示词
现在基本框架已经搭好了,接下来只需不断反复打磨提示词即可。
为了获得更详细的输出,我补充了输出规则和判定规则,并把所有填写注意用语都输入了进去。
7. 使用后感

最重要的是,准确度非常出众。
用这种方式检查后,错别字和空格问题几乎都解决了。
在某些科目中,还发现了记录了海外志愿服务经历的内容,并进行了修改。
由于生记簿填写指引每次都会变,让教师记住所有内容本身就不是件容易的事。
而且我也不太明白,这种生记簿填写活动到底和教育质量有什么关系。
希望能通过一点点减少教师的杂务,早日迎来可以把更多精力投入到教学上的那一天。






댓글을 불러오는 중...