"LLM 모델이나 프롬프트 지시사항에는 전혀 이상이 없는데, 에이전트가 생성한 JSON 데이터 결과물 끝부분에 따옴표(')나 괄호(}) 하나가 누락되어 전체 파이프라인이 먹통이 되어버렸습니다."
AI 에이전트를 연동한 엔드 투 엔드 자동화 파이프라인을 운영하다 보면, 개발자의 혈압을 가장 오르게 만드는 실전 버그가 있습니다. 에이전트의 논리나 생각은 아주 훌륭한데, '출력 포맷의 미세한 문법 에러(JSON Syntax Error)' 때문에 다음 백엔드 노드로 데이터를 넘기지 못하고 전체 프로세스가 터져버리는 현상입니다.
아무리 프롬프트에 "반드시 표준 JSON 규격으로만 출력해!"라고 신신당부를 해두어도, 생성 길이가 길어지거나 순간적인 토큰 생략이 발생하면 닫는 괄호가 빠지거나 중간 쉼표(Comma)가 누락되는 일이 비일비재하죠. 오늘은 제가 직접 겪었던 'JSON 포맷 파싱 에러 폭주 잔혹사'와 이를 깔끔하게 구원해 낸 '구조화된 출력(Structured Output) & 자가 치유(Self-Correction) 파이프라인' 적용기를 나눠보겠습니다.
1. "생각은 완벽한데 괄호 하나 때문에 뻗는다고?" - 텍스트 파싱의 비극
웹 수집 데이터와 사용자 요청을 분석해서 데이터베이스에 바로 들어갈 형태로 정제해 주는 중간 파이프라인 에이전트를 돌릴 때였습니다. 백엔드 시스템은 정교하게 작성된 JSON 데이터를 받아 처리하도록 설계되어 있었지요.
그런데 실전 배포 후 예기치 못한 에러가 연달아 터졌습니다. LLM이 답변을 내놓으면서 친절하게 앞뒤로 ` ```json ` 같은 마크다운 태그를 붙여버리거나, 문장 끝에 주석성 설명을 덧붙이는 바람에 Python의 `json.loads()` 함수가 파싱 에러를 내며 서버를 멈춰 세운 것입니다. 심지어 생성 토큰 제한에 걸려 마지막 `}` 괄호가 끊긴 채 출력되는 바람에 밤샘 관제 알람이 울려 대기 일쑤였습니다.
에이전트의 '자유로운 텍스트 생성 능력'은 큰 장점이지만, 시스템과 시스템을 이어주는 '데이터 파이프라인' 레이어에서는 이 자유로움이 곧 치명적인 독이 된다는 사실을 뼈저리게 느꼈습니다.
2. 시행착오: 프롬프트에 "마크다운 쓰지 마"라고 쓰던 나날들
초기에는 지시사항(Prompt)을 고치는 것에 집중했습니다. "절대로 ```json 태그를 붙이지 마라", "JSON 이외의 인사말이나 설명은 단 한 글자도 적지 마라"라고 엄격한 금지 문구를 빽빽하게 채워 넣었죠.
하지만 지시문만으로는 한계가 명확했습니다. 프롬프트 수정을 거치면 정상 작동 확률이 80%에서 95%로 오르긴 했지만, 100건 중 5건은 여전히 미세한 문법 오류를 일으켰습니다. 99%의 성공률을 자랑해도 단 1%의 문법 오류 때문에 전체 백엔드가 도미노처럼 무너진다면, 그것은 상용화할 수 없는 불안정한 자동화에 불과했습니다.
💡 몬이쌤의 실전 트러블슈팅 깨달음: 아이들에게 서술형 답안을 쓰라고 할 때 "글씨 예쁘게 써라"라고 말로만 당부하는 것보다, 칸이 나뉜 원고지 채점표를 나누어주는 것이 훨씬 정확한 오답을 줄여줍니다. AI 에이전트에게도 말로만 지시할 것이 아니라, 스키마(Schema)라는 정확한 틀을 강제로 씌워주어야 합니다.
3. 해결책: Pydantic 스키마 강제 & 자동 문법 수리(Json Repair) 3단계 방어막
이 고질적인 포맷 파싱 실패를 100% 방지하기 위해, 저는 프롬프트 잔소리를 지우고 '3단계 구조화 포맷 보장 파이프라인'을 구축했습니다.
- 1단계 [Pydantic / Zod 기반 엄격한 스키마 바인딩]: API 호출 시 `with_structured_output()` 기법을 적용하여 모델이 응답을 생성할 때부터 정해진 스키마 타입(String, Integer, List 등)을 벗어나지 못하도록 하드웨어급 제약을 걸었습니다.
- 2단계 [실시간 문법 수리 레이어 (Json Repair Parser)]: 혹시라도 토큰 절단으로 마지막 괄호가 누락되거나 싱글 쿼테이션(')이 섞여 들어오면, 백엔드 수리 라이브러리가 파싱 직전 문법을 실시간으로 교정하여 보완합니다.
- 3단계 [포맷 검증 오류 시 자가 치유(Self-Correction) 피드백]: 2단계 수리조차 불가능한 중대한 스키마 에러 발생 시, 에러 메시지 원문을 에이전트에게 다시 던져 "이 오류를 수정한 올바른 JSON만 다시 리턴하라"고 1회 핀포인트 재요청을 보냅니다.
4. 결과: 포맷 파싱 에러 0건, 견고해진 데이터 파이프라인
스키마 바인딩과 자가 수리 파이프라인을 도입한 이후, 1만 건 이상의 배치 데이터 전환 작업을 수행하는 동안 단 한 건의 JSON 파싱 에러도 발생하지 않았습니다!
개발자가 매번 텍스트 뒤에 붙은 마크다운 태그를 자르려고 `replace()` 코드를 지저분하게 작성하던 시절에서 벗어나, 완벽하게 정제된 객체(Object) 형태의 데이터만 깔끔하게 전달받을 수 있게 되었지요.
AI 에이전트를 실전 자동화 시스템과 연결하는 핵심은 '텍스트를 예쁘게 만들어내는 것'이 아니라, '어떤 상황에서도 시스템이 즉시 삼킬 수 있는 정갈한 데이터 구조로 포맷을 사수하는 것'에 있음을 배웁니다.
여러분의 AI 에이전트 파이프라인도 끊임없이 터지는 문법 파싱 에러로 불안하다면, 지시문 고치기를 멈추고 스키마 강제와 자동 문법 수리 방어막을 쳐보세요. 단단하게 연결된 무결점 데이터 흐름을 경험하게 되실 겁니다.
