이 글에서 다루는 내용
6편에서는 AirClassGrading의 첫 번째 흐름인 Teams 과제 자동 채점을 정리했다. 이번 7편에서는 두 번째 흐름, 서술형 채점에 AI를 적용한 구조를 다룬다.
서술형 채점은 Teams 과제 채점과 입력부터 다르다. Teams 과제는 학생이 파일을 제출하고, 그 파일을 기준으로 리뷰한다. 반면 서술형 평가는 보통 종이 답안지를 걷고, 스캔해서 PDF로 만들고, 그 안에서 학생별·문항별 답안을 다시 분리해야 한다.
그래서 이 흐름의 핵심은 다음과 같다.
- 답안 PDF를 학생별·문항별 이미지로 나눈다.
- 문항별 부분점수 기준을 JSON으로 정리한다.
- AI가 문항별 초검을 수행한다.
- 같은 문항을 반복 채점해 흔들림을 확인한다.
- 교사가 최종 점수를 확정한다.
- 반별 평균과 결과 파일을 산출한다.
전체 흐름은 다음과 같다.
왜 서술형 채점 흐름이 따로 필요했나
서술형 평가는 자동 채점이 가장 어려운 영역 중 하나다. 객관식처럼 정답만 비교하면 끝나는 것이 아니라, 풀이 과정과 부분점수를 봐야 한다.
교사가 실제로 보는 요소는 많다.
- 핵심 식을 세웠는가
- 계산 과정이 맞는가
- 중간 실수는 어디에서 생겼는가
- 정답은 틀렸지만 부분점수를 줄 수 있는가
- 그래프나 표기가 충분한가
- 결론 문장이 빠지지는 않았는가
- 같은 오류를 중복 감점하고 있지는 않은가
이 일을 AI에게 바로 맡기면 결과가 흔들릴 수 있다. 그래서 먼저 채점 단위를 명확히 해야 했다.
이 프로젝트에서는 채점 단위를 다음처럼 잡았다.
학생 1명 × 문항 1개
예를 들어 64명의 학생이 5문항을 풀었다면, 채점 대상은 64개가 아니라 320개다.
64명 × 5문항 = 320개 채점 단위
이 단위로 쪼개야 AI도 문항별 기준에 맞춰 볼 수 있고, 교사도 특정 문항만 모아서 검수할 수 있다.
폴더 구조
서술형 채점 흐름은 written_response_grader 아래에 정리되어 있다.
written_response_grader/
core/
grade_cli.py
wrg_preprocess.py
wrg_stats.py
wrg_workflow.py
wrg_paths.py
ieum_chat_client.py
gui/
grading_gui_qt.py
workflow_dashboard.py
preprocessing_setup_dialog.py
data/
grading_criteria.json
preprocess_config.json
manual_regions_page002_ccw05.json
random_mapping.json
student_problem_images_hq/
grading_reviews/
teacher_finals/
source_pdfs/
1test.pdf
1test_rotated_90cw.pdf
1problem.pdf
1answer.pdf
docs/
written_response_grading_workflow.md
AUDIT_REPORT.md
역할을 나누면 다음과 같다.
| 영역 | 역할 |
|---|---|
core |
전처리, AI 채점 CLI, 통계, 경로, API 클라이언트 |
gui |
PySide6 GUI, 워크플로우 대시보드, PDF/칸 설정 화면 |
data |
기준, 설정, 학생별 이미지, AI 리뷰, 교사 최종 평가 |
source_pdfs |
답안지, 문제지, 해설 PDF |
docs |
운영 절차와 코드 감사 기록 |
1단계: 답안 PDF를 문항별 이미지로 나누기
서술형 채점의 첫 단계는 PDF 전처리다. 입력 자료는 다음과 같다.
source_pdfs/
1test.pdf # 학생 답안 스캔본 원본
1test_rotated_90cw.pdf # 방향 보정된 답안 PDF
1problem.pdf # 시험지 원본
1answer.pdf # 해설 및 부분채점기준
스캔 답안지는 바로 채점에 쓰기 어렵다. 한 PDF 안에 표지, 여러 반, 여러 학생 답안이 이어져 있고, 답안지 방향이나 기울기도 맞춰야 한다. 그래서 GUI에서 먼저 PDF와 영역을 설정한다.
설정 파일은 data/ 아래에 저장된다.
data/
preprocess_config.json
manual_regions_page002_ccw05.json
GUI에서는 샘플 페이지를 보면서 다음 영역을 지정한다.
- 학번/이름 영역
- 전체 문제 영역
- 1번 문항 영역
- 2번 문항 영역
- 3번 문항 영역
- 4번 문항 영역
- 5번 문항 영역
또한 반 수, 반별 학생 수, 표지 제외 쪽수, 첫 학번을 설정한다. 예를 들어 4개 반, 반별 16명, 반마다 표지 1쪽이라면 전체 PDF에서 어느 페이지가 첫 학생 답안인지 자동으로 계산할 수 있어야 한다.
문항 영역을 저장한 뒤 이미지 생성을 실행하면 다음 구조가 만들어진다.
data/student_problem_images_hq/
1101/
1101_1.png
1101_2.png
1101_3.png
1101_4.png
1101_5.png
1102/
1102_1.png
...
이제 AI는 전체 PDF가 아니라, 학생 한 명의 한 문항 이미지만 보고 판단할 수 있다.
2단계: 부분점수 기준을 JSON으로 정리하기
서술형 채점에서 가장 중요한 것은 부분점수 기준이다. AI에게 “풀이를 보고 점수를 줘”라고 하면 문항마다 기준이 흔들린다. 그래서 문제 원문, 정답, 해설, 보조채점기준을 JSON으로 정리한다.
핵심 파일은 다음이다.
data/grading_criteria.json
기본 구조는 다음과 같다.
{
"schema_version": "partial_credit_v1",
"common_instructions": "공통 채점 지침",
"notation_penalty": {
"points": -0.5,
"rule": "잘못되거나 불분명한 표기는 건당 0.5점 감점"
},
"problems": [
{
"problem": 1,
"title": "문항 제목",
"problem_text": "문제 원문",
"answer": "정답",
"explanation": "해설",
"max_score": 5,
"scoring_items": [
{
"id": "1-1",
"label": "보조채점기준 이름",
"points": 1,
"criterion": "점수 부여 기준"
}
],
"partial_credit_note": "부분점수 유의사항"
}
]
}
현재 총점 구조는 다음을 기준으로 한다.
| 문항 | 만점 |
|---|---|
| 1번 | 5점 |
| 2번 | 6점 |
| 3번 | 6점 |
| 4번 | 6점 |
| 5번 | 7점 |
| 합계 | 30점 |
기준 JSON에는 단순 정답뿐 아니라 애매한 상황도 명시한다.
- 동치 표현을 어디까지 인정할지
- 표기 오류를 몇 점 감점할지
- 그래프에 점만 찍은 것을 결론으로 인정할지
- 판별식
D,D/4,D'를 어떻게 처리할지 - 계산은 맞지만 결론 문장이 빠진 경우 어떻게 볼지
- 같은 오류를 보조기준 0점과 표기 감점으로 중복 처리하지 않을지
이 기준이 구체적일수록 AI 초검 결과가 안정된다.
실제 문항 기준 예시: 다항식 나눗셈 5점 문항
1번 문항은 다항식의 나눗셈이었다.
[서답형 1]
두 다항식 A=3x^3-4x^2+2x-5, B=x^2-2x+1에 대해,
A를 B로 나눈 몫 Q와 나머지 R을 구하는 과정과 그 결과를 서술하시오. (5점)
정답은 다음과 같다.
Q = 3x + 2
R = 3x - 7
이 문항은 5개의 1점 기준으로 나누었다.
| 기준 ID | 항목 | 배점 | 판단 기준 |
|---|---|---|---|
| 1-1 | 몫 첫째항 | 1 | 몫의 첫째항 3x를 바르게 구함 |
| 1-2 | 첫 번째 곱셈과 뺄셈 | 1 | 3x(x^2-2x+1)을 계산하고 빼서 2x^2-x-5를 구함 |
| 1-3 | 몫 둘째항 | 1 | 몫의 둘째항 2를 바르게 구함 |
| 1-4 | 두 번째 곱셈과 나머지 | 1 | 2(x^2-2x+1)을 계산하고 빼서 나머지 3x-7을 구함 |
| 1-5 | 최종 답 서술 | 1 | Q=3x+2, R=3x-7을 모두 정확히 서술 |
이렇게 쪼갠 이유는 최종 답만 맞고 과정이 약한 답안, 중간 과정은 맞지만 마지막 답을 잘못 쓴 답안, 계산은 틀렸지만 나눗셈 구조를 이해한 답안을 구분하기 위해서다.
공통 채점 지침: 유추 금지와 중복 감점 방지
공통 지침에는 AI가 답안지를 과하게 해석하지 않도록 하는 규칙을 넣었다.
1. 답안지에서 구체적으로 확인되는 사항들을 채점한다. 유추하지 않는다.
2. 서술형 문항들의 최종 결론 형식뿐 아니라 실제 값이나 형태가 일치해야 한다.
3. 요구사항이 2개인 채점기준에서는 한 개 누락 시 절반을 부여한다.
4. 표기 오류 감점은 별도 항목으로 분리하지 않고,
가장 관련 있는 세부기준의 awarded_points에서 직접 0.5점을 차감한다.
같은 오류가 세부기준 미충족으로 이미 0점 처리된 경우는 추가 차감하지 않는다.
이 지침은 AI가 “대충 맞는 것 같다”는 식으로 판단하지 않게 하려는 장치다. 특히 중복 감점 방지는 서술형 채점에서 중요했다. 같은 실수를 이유로 한 세부기준에서 0점을 주고, 다시 표기 오류로 추가 감점하면 실제 교사 채점보다 지나치게 낮아질 수 있기 때문이다.
애매한 기준 사례: 5번 최댓값·최솟값
5번 문항은 그래프와 최댓값·최솟값 결론이 함께 들어가는 문제였다. 이 문항에서는 단순히 그래프 위에 점을 찍은 것만으로 최댓값·최솟값 서술을 인정하지 않도록 했다.
5번 문항의 최댓값/최솟값 서술은 좌표평면 위 점 표시만으로 인정하지 말고,
답안에 x값과 그때의 최댓값/최솟값이 글 또는 식으로 명시되어야 인정한다.
다만 너무 엄격하게만 보지 않도록 보완 기준도 함께 넣었다.
한 문장으로 완벽하게 쓰지 않아도 된다.
계산/서술 영역에서 x값, 함수값, 최댓값/최솟값 표현의 대응 관계가 명확히 확인되면 인정한다.
예를 들어 x=6, y=5가 확인되고 그 근처에 최댓값 표현이 있으면 인정하고,
x=3, y=-4가 확인되고 그 근처에 최솟값 표현이 있으면 인정한다.
이런 기준은 실제 메트릭과도 연결된다. 5번은 교사 수정이 19개로 많았고, AI와 교사 점수의 절대 차이 평균도 0.289점으로 가장 컸다. 즉 이 문항은 기준을 더 세밀하게 쓰는 것이 특히 중요했다.
AI 출력 JSON 예시
AI 초검 결과는 단순 점수만 저장하지 않는다. 어떤 세부기준에서 몇 점을 주었고, 어떤 근거를 보았는지 함께 남긴다. 아래는 개인정보를 제거한 형식 예시다.
{
"student_id": "S-anon",
"problem": 5,
"score": 6.5,
"max_score": 7,
"scoring_results": [
{
"id": "5-1",
"label": "꼭짓점",
"points": 2,
"awarded_points": 2,
"evidence": "y=(x-3)^2-4와 꼭짓점 (3,-4)가 확인됨",
"rationale": "꼭짓점을 정확히 구해 서술했으므로 부여"
},
{
"id": "5-5",
"label": "최댓값",
"points": 1,
"awarded_points": 0.5,
"evidence": "x=6, y=5는 보이나 최댓값 표현이 불명확함",
"rationale": "대응 관계는 보이나 결론 표현이 충분하지 않아 부분점수"
}
],
"notation_penalties": []
}
이 형식이 있으면 교사는 AI가 왜 점수를 그렇게 주었는지 바로 확인할 수 있다. 점수만 보는 것이 아니라, 세부기준별 근거를 보면서 최종 점수를 조정할 수 있다.
3단계: AI 초검 실행
AI 초검은 CLI로 실행한다.
cd written_response_grader
# dry-run
uv run wrg-grade --dry-run --students 1101 --problems 1
# 전체 64명 × 5문항 채점
uv run wrg-grade --workers 4 --retries 2 --repeat 1
# 전체를 3회 반복 채점
uv run wrg-grade --workers 4 --retries 2 --repeat 3
# 특정 문항만 전체 학생 채점
uv run wrg-grade --problems 4 --workers 4
채점 결과는 학생별·문항별 JSON으로 저장된다.
data/grading_reviews/
1101/
1101_1.json
1101_2.json
1101_3.json
1101_4.json
1101_5.json
각 문항 JSON에는 AI 채점 회차가 grading_runs로 누적된다. 예를 들어 같은 학생의 5번 문항을 세 번 채점했다면, 한 JSON 안에 세 회차 결과가 남는다.
이 구조는 중요하다. AI 결과 하나를 바로 믿는 것이 아니라, 반복 결과를 보고 기준이 흔들리는 지점을 찾기 위해서다.
4단계: 반복 채점으로 흔들림 확인하기
서술형 채점에서 AI가 흔들리는 이유는 다양하다.
- 기준 문장이 모호하다.
- 학생 풀이가 여러 방식으로 해석된다.
- 표기 오류와 개념 오류가 섞여 있다.
- 결론은 맞지만 과정이 부족하다.
- 과정은 맞지만 마지막 계산 실수가 있다.
그래서 반복 채점 결과를 비교한다.
확인할 지점은 다음과 같다.
- 같은 학생/문항의 점수 범위가 큰가?
- 특정 보조채점기준이 회차마다 뒤집히는가?
- 표기 감점이 과도하게 중복 적용되는가?
- 명확한 정답이 서술 방식 때문에 과하게 감점되는가?
- 기준 수정 후 평균이 비정상적으로 움직이지 않는가?
문제가 보이면 기준 JSON을 고친 뒤 해당 문항이나 학생만 다시 채점한다.
uv run wrg-grade --students 1101,1111,1206 --problems 5 --workers 4 --retries 2 --repeat 1
이 방식은 “AI를 믿는다”가 아니라, AI가 흔들리는 지점을 이용해 기준을 더 명확히 만든다에 가깝다.
5단계: 교사 최종 점수 확정
AI 초검은 참고 자료다. 최종 점수는 교사가 확정한다.
현재 구조에서는 AI 결과와 교사 최종 평가를 분리한다.
DEFAULT_REVIEW_DIR = DATA_DIR / "grading_reviews"
DEFAULT_TEACHER_FINAL_DIR = DATA_DIR / "teacher_finals"
역할은 다음과 같다.
| 경로 | 역할 |
|---|---|
data/grading_reviews |
AI 채점 결과와 반복 회차 |
data/teacher_finals |
교사 최종 평가 |
이 분리는 중요하다. AI 재채점을 돌렸을 때 교사가 이미 확정한 점수가 덮어써지면 안 된다.
GUI에서는 다음 흐름으로 검토한다.
- 학생별/문항별 답안 이미지 확인
- AI 회차별 채점 결과 확인
- 보조채점기준별 판단 확인
- 교사 최종 점수 입력
- 교사 코멘트 저장
- 다음 미확정 문항으로 이동
특히 문항별 검수에서는 학생 식별 편향을 줄이기 위해 R01~R64 같은 랜덤 ID를 사용할 수 있다. 교사는 학번보다 답안 자체와 기준을 중심으로 보게 된다.
6단계: 통계와 결과 산출
최종 점수가 쌓이면 반별 평균과 문항별 평균을 확인한다. 관련 로직은 wrg_stats.py, wrg_workflow.py 쪽에 있다.
확인할 수 있는 값은 다음과 같다.
- 학생별 총점
- 문항별 점수
- 반별 평균
- 문항별 반 평균
- 채점 완료율
- 누락된 문항 JSON
- 최종 확정 여부
중요한 원칙은 통계와 CSV 산출에서 AI 점수와 교사 최종 점수를 구분하는 것이다. 실제 성적 산출에서는 교사 최종 평가가 우선되어야 한다.
실제 결과로 본 효과
학생 이름, 답안 이미지, 개별 피드백 원문은 공개하지 않았다. 대신 data/ 아래에 남아 있는 비식별 집계만으로도 어느 정도 효과를 볼 수 있다.
현재 서술형 채점 데이터는 다음 규모였다.
| 항목 | 수치 |
|---|---|
| 학생 수 | 64명 |
| 문항 수 | 5문항 |
| 학생별·문항별 답안 이미지 | 320개 |
| AI 리뷰 JSON | 320개 |
| 교사 최종 평가 JSON | 320개 |
| 채점 완료 학생 | 64명 |
| 누락 문항 | 0개 |
즉 전체 64명 × 5문항이 모두 이미지로 분리되었고, AI 초검과 교사 최종 평가까지 빠짐없이 저장된 상태다.
AI 초검은 각 문항당 4회씩 누적되어 있었다.
| 항목 | 수치 |
|---|---|
| 전체 AI 채점 회차 | 1,280회 |
| 문항당 AI 채점 회차 | 4회 |
| 반복 채점 점수 범위 평균 | 0.278점 |
| 4회 결과가 완전히 같은 문항 | 238개 / 320개 |
| 4회 결과 차이가 0.5점 이하인 문항 | 262개 / 320개 |
| 4회 결과 차이가 1점 이하인 문항 | 299개 / 320개 |
이 숫자는 AI 초검이 완벽하다는 뜻이 아니다. 오히려 어느 문항에서 흔들림이 생기는지 확인할 수 있었다는 점이 중요하다. 320개 중 238개는 4회 반복 결과가 같았고, 299개는 1점 이내에서 움직였다. 반대로 21개 정도는 1점을 넘게 흔들렸기 때문에 교사가 더 주의해서 봐야 할 대상으로 잡을 수 있었다.
AI 최종 회차 점수와 교사 최종 점수를 비교하면 다음과 같았다.
| 항목 | 수치 |
|---|---|
| 비교 대상 | 320개 문항 |
| AI 평균 점수 | 4.570점 |
| 교사 최종 평균 점수 | 4.583점 |
| 평균 차이 | +0.013점 |
| 절대 차이 평균 | 0.212점 |
| AI 점수와 교사 점수가 같은 문항 | 248개 / 320개 |
| 차이가 0.5점 이하인 문항 | 279개 / 320개 |
| 차이가 1점 이하인 문항 | 307개 / 320개 |
| 교사가 수정한 문항 | 72개 / 320개 |
| 교사가 올린 문항 | 36개 |
| 교사가 내린 문항 | 36개 |
여기서 눈에 띄는 점은 교사 수정이 한쪽 방향으로 치우치지 않았다는 것이다. AI가 지나치게 박하게만 보거나, 지나치게 후하게만 본 것이 아니라, 실제 교사 검토에서 올린 경우와 내린 경우가 각각 36개로 같았다.
문항별로 보면 차이가 더 잘 보인다.
| 문항 | AI 평균 | 교사 최종 평균 | 평균 차이 | 절대 차이 평균 | 수정 문항 |
|---|---|---|---|---|---|
| 1번 | 4.008 | 4.211 | +0.203 | 0.234 | 15개 |
| 2번 | 4.508 | 4.367 | -0.141 | 0.188 | 10개 |
| 3번 | 5.234 | 5.227 | -0.008 | 0.102 | 9개 |
| 4번 | 4.203 | 4.172 | -0.031 | 0.250 | 19개 |
| 5번 | 4.898 | 4.938 | +0.039 | 0.289 | 19개 |
3번은 AI와 교사 판단 차이가 가장 작았고, 4번·5번은 교사 수정이 상대적으로 많았다. 이런 식으로 보면 “AI가 잘했다/못했다”가 아니라, 어떤 문항의 기준을 더 세밀하게 다듬어야 하는지가 보인다.
교사 최종 점수 기준 반별 총점 평균은 다음과 같았다. 개별 학생 점수는 공개하지 않고, 반 단위 집계만 사용했다.
| 반 | 인원 | 총점 평균 | 최저 | 최고 |
|---|---|---|---|---|
| 11 | 16명 | 25.31 | 15.5 | 29.5 |
| 12 | 16명 | 21.75 | 2.0 | 30.0 |
| 13 | 16명 | 24.69 | 10.0 | 30.0 |
| 14 | 16명 | 19.91 | 2.0 | 30.0 |
이 결과에서 서술형 채점 AI 적용의 효과는 세 가지로 정리할 수 있다.
첫째, 320개 문항을 모두 같은 단위의 이미지와 JSON으로 정리했다. 교사는 더 이상 전체 PDF를 넘겨 가며 특정 학생의 특정 문항을 찾아야 하지 않는다.
둘째, AI 초검을 1,280회 누적해 흔들리는 문항을 찾을 수 있었다. 반복 결과가 안정적인 문항과 교사 검토가 필요한 문항을 구분할 수 있었다.
셋째, 교사 최종 점수가 별도로 남아 AI 결과와 비교 가능해졌다. AI 평균과 교사 평균의 차이는 작았지만, 72개 문항은 교사가 실제로 수정했다. 즉 AI는 최종 결정자가 아니라, 교사가 빠르게 검토할 수 있는 초안 생성자 역할을 했다.
워크플로우 대시보드
gui/workflow_dashboard.py는 서술형 채점 흐름을 하나의 화면으로 묶는다.
1 전처리
PDF 지정 → 샘플 렌더 → 문항 칸 지정 → 학생별 문항 이미지 생성
2 기준/AI채점
채점기준 편집 → CLI 채점 실행 → 결과 새로고침
3 통계/결과
반별 평균 → 결과 확인 → 최종 산출
작업 순서는 다음과 같다.
- 답안 PDF를 지정한다.
- 표지 제외, 반 수, 학생 수, 첫 학번을 설정한다.
- 문항 칸을 잡는다.
- 학생별 문항 이미지를 만든다.
- 채점 기준 JSON을 확인한다.
- AI 초검을 실행한다.
- 흔들리는 기준을 수정하고 재채점한다.
- 교사가 최종 점수를 확정한다.
- 반별 평균과 결과 파일을 확인한다.
이 대시보드는 서술형 채점이 여러 단계로 흩어지는 문제를 줄인다. PDF 전처리, 기준 수정, AI 채점, 결과 확인이 같은 흐름 안에서 이어진다.
코드 정리에서 남은 과제
docs/AUDIT_REPORT.md에는 코드 구조상 조심해야 할 지점도 정리되어 있다. 특히 중요한 것은 다음이다.
첫째, AI 점수와 교사 최종 점수를 섞지 않아야 한다. 통계, CSV, 완료율 계산이 AI 점수만 보고 있으면 최종 확정 단계가 의미를 잃는다.
둘째, CLI와 GUI의 공통 로직은 더 분리할 필요가 있다. 프롬프트 생성, API 호출, 결과 정규화, 저장 로직이 여러 곳에 중복되면 수정할 때 오류가 생긴다.
셋째, 문항별 JSON과 교사 최종 평가 파일의 역할을 명확히 유지해야 한다. 같은 점수가 여러 위치에 중복 저장되면 어느 값이 진짜인지 헷갈리게 된다.
이 부분은 기능의 실패라기보다, 실제 사용하면서 생긴 구조 개선 과제에 가깝다. 서술형 채점은 데이터 흐름이 복잡하기 때문에 저장 위치와 책임을 명확히 나누는 것이 중요하다.
AirClassGrading 1과 2의 연결
6편의 Teams 과제 자동 채점과 이번 서술형 채점 흐름은 입력은 다르지만 같은 문제를 다룬다.
| 구분 | AirClassGrading 1 | AirClassGrading 2 |
|---|---|---|
| 대상 | Teams 과제 제출물 | 스캔된 서술형 답안 PDF |
| 입력 | Teams submission, 첨부 파일 | 답안 PDF, 문제 PDF, 해설 PDF |
| 채점 단위 | 학생 제출물 / 과제 | 학생 1명 × 문항 1개 |
| 기준 | Teams 지시문, 루브릭, snapshot | grading_criteria.json 부분점수 기준 |
| 전처리 | 파일 다운로드, PDF 렌더링, artifact 정리 | PDF 렌더링, 문항별 crop 이미지 생성 |
| AI 역할 | 과제 리뷰, 피드백 초안, 등급/점수 제안 | 문항별 초검, 부분점수 판단 보조 |
| 교사 역할 | 리뷰 확인, 최종 점수/코멘트 | 문항별 최종 점수 확정 |
| 산출 | Teams 피드백, 리뷰 DB | 최종 점수, 반별 평균, 결과 파일 |
결국 핵심은 같다.
학생 산출물을 AI가 먼저 정리하고 검토하게 하되, 최종 판단과 기준 관리는 교사가 할 수 있게 만든다.
정리하면
서술형 채점에 AI를 적용하려면 단순히 이미지를 모델에 넣는 것만으로는 부족하다. 먼저 답안 PDF를 학생별·문항별로 정확히 나누어야 하고, 부분점수 기준을 구조화해야 하며, AI 초검 결과가 흔들리는지 반복 확인해야 한다.
이번 흐름에서 중요한 설계는 다음이었다.
- 채점 단위를 학생 1명 × 문항 1개로 나눈 것
- 답안 PDF에서 문항별 crop 이미지를 만든 것
- 부분점수 기준을
grading_criteria.json으로 관리한 것 - AI 초검을 반복 실행해 기준의 모호함을 찾은 것
- 교사 최종 점수를 AI 결과와 분리해 저장한 것
- 워크플로우 대시보드로 전처리부터 결과 확인까지 묶은 것
AirClassGrading 2는 서술형 평가에서 AI를 어떻게 실제 채점 흐름 안에 넣을 수 있는지 확인한 작업이다. 점수를 자동으로 확정하는 것이 아니라, 교사가 더 빠르고 일관되게 최종 판단할 수 있도록 초검과 정리를 맡기는 구조다.
💬 댓글
이 글에 대한 의견을 남겨주세요