LLM이 반환하는 JSON을 처리하여 파싱 오류를 해결하는 방법
요약
LLM이 반환하는 JSON에서 발생하는 파싱 오류를 해결하기 위한 단계별 방법을 소개합니다. 본문에서는 정규 표현식과 Python 코드를 사용하여 마크다운 펜스, 주변 문장, 후행 쉼표 등의 일반적인 문제를 처리하는 방법부터 시작합니다.
핵심 포인트
- 정규 표현식을 사용해 JSON을 감싸는 마크다운 펜스를 제거할 수 있습니다.
- 파싱 과정에서 발생하는 후행 쉼표 등 일반 오류를 수정하고 구조화된 출력을 검증해야 합니다.
- 가장 좋은 해결책은 API 레벨에서 스키마 준수를 강제하는 것입니다 (Structured Outputs).
- 오류 메시지를 모델에 다시 입력하여 재시도하면 문제를 해결할 가능성이 높습니다.
LLM에 JSON을 요청하면 데모에서는 작동하지만 최악의 순간에 프로덕션 환경에서 실패하는 경우가 있습니다. 일반적인 원인은 JSON 주변의 마크다운 코드 펜스(markdown code fence), 그 앞 문장("Sure! Here is the JSON:"), 또는 후행 쉼표(trailing comma)입니다.
여기서는 순수 Python을 사용하여 이 세 가지 문제를 모두 처리하는 작고 단계별 방법을 소개합니다.
1단계: 일반적인 감싸는 부분 제거 (Strip the usual wrapping)
import json
import re
# ...
{% endraw %}
json ...
{% raw %}
fence = re.search(r"```
(?:json)?\s*(.*?)
```", text, re.DOTALL)
if fence:
text = fence.group(1).strip()
# 2. 가장 바깥쪽의 {...} 또는 [...]만 유지
...
2단계: 파싱하고 일반적인 오류 수정 (Parse, and repair the one common error)
def parse_llm_json(text: str):
raw = extract_json(text)
try:
# ...
3단계: 구문뿐만 아니라 구조까지 검증하기 (Validate the shape, not just the syntax)
유효한 JSON이라도 잘못된 키를 가질 수 있습니다. 의존하는 필드를 확인하세요:
def require(data: dict, schema: dict):
for key, typ in schema.items():
if key not in data:
# ...
4단계: 오류 메시지와 함께 재시도하기 (Retry once with the error message)
정확한 오류를 모델에 다시 입력해 주세요. 한 번의 재시도로 대부분의 실패가 해결되며, 두 번 이상의 재시도는 보통 토큰만 소모할 뿐입니다:
def ask_json(call_llm, prompt, schema, retries=1):
reply = call_llm(prompt)
for attempt in range(retries + 1):
# ...
더 좋은 방법: API에 강제하도록 요청하기 (Better: ask the API to enforce it)
방어적으로 파싱하는 것은 최후의 수단입니다. 제공업체가 지원하는 경우, 처음부터 모델이 스키마를 따르도록 구조화된 출력(structured outputs)을 사용하세요. OpenAI의 Structured Outputs 가이드와 Python의 json 모듈 문서를 참조하여 포착할 수 있는 오류 유형(예: json.JSONDecodeError는 줄과 열을 포함합니다)을 확인하세요.
요약 (Recap)
- 펜스와 주변의 서술적인 내용을 제거합니다.
- 파싱하고 후행 쉼표를 제거합니다.
- 키와 타입을 검증합니다.
- 오류 메시지를 인용하여 한 번 재시도합니다.
모델로부터 받은 가장 이상하고 깨진 JSON 출력은 무엇인가요? 테스트 케이스에 추가하고 싶습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기