본문 바로가기

Python 업무 자동화

LLM 환각으로 인한 JSON 파싱 에러 원인과 Pydantic 강제 검증기 도입

LLM 환각으로 인한 JSON 파싱 에러 원인과 Pydantic 강제 검증기 도입

안녕하세요, 파인선생입니다. 지난 편에서 영상 편집 과정의 수동 노가다를 줄이기 위해, AI(LLM)에게 영상 소스와 자막을 미리 'JSON 데이터' 형태로 구조화하여 뽑아내는 꼼수를 도입했었습니다. 이 방식은 인간과 AI의 하이브리드 협업을 극대화하며 제 업무 시간을 획기적으로 단축시켜 주었습니다.

"이제 진짜 완벽한 파이프라인이 완성되었다!"라며 퇴근을 준비하던 찰나, 쌩쌩하게 돌아가던 터미널 창이 새빨간 에러 메시지를 뿜어내며 멈춰 섰습니다. 바로 프로그래머들의 영원한 적, JSONDecodeError: Expecting value 에러였습니다. 오늘은 생성형 AI가 데이터를 반환할 때 저지르는 치명적인 실수(환각)의 구조적 원인과, 이를 방어하기 위한 'Pydantic 강제 검증기' 도입 과정에 대해 상세히 분석해 보겠습니다.

AI는 코더가 아니라 문과생이다 (JSON 괄호의 실종)

에러가 발생한 파이썬 코드를 열어 AI가 뱉어낸 결과물(Response) 로그를 확인해 보았습니다. 정상적이라면 완벽한 딕셔너리(Dictionary) 형태로 출력되어야 할 JSON 데이터의 끝부분이 기괴하게 잘려 있었습니다.

{
  "scene_1": {
    "script": "안녕하세요",
    "image": "인사하는 모습"
  },
  "scene_2": {
    "script": "파인선생입니다"

(마지막 닫는 중괄호 }가 두 개나 누락된 실제 에러 사례)

분명히 시스템 프롬프트에 "반드시 완벽한 JSON 형식으로 출력해라"라고 수십 번을 명령했는데도, 이 똑똑한 척하는 제미나이(Gemini)와 챗GPT는 툭하면 쉼표(,)를 빼먹거나, 따옴표(")를 홑따옴표(')로 마음대로 바꿔 쓰거나, 위 사례처럼 아예 닫는 괄호를 빼먹고 출력을 끝내버렸습니다.

원인은 명확했습니다. LLM(대규모 언어 모델)은 기본적으로 확률에 기반해 '다음 단어'를 예측하는 문과생(언어 모델)이지, 문법의 구조적 완결성을 보장하는 이과생(컴파일러)이 아니기 때문입니다. 문맥상 출력해야 할 데이터가 길어지거나 문장이 복잡해지면, 모델은 내용 생성에 집중하느라 JSON의 구조적 문법 규칙을 까맣게 잊어버리는 환각(Hallucination) 상태에 빠져버린 것입니다.

에러 대기조로 전락한 1인 기업

이 치명적인 JSON 파싱 에러는 저를 파이프라인의 노예로 만들었습니다. 100% 무인화를 꿈꿨지만, AI가 언제 괄호를 빼먹을지 알 수 없었기 때문에 저는 컴퓨터 앞을 떠나지 못하고 터미널만 뚫어져라 쳐다보는 '인간 디버거' 신세로 전락했습니다.

에러가 터지면 수동으로 코드를 중지하고, 로그를 열어 누락된 괄호를 키보드로 직접 채워 넣은 뒤, 다시 파이프라인을 재가동하는 비참한 노동이 반복되었습니다. 자동화를 위해 도입한 AI가 오히려 저에게 24시간 대기조라는 더 큰 짐을 지워버린 역설적인 상황이었습니다.

인간의 한탄 대신 Pydantic 방패를 들다

"AI가 멍청하게 출력한다면, 파이썬으로 멱살을 잡고 고치게 만들자!"
저는 수동 복구를 멈추고 파이썬의 강력한 데이터 검증 라이브러리인 Pydantic을 파이프라인에 전격 도입했습니다.

Pydantic은 데이터의 '틀(Schema)'을 미리 정의해 두고, 들어온 데이터가 이 틀에 완벽히 맞지 않으면 가차 없이 에러를 발생시키는 이과생 검증기입니다. 저는 이 Pydantic과 try-except 예외 처리 구문을 결합하여 새로운 방어 로직을 짰습니다.

  1. 검증: AI가 JSON을 뱉어내면 무조건 Pydantic 모델에 통과시킨다.
  2. 반려: 괄호가 누락되거나 타입이 틀려서 에러가 발생하면, 파이프라인을 멈추는 대신 AI에게 에러 메시지(Validation Error)를 그대로 던져주며 "네가 짠 JSON이 틀렸으니 괄호 채워서 다시 만들어와!"라고 재시도(Retry) 명령을 내린다.
  3. 승인: Pydantic 검증을 통과한 완벽한 데이터만 다음 영상 렌더링 단계로 넘긴다.

결과는 대성공이었습니다. AI가 환각에 빠져 불량 데이터를 뱉어내더라도, Pydantic 방패가 이를 튕겨내고 자동으로 재작업을 지시하니 파이프라인은 단 한 번의 멈춤 없이 24시간 유기적으로 돌아가기 시작했습니다. 기계의 결함을 기계(코드)로 막아내는 완벽한 자동화의 쾌감이었습니다.

터미널 창의 공포, 프론트엔드의 필요성 (다음 편 예고)

Pydantic 도입으로 파이프라인의 내실(Backend)은 강철처럼 단단해졌습니다. 더 이상 에러 때문에 밤잠을 설칠 일도 없어졌죠. 하지만 여전히 해결되지 않은 치명적인 문제가 하나 남아있었습니다.

바로 매일 아침 검은색 터미널(CMD) 창을 띄우고 알 수 없는 영어 명령어(python main.py)를 타이핑해야 하는 제 끔찍한 작업 환경이었습니다. 코딩을 모르는 일반인은 제 시스템을 단 한 번도 실행할 수 없을 만큼 UI가 불친절했습니다. "이 강력한 파이프라인에 예쁜 버튼과 입력창을 달아줄 순 없을까?" 다음 16편, 검은 터미널 창을 벗어나기 위한 'Streamlit 프론트엔드 연동기'를 기대해 주세요.