Insight
home
News
home

수학 문제 오류 신고를 AI가 먼저 살펴본다면

날짜
2026/04/17
수학 문제 콘텐츠에는 꽤 자주 오류 신고가 들어옵니다. 학생이 풀다가 "정답이 이상하다", 선생님이 수업 중 "이 해설이 틀린 것 같다"는 식으로 CMS를 통해 접수됩니다. 이 신고들을 매일 콘텐츠팀이 직접 확인하고 처리해왔습니다. 문제는 이 작업이 생각보다 품이 많이 든다는 점입니다. 수학 문제 하나를 검토하려면 문제 이미지, 정답 이미지, 해설 이미지를 모두 열어보고 직접 풀어서 확인해야 합니다. 그리고 판단 기준이 학교급에 따라 달라집니다. "4의 제곱근"을 예로 들면, 중학교 교육과정에서는 양수인 2만 정답이지만 고등학교에서는 ±2가 모두 성립합니다. 같은 문제라도 어느 학교급 콘텐츠냐에 따라 오류 여부 자체가 바뀌는 것입니다.
신고 한 건을 제대로 검토하는 데 간혹 몇십 분이 걸리기도 하는데, 그게 매일 여러 건씩 쌓이다 보면 담당자 입장에서는 결코 가벼운 업무가 아닙니다. 어느 시점부터 자연스럽게 "AI가 먼저 살펴볼 수 있지 않을까"라는 이야기가 나왔습니다. 다만 방향을 잡을 때 팀에서 한 가지를 분명히 했습니다. AI가 신고를 자동으로 처리하거나 결론을 내리는 구조는 원하지 않았습니다. 선생님들이 보내주신 신고 하나하나에 직접 판단하고 응답하는 것이 매쓰플랫의 기본 태도이기 때문입니다. AI는 담당자가 검토하기 전에 필요한 정보를 미리 정리해두는 역할, 그 이상도 이하도 아니었으면 했습니다.

어떤 시스템을 만들었나

결과물인 ReportAssist는 매일 오전 6시에 자동 실행되어 전날 접수된 오류 신고를 분석하고, 초/중/고 학교급별 Slack 채널에 분석 결과를 전송하는 동시에 신고와 처리 답변을 이력으로 기록해 담당자가 언제든 과거 내용을 확인할 수 있도록 합니다.
출근 후 담당자가 Slack을 열면 신고별로 정리된 분석 내용이 전송되어 있습니다. "신고 내용이 타당해 보입니다 / 그렇지 않습니다", "AI가 직접 풀어본 결과 등록된 정답과 일치합니다 / 차이가 있습니다" 같은 식입니다. 메시지 스레드에는 문제·정답·해설 이미지도 함께 첨부되어 있어 CMS를 별도로 열지 않고도 바로 내용을 확인할 수 있습니다. 담당자는 이 내용을 참고해 직접 문제를 확인하고 최종 판단을 내립니다. AI 분석이 틀릴 수도 있고, 문맥상 더 세심한 판단이 필요한 경우도 있습니다. 어디까지나 검토의 출발점입니다.
ReportAssist가 신고를 처리하는 전체 흐름은 이렇습니다.
[CMS에서 신고 조회]     ↓ [문제/정답/해설 이미지 수집 + OCR 텍스트 추출]     ↓ [AI 분석 — 학교급별 프롬프트 적용]     ↓ [Slack 채널에 결과 전송 (초/중/고 분리) + 이력 기록]     ↓ [담당자가 확인 후 최종 처리]
이 흐름 옆에는 콘텐츠팀이 직접 쓸 수 있는 프롬프트 관리 웹 UI도 붙어 있습니다. 여기서 학교급별 AI 판단 기준을 수정하고, 특정 문제로 즉시 테스트해볼 수 있습니다.

만들면서 풀어야 했던 것들

"AI에게 교육과정을 어떻게 설명하지?"

처음 시도는 단순했습니다. 문제 이미지와 신고 내용을 AI에게 보내고 "오류인지 판단해줘"라고 하면 어느 정도 될 거라 생각했습니다. 실제로 돌려보니 학교급 경계에 있는 문제들에서 판단이 흔들렸습니다. 앞서 말한 제곱근 예시처럼, 수학은 어느 교육과정 기준으로 보느냐에 따라 정답 자체가 달라지는 도메인입니다. AI 모델은 이런 맥락을 명시적으로 알려주지 않으면 알 수가 없습니다. 해결 방향은 프롬프트를 계층화하는 것이었습니다. 모든 학교급에 공통으로 적용되는 시스템 프롬프트를 고정해두고, 그 위에 학교급별 지침을 얹는 구조입니다. 중학교 프롬프트에는 "제곱근은 양수만", "이차방정식은 인수분해·근의공식 범위 내에서 판단"이 들어갑니다. 고등학교 프롬프트에는 "미적분 경계조건 주의", "복소수 범위 허용"이 추가됩니다. 중요한 점은 이 프롬프트를 코드에 하드코딩하지 않았다는 것입니다. 수학 교육과정은 매번 바뀌고, 신고 패턴도 쌓이면서 판단 기준을 조정할 필요가 생깁니다. 콘텐츠팀이 개발팀을 거치지 않고 직접 수정할 수 있어야 했습니다.
# 학교급에 맞는 프롬프트를 DB에서 불러와 시스템 프롬프트와 조합 prompt = prompt_store.get_current_prompt(report.school_type) system_prompt = read_file(SYSTEM_PROMPT_FILE) ctx = ReportContext( prompt=system_prompt + prompt.body, attachments=[snapshots.problem, snapshots.answer, snapshots.solution], payload={"report": report, "ocr": ocr_result, "problem_meta": meta} )
Plain Text
복사

"이미지만 보내면 충분하지 않을까?"

AI 모델에 이미지를 직접 읽는 멀티모달 기능이 있으니, 문제 이미지를 그냥 보내면 될 것 같았습니다. 막상 테스트해보니 그것만으로는 부족했습니다. AI 멀티모달 기능이 이미지를 이해하는 데는 강하지만, 수식이나 기호처럼 정밀한 텍스트를 빠짐없이 읽어내는 데는 한계가 있습니다. OCR로 추출한 텍스트를 함께 넣으면 AI가 두 결과를 교차 확인하면서 정확도가 올라갔습니다.
다만 OCR 자체에도 오인식 패턴이 있습니다. 한글 'ㄹ'이 '근'으로, 수직 기호 '⊥'이 숫자 '1'로 읽히는 케이스들입니다. 이런 패턴을 시스템 프롬프트에 명시해서 AI가 참고하도록 했습니다. 결국 AI에게 들어가는 입력은 네 가지입니다. 역할과 판단 원칙을 담은 시스템 프롬프트, 학교급별 교육과정 지침이 담긴 프롬프트, 문제·정답·해설 이미지 원본과 OCR로 추출한 텍스트, 그리고 CMS에서 받은 메타데이터(문제 ID, 신고 내용, 등록된 정답)까지. AI는 이 모든 정보를 종합해서 분석 결과를 냅니다.

"신고 내용이 맞는지 판단하는 것만으로 충분한가?"

첫 번째 분석 단계는 신고 내용이 타당한지 판단하는 것입니다. 그런데 이것만으로는 아쉬운 케이스가 있다는 걸 운영하면서 알게 됐습니다. "정답이 틀렸다"는 신고가 들어왔을 때, 해설도 그 틀린 정답을 기준으로 작성되어 있을 수 있습니다. 이 경우 AI가 문제·정답·해설을 함께 참고하면 세 가지가 일관되게 보여 오류를 그냥 넘길 수 있습니다. 정답과 해설이 함께 잘못된 상황에서는 AI가 틀린 내용을 사실로 받아들일 가능성이 생기는 것입니다. 그래서 2단계를 추가했습니다. AI가 해설을 참고하지 않고 문제만 보고 직접 계산해서 정답을 도출합니다. 그 결과를 등록된 정답과 비교합니다. "AI가 직접 풀어봤더니 다른 결과가 나왔습니다"가 되면, 담당자 입장에서 훨씬 판단하기 쉬워집니다.
# AI 분석 결과의 두 번째 단계: 직접 풀어서 정답 검증 class AdditionalReviewResponse(BaseModel): derived_answer: str # AI가 직접 계산한 정답 checks: List[CheckResult] # 검토 항목별 결과 class CheckResult(BaseModel): code: int # 1=오타/오류 검토, 2=정답 비교 status: str # "ok" / "issue" / "unknown" detail: str # 이슈 있을 경우 근거 설명
Plain Text
복사
구조화된 형식으로 받기 때문에 Slack 메시지도 항목별로 깔끔하게 표시할 수 있습니다.

"어떤 LLM 모델을 쓸지, 선택을 미룬 이유"

수학 도메인에서 LLM 모델별 성능 차이가 실제로 있습니다. 문제 유형에 따라, 그리고 이미지 분석 정확도에서 차이가 보였습니다. 어떤 모델이 항상 우월하다기보다, 케이스에 따라 다릅니다. 더 현실적인 이유도 있습니다. AI 모델 API의 비용과 성능은 계속 바뀝니다. 지금 기준으로 하나를 선택해 코드에 고정해두면 나중에 교체하기가 번거롭습니다. 그래서 모델을 교체 가능한 형태로 설계했습니다. 사용할 모델별로 어댑터를 만들고, 같은 인터페이스를 따르게 했습니다. 학교급별로 어떤 모델을 쓸지 웹 UI에서 설정하면 다음 배치부터 반영됩니다. 새 모델이 나왔을 때는 어댑터 하나 추가하면 됩니다. 결과적으로 담당자는 각 학교급에 가장 적합하다고 판단한 모델의 분석을 참고해 최종 결론을 내릴 수 있게 됩니다.

프롬프트 관리, 개발팀 없이 운영되어야 한다

AI 분석 품질은 프롬프트에 달려 있습니다. 그런데 프롬프트 한 줄 수정에 개발팀이 개입해야 하면 운영 속도가 느려집니다. 콘텐츠팀이 "이번에 들어오는 신고 유형에 이런 지침을 추가하고 싶다"고 할 때 바로 반영이 가능해야 했습니다. 그래서 프롬프트 관리 웹 UI를 따로 만들었습니다. 초/중/고 탭으로 구분된 편집기, 저장 전 변경 내용 미리보기, 버전 히스토리 5개 유지와 원클릭 롤백, 특정 문제 ID로 즉시 테스트 실행까지 갖춰뒀습니다. 특히 버전 관리와 롤백은 처음부터 넣었습니다. 프롬프트를 수정했더니 오히려 판단 품질이 달라지는 경우가 생깁니다. 이전 버전으로 되돌릴 방법이 없으면 원인 파악도 어렵고 복구도 힘듭니다. 실제로 테스트 과정에서 한 번 경험한 뒤로, 롤백은 선택이 아니라 필수라는 생각이 생겼습니다.

만들다가 멈춘 것들

개발 과정에서 구현까지 했다가 일단 멈춘 기능도 있습니다. Slack에서 AI에게 추가 질의를 할 수 있는 기능이었습니다. 배치 결과를 받은 담당자가 스레드에서 "이 신고를 타당하지 않다고 판단한 근거가 뭐야?", "이 부분은 어떤 교육과정 기준으로 판단한 거야?" 같은 질문을 던지면 AI가 그 맥락을 이어받아 답하는 형태였습니다. 대화 이력 관리, 토큰이 너무 많아지면 요약해서 압축하는 로직까지 구현해놓은 상태였습니다. 다만 콘텐츠팀과 논의하면서 일단 멈추기로 했습니다. AI와의 대화 채널이 늘어날수록 결과를 어디서 확인하고 어떻게 판단하는지 흐름이 분산될 수 있다는 의견이 있었습니다. 지금은 배치 결과를 보고 담당자가 직접 원본을 확인하는 방식을 유지하고 있습니다. 필요하다는 쪽으로 의견이 모이면 꺼낼 수 있게 코드는 그대로 두고 있습니다. 이런 방식으로 기능 하나에도 팀 안에서 꽤 많은 논의가 오갔습니다. 기술적으로 만들 수 있는 것과 실제로 쓰기 좋은 것 사이의 간격은 생각보다 크고, 그 간격은 팀과의 대화로만 좁혀집니다.

AI가 판단하는 게 아니라, 판단을 돕는 것

운영하면서 한 가지를 명확히 유지하고 있습니다. AI의 분석 결과는 담당자의 판단을 돕는 자료일 뿐입니다.선생님들이 보내주신 신고는 단순한 오류 제보가 아닌 경우도 많습니다. 교육 현장에서 직접 가르치다 발견한 문제이고, 때로는 문제 자체의 오류보다 출제 의도나 교육과정 적용 방식을 묻는 신고이기도 합니다. 그런 신고에 AI 분석 결과만 보고 처리하는 건 맞지 않습니다. ReportAssist가 하는 일은 담당자가 문제를 열기 전에 이미 기본 정보가 정리되어 있게 하는 것입니다. "AI가 풀어봤더니 문제 없음"이라는 결과가 나왔더라도 담당자는 직접 확인합니다. "AI가 이 부분이 이상하다고 했는데 정말 그런지" 자신의 판단으로 확인합니다. 그 과정이 짧아지고 맥락을 잡기 쉬워지는 것, 거기까지가 이 시스템의 역할입니다. 프롬프트 설계에서도 이 방향을 반영했습니다. AI가 확신이 없을 때 임의로 결론을 내리는 대신 "판단 보류"를 명시하도록 했습니다. 정보가 충분하지 않으면 추정하지 않고 그렇다고 밝히는 것, 그게 자신 없는 결과를 그럴듯하게 포장하는 것보다 담당자에게 실질적으로 도움이 되는 방향입니다.

만들고 나서 정리한 것들

프롬프트도 버전 관리가 필요합니다. 코드는 git으로 이력을 관리하면서 프롬프트는 그냥 덮어쓰는 경우가 많습니다. 여러 사람이 수정할수록, 시간이 지날수록 어느 시점에 뭐가 바뀌었는지 알기 어렵습니다. 처음부터 버전 관리를 넣어두는 게 맞았습니다.
구조화된 응답을 처음부터 설계하는 게 낫습니다. AI의 자유 텍스트 응답을 파싱하다가 형식이 조금 달라지면 파싱이 깨지는 경험을 했습니다. 응답 스키마를 미리 정의하고 구조화 출력으로 받는 형태로 바꾸고 나서 안정성이 올라갔습니다. 어떤 항목이 어떤 형식으로 나와야 하는지를 설계 단계에서 정해두면 뒤에 수정할 일이 없습니다.
모델은 고정하지 않는 편이 낫습니다. AI 모델 생태계가 빠르게 바뀝니다. 특정 모델에 코드를 엮어두면 교체 비용이 생깁니다. 처음부터 교체 가능한 구조로 만들어두면 모델 비교 테스트도 쉽고, 더 나은 옵션이 나왔을 때 부담 없이 전환할 수 있습니다.
팀과의 논의가 기술 결정만큼 중요합니다. 기능을 만들다 멈춘 경험에서 나온 이야기입니다. 기술적으로 가능한 것과 실제로 운영에 맞는 것 사이에는 간격이 있습니다. 사용하는 팀과 자주 이야기하면서 방향을 맞춰가는 것, 그게 결국 도구를 도구답게 만드는 일입니다.

앞으로 보고 있는 것들

현재는 AI 분석 결과가 실제로 얼마나 정확한지를 체계적으로 측정하는 방법을 만들어가는 중입니다. 담당자가 최종 판단한 결과를 이력과 대조해 AI의 판단이 맞았는지 추적하고, 그 데이터를 프롬프트 개선에 반영하는 피드백 루프를 구축하는 것이 다음 과제입니다.
수학이라는 도메인이 까다롭긴 했지만, 그만큼 많은 것을 구체화할 수 있었습니다. AI를 범용 도구처럼 쓰는 것보다, 쓰이는 맥락에 맞게 꼼꼼하게 설계할수록 실제 운영에서 더 유용한 도구가 됩니다. 어떤 도메인이든 "이 맥락에서 AI가 알아야 할 것이 무엇인가"를 정리하는 과정이 결국 가장 중요한 설계 작업이라는 걸, 이번 프로젝트를 통해 확인했습니다. AI를 어떻게 쓸 것인가는 결국 설계 문제입니다.