JUN0.DEV
JUN0.DEV

시간표 이미지 AI 인식 및 프롬프트 개선

Published on
  • avatarJunyoung Yang

UniSchedule에서는 사용자가 대학 시간표를 직접 하나씩 입력하는 부담을 줄이는 것이 목표였다. 일정 관리 서비스에서 초기 입력이 번거로우면 사용자는 기능을 써보기 전에 이탈할 수 있다고 봤다.

그래서 시간표 이미지를 올리면 수업명, 요일, 시간 정보를 추출해 일정 데이터로 바꾸는 기능을 검토했다. 단순히 이미지를 설명하는 수준이 아니라, 서비스가 저장할 수 있는 구조화된 데이터로 변환하는 것이 목표였다.

이 글은 시간표 이미지 인식 기능을 만들면서 GPT Vision과 Structured Output을 사용하고, 프롬프트를 어떻게 다듬었는지 정리한 기록이다.

처음 보인 문제

시간표 이미지는 형태가 다양했다. 학교마다 UI가 다르고, 캡처 크기도 다르고, 글자가 작거나 표 경계가 흐린 경우도 있었다.

초기에는 이미지에서 수업 정보를 어느 정도 읽어오더라도, 결과가 서비스에서 바로 쓰기에는 부족했다.

  • 수업명이 일부 잘리거나 합쳐질 수 있었다.
  • 요일과 시간이 잘못 매칭될 수 있었다.
  • 텍스트 설명은 자연스럽지만 DB에 넣기 어려웠다.
  • 누락된 값을 어떻게 처리할지 기준이 필요했다.

즉, 문제는 이미지를 읽는 것만이 아니었다. 읽은 내용을 일정 도메인에 맞는 데이터로 바꾸는 일이 더 중요했다.

해결 방안

이미지 인식에는 GPT Vision을 사용했다. 다만 모델에게 "시간표를 읽어줘"라고만 요청하면 자연어 설명이 섞이기 쉬웠다.

서비스에서 필요한 것은 설명문이 아니라 일정 객체였다. 그래서 출력 형식을 명확히 지정하고, 수업명, 요일, 시작 시간, 종료 시간 같은 필드를 기준으로 구조화된 결과를 받도록 했다.

이때 확인한 기준은 아래와 같았다.

  • 각 수업이 독립된 항목으로 분리되는가
  • 요일과 시간 정보가 안정적으로 매칭되는가
  • 누락된 값이 있을 때 임의로 채우지 않는가
  • 서비스에서 바로 검증하고 저장할 수 있는 형태인가

AI 기능을 적용한다는 것은 모델 응답을 그대로 보여주는 일이 아니었다. 백엔드 입장에서는 결국 신뢰할 수 있는 입력 데이터로 바꿔야 했다.

적용 및 구현

프롬프트를 작성할 때 가장 신경 쓴 것은 모델이 추측하지 않게 만드는 것이었다.

시간표 이미지에서 명확히 보이지 않는 정보가 있을 때, 모델이 빈칸을 임의로 채우면 오히려 문제가 된다. 그래서 확인되지 않는 값은 비워두거나 낮은 확신도로 표시하도록 유도했다.

또한 출력 형식도 반복해서 조정했다. 처음에는 자연어 설명이 섞였고, 그다음에는 JSON 구조는 맞지만 필드명이 달라지는 문제가 있었다. 그래서 필드 이름과 값 형식을 고정하고, 예시를 함께 넣어 응답 형태를 제한했다.

프롬프트에서 중요했던 기준은 이렇다.

  • 모델이 설명보다 데이터를 반환하게 한다.
  • 알 수 없는 값은 추측하지 않게 한다.
  • 요일과 시간을 서비스 기준 형식으로 맞춘다.
  • 결과를 백엔드에서 검증할 수 있는 형태로 제한한다.

백엔드에서 다시 확인해야 했다

AI가 구조화된 결과를 줘도 그대로 저장하면 안 된다고 봤다. 최종적으로는 백엔드에서 한 번 더 검증해야 했다.

예를 들어 시작 시간이 종료 시간보다 늦거나, 요일 값이 허용 범위를 벗어나거나, 수업명이 비어 있으면 그대로 저장하지 않아야 했다. AI 출력은 편의 입력일 뿐이고, 서비스 데이터로 들어가기 전에는 일반 입력과 같은 검증 과정을 거쳐야 했다.

이 지점에서 AI 기능도 결국 API 입력 처리와 크게 다르지 않다고 느꼈다. 사용자가 직접 입력한 값이든, 모델이 추출한 값이든, 서비스에 저장되는 순간에는 도메인 규칙을 통과해야 했다.

마무리

이 기능을 만들면서 정리한 기준은 단순했다. AI 기능은 사용자의 입력 부담을 줄여야 하지만, 서비스 데이터의 책임까지 모델에 넘기면 안 된다.

이후 비슷한 기능을 만들 때는 아래 항목을 먼저 확인한다.

  • 모델 출력이 서비스가 받을 수 있는 데이터 구조인가
  • 모델이 알 수 없는 값을 추측하지 않도록 막았는가
  • 백엔드에서 다시 검증할 수 있는 형태인가
  • 실패했을 때 사용자가 직접 수정할 수 있는 흐름이 있는가

시간표 이미지 인식은 화려한 AI 기능이라기보다, 불안정한 이미지 입력을 안정적인 일정 데이터로 바꾸는 문제였다. 그렇게 보니 프롬프트뿐 아니라 출력 형식, 검증, 수정 흐름까지 함께 설계해야 했다.