[MAICE 개발기 3편] 수식을 실시간으로 렌더링하는 SvelteKit 챗봇 인터페이스

English version

1. 수학 챗봇은 입력창에서부터 막힌다

2편에서는 MAICE가 질문을 분류하고, 명료화하고, 답변하는 구조를 살펴봤습니다. 그런데 실제 교실에서는 그보다 먼저 만나는 장면이 있습니다. 학생이 입력창 앞에서 멈추는 순간입니다.

수학 질문은 일반 문장만으로 이루어지지 않습니다. 분수, 지수, 시그마, 점화식, 증명 과정이 섞입니다. 학생에게 이것을 모두 일반 키보드로 입력하라고 하면, 학생은 수학이 아니라 입력 방식과 싸우게 됩니다.

이 글의 핵심은 UI를 화려하게 만들었다는 이야기가 아닙니다. 학생이 수학 질문을 포기하지 않고 시작할 수 있게 한 장치들을 정리하는 것입니다.

DBR 2차 사이클의 베타테스트(N=11)에서도 이 문제가 드러났습니다. 학생들은 LaTeX 입력을 어렵게 느꼈고, 문제나 풀이를 사진으로 찍어 올리고 싶어 했습니다. 그래서 MAICE 프론트엔드의 목표는 단순한 "예쁜 채팅창"이 아니었습니다.

  • 수식 입력 장벽을 낮출 것
  • 사진 기반 입력을 지원할 것
  • AI 답변의 LaTeX가 스트리밍 중에도 깨지지 않게 할 것
  • 학습 흐름을 방해하는 UI 요소를 줄일 것

2. SvelteKit을 고른 이유

MAICE 프론트엔드는 SvelteKit으로 구현했습니다. 이유는 거창하지 않습니다. 작은 팀이 빠르게 실험하고, 수식 입력과 실시간 렌더링처럼 자주 바뀌는 UI를 단순하게 다루기 위해서였습니다.

수식 입력 컴포넌트는 DOM 변화가 많습니다. 스트리밍 답변은 짧은 간격으로 화면을 계속 갱신합니다. SvelteKit은 이런 상태 변화를 비교적 간결하게 표현할 수 있었습니다.

물론 React나 Vue로도 구현할 수 있습니다. 중요한 것은 프레임워크 이름이 아니라, 학생이 수학 질문을 쓰는 동안 UI가 방해물이 되지 않게 만드는 것이었습니다.


3. 수식을 직접 쓸 수 있게 하기

MAICE의 입력창은 단순 텍스트 박스가 아닙니다. 학생은 글로 질문을 쓰다가 필요한 순간 수식 입력으로 넘어갈 수 있어야 했습니다. 이를 위해 MathLive 기반 입력을 사용했습니다.

개발자에게는 MathLive가 수식 편집 컴포넌트이지만, 학생에게는 "분수와 지수를 조금 덜 힘들게 입력하게 해주는 도구"에 가깝습니다. 모바일에서는 수학 기호용 가상 키보드를 열어 분수, 지수, 괄호 같은 표현을 직접 넣을 수 있습니다.

여기서 중요한 것은 기능의 수가 아닙니다. 학생이 질문을 포기하지 않는 것입니다. 수식 입력이 어렵다는 이유로 질문 자체를 줄이면, 2편에서 만든 질문 명료화 구조도 작동할 기회를 잃습니다.


4. 사진을 질문 초안으로 바꾸기

베타테스트 이후에는 OCR 기능을 도입했습니다. 여기서 OCR은 사진 속 글자와 수식을 읽어 질문 입력을 돕는 기능입니다. 학생 입장에서 보면 문제집의 수식이나 자신이 쓴 풀이를 전부 다시 타이핑하지 않고, 사진에서 출발할 수 있게 해주는 장치입니다.

실제 MAICE의 흐름은 이렇습니다. 학생은 파일을 고르거나, 카메라로 촬영하거나, 클립보드의 이미지를 붙여 넣을 수 있습니다. 이미지는 곧바로 서버로 가지 않습니다. 먼저 필요한 부분만 자를 수 있는 화면을 거칩니다. 한 장의 사진 안에는 문제 번호, 여백, 다른 문항, 학생의 낙서가 함께 들어갈 수 있기 때문입니다.

이미지 선택 / 촬영 / 붙여넣기
-> 필요한 부분 자르기
-> 서버에서 수식과 문장 인식
-> 입력창 커서 위치에 삽입
-> 학생이 확인하고 수정

개발 메모로 남기면, 프론트엔드의 InlineMathInput.svelteImageCropModal.svelte가 이 흐름을 담당합니다. 잘라낸 이미지는 FormDataimage 필드로 POST /student/convert-image-to-latex API에 전달됩니다. 백엔드의 image_to_latex_service.py는 10MB 이하의 JPG, PNG, WebP만 받고, PIL로 이미지를 열어 RGB로 맞춘 뒤 긴 변이 1536픽셀을 넘지 않게 줄입니다. 그다음 Gemini Vision 모델에 "수학 내용을 LaTeX로 반환하되 불필요한 설명을 붙이지 말라"는 지시와 함께 이미지를 보냅니다.

결과도 그대로 쓰지 않습니다. 코드 블록 표시 같은 껍데기를 제거하고, MathLive에서 안정적으로 다루기 위해 일부 LaTeX 표현을 정리합니다. 예를 들어 \dots, \cdots, \vdots\ldots로 통일하고, \times\cdot으로 바꿉니다. 다만 이런 치환이 모든 수학적 맥락에서 항상 최선은 아니므로, 최종 확인은 학생에게 남아 있어야 합니다.

이 지점이 중요합니다. MAICE의 OCR은 자동 풀이 기능이 아닙니다. 사진을 넣으면 바로 답이 나오는 구조가 아니라, 사진을 질문 초안으로 바꾸어 입력창에 넣어 주는 구조입니다. 학생은 인식된 수식과 문장을 확인하고, 필요한 부분을 고친 뒤 자신의 막힌 지점을 덧붙일 수 있습니다.

물론 OCR에는 오인식이 생길 수 있습니다. 숫자 1과 문자 l, 숫자 0과 문자 o, 손글씨 지수나 첨자처럼 헷갈리는 부분이 있을 수 있습니다. 그래서 OCR은 학습 효과의 직접 원인이 아니라, 질문 명료화 실험이 교실에서 작동할 수 있도록 입력 장벽을 낮춘 기반 조건으로 보는 것이 맞습니다.


5. 답변도 깨지지 않게 보여야 한다

학생이 질문을 잘 입력해도, AI 답변이 깨져 보이면 학습 흐름은 다시 끊깁니다. 특히 수식이 포함된 답변은 스트리밍 중에 더 쉽게 깨집니다. 아직 닫히지 않은 LaTeX 기호가 화면에 먼저 나타나거나, 문장 중간에 수식 렌더링이 실패할 수 있습니다.

MAICE는 답변을 한 번에 완성해서 보여주는 대신, 스트리밍으로 조금씩 보여줍니다. 학생 입장에서는 AI가 생각하고 답하는 흐름을 기다릴 수 있지만, 개발 입장에서는 중간 상태의 수식도 안전하게 처리해야 합니다.

그래서 렌더링은 단순히 "마크다운을 HTML로 바꾸기"가 아니라, 수식이 완성되지 않은 상태를 견디는 문제였습니다. 답변이 들어오는 동안 화면이 흔들리지 않고, 수식이 완성되면 자연스럽게 렌더링되도록 조정해야 했습니다.


6. UX 개선을 어떻게 해석해야 하는가

3편에서 다룬 MathLive, OCR, 스트리밍 렌더링은 모두 중요했습니다. 하지만 이것을 곧바로 "학습 효과의 원인"이라고 말하면 안 됩니다.

베타테스트와 본실험은 시점, 참여 조건, 시스템 안정성, UI 상태가 모두 달랐습니다. OCR 외에도 여러 수정이 함께 이루어졌습니다. 따라서 "OCR을 넣었기 때문에 성과가 올랐다"고 해석할 수는 없습니다.

더 정확한 표현은 이렇습니다. 인터페이스 개선은 학생이 질문을 시작하고 이어갈 수 있게 만든 참여 조건이었습니다. 학습 효과 검증의 중심은 질문 명료화 흐름이며, UX는 그 흐름이 교실에서 실제로 작동하도록 도운 기반이었습니다.


7. 기술이 교육을 방해하지 않도록

수학 AI를 만들면서 배운 것은, 좋은 모델만으로는 충분하지 않다는 점입니다. 학생이 질문을 입력하지 못하면 모델은 아무것도 도울 수 없습니다. 답변이 깨져 보이면 학생은 설명을 따라갈 수 없습니다.

그래서 3편의 핵심은 프론트엔드 기술 자체가 아닙니다. 수식 입력, 사진 입력, 렌더링을 통해 학생이 질문을 포기하지 않게 만드는 것입니다.

이제 질문은 다음 단계로 넘어갑니다. 대화가 가능해졌다면, 그 대화가 정말 좋은 학습 대화인지 어떻게 판단할 수 있을까요? 4편에서는 MAICE의 QAC 체크리스트를 다룹니다.

다음 글: [MAICE 개발기 4편] QAC 체크리스트 개발: 교육 품질을 측정 가능한 기준으로 만들기

💬 댓글

이 글에 대한 의견을 남겨주세요