welclaiAI·TREND·DIGEST
도구

구조화된 출력: 모델에서 믿을 수 있는 JSON 얻기

코드가 산문이 아니라 데이터를 필요로 할 때, 모델은 깔끔하고 파싱 가능한 구조를 반환해야 합니다. 막연한 기대 대신 믿을 수 있는 JSON을 얻는 법입니다.

tools2026-05-21 08:19 KST·편집장·7

멋진 문단을 쓰는 언어 모델은 사람에게 유용합니다. 다른 프로그램에 입력을 공급하는 언어 모델은 더 어려운 일을 해내야 합니다. 코드가 파싱할 수 있는 형태의 데이터를, 매번, 놀라움 없이 반환하는 것입니다. 출력을 여러분이 직접 읽기를 멈추고 그것을 json.parse에 넘기기 시작하는 순간, 산문은 부채가 되고 구조는 요구사항이 됩니다. 이 가이드는 "모델이 보통 JSON 비슷한 무언가를 반환한다"와 "내 파이프라인이 모델의 출력에 의존할 수 있다" 사이의 간극을 좁히는 것에 관한 것입니다 — 프로덕션에서 "보통"은 "정해진 일정마다 고장 나는"과 같은 말이니까요.

산문으로는 충분하지 않은 이유

모델이 사람에게 답할 때, 작은 결함들은 사람의 유연함 속으로 사라집니다. 답이 "물론이죠, 여기 있습니다:"로 시작하든, 데이터를 코드 펜스로 감싸든, 지난번과 약간 다른 단어로 필드를 라벨링하든, 독자는 신경 쓰지 않습니다. 파서는 그 모든 것에 신경 씁니다. 데이터 앞의 떠도는 문장 하나, 후행 쉼표 하나, 어떤 때는 숫자였다가 어떤 때는 "unknown"이라는 단어인 필드 하나 — 이 가운데 어느 하나가 작동하던 파이프라인을 스택 트레이스로 바꿉니다.

핵심 문제는 모델이 그럴듯한 텍스트를 만들도록 훈련되었다는 점이며, 그럴듯한 텍스트는 유효한 구조화 데이터와 같지 않습니다. 내버려 두면 모델은 정확히 여러분이 모델에게 엄격하고 기계가 읽을 수 있기를 원하는 그 순간에, 도움이 되고 대화하려는 쪽으로 표류합니다. 믿을 수 있는 구조화 출력을 얻는 일은 그 표류를 제거하는 작업입니다. 몇 가지 지렛대가 있고, 그것들은 쌓입니다.

지렛대 하나: 정밀하게 요청하라

가장 저렴한 개선은 가장 자주 건너뛰는 것이기도 합니다. 원하는 형태가 정확히 무엇인지 모델에게 말하고, 보여 주십시오. 모호한 지시는 모호한 구조를 낳습니다. "세부 정보를 JSON으로 반환하라"는 요청은 모델이 필드 이름, 중첩, 타입을 발명하게 내버려 두고, 모델은 호출마다 그것들을 다르게 발명할 것입니다.

대신 스키마를 구체적으로 명시하십시오. 모든 필드의 이름을 짓고, 그 타입을 밝히고, 필수인지 말하고 — 사람들이 빠뜨리는 부분이 이것인데 — 유효한 응답의 완전한 예시를 보여 주십시오. 모델은 예시에 패턴 매칭하는 데 놀라울 만큼 능하며, 잘 짜인 샘플 하나가 한 문단의 설명보다 형식을 못 박는 데 더 큰 역할을 합니다. 중요한 규칙도 명시적으로 밝히십시오. 출력은 둘러싼 텍스트 없이 JSON만이어야 한다는 것, 빠진 값은 생략하거나 추측하지 말고 특정한 방식으로 표현해야 한다는 것, 필드 집합은 고정되어 있다는 것을요. 요청에서의 정밀함은 다른 모든 것이 그 위에 세워지는 토대입니다. 그것을 건너뛰면 이후의 지렛대들은 여러분이 만든 문제를 땜질하는 것입니다.

지렛대 둘: 모델의 구조화 출력 기능을 사용하라

정중하게 요청하는 것은 도움이 되지만, 지시만으로는 모델이 헤맬 여지가 남습니다. 이제 대부분의 진지한 LLM 제공자는 구조화 출력을 위한 기능을 따로 제공하며, 그것을 사용하는 것은 프롬프트만으로 하는 것보다 크게 한 단계 위입니다.

이 기능들은 몇 가지 형태로 옵니다. 가벼운 형태는 출력을 유효한 JSON으로 제약하는 모드입니다 — 모델이 문법적으로 올바르지 않은 어떤 것도 내놓지 못하게 막아, "문장을 덧붙였다"와 "코드 펜스를 썼다" 류의 실패 범주 전체를 제거합니다. 더 강한 형태는 출력이 따라야 할 스키마를 공급하게 해 주어, 결과가 유효한 JSON일 뿐 아니라 올바른 필드와 타입을 갖춘, 여러분이 요청한 정확한 형태의 유효한 JSON이 되게 합니다.

이런 기능이 존재하는 곳에서는, 손으로 만든 프롬프트보다 그것들을 선호하십시오. 그것들은 보장을 "모델에게 요청했다"에서 "시스템이 강제한다"로 옮기며, 그 전환이 게임의 전부입니다. 무엇이 제공되고 어떻게 호출하는지는 제공자의 문서를 확인하십시오. 구체적인 내용은 다르지만 원칙은 일정하니까요. 모델의 선의에 기대는 대신 플랫폼이 구조를 강제하게 하십시오.

지렛대 셋: 믿기 전에 검증하라

최고의 프롬프트와 가장 강력한 구조화 출력 기능을 갖추고도, 검사하기 전까지는 모델의 출력을 신뢰할 수 없는 것으로 다루십시오. 이는 편집증이 아닙니다. 어떤 외부 입력에든 적용할 바로 그 규율입니다. 검증에는 두 계층이 있고, 둘 다 원해야 합니다.

  • 구조적 검증은 출력이 파싱되고 스키마와 일치하는지 확인합니다. 올바른 필드가 존재하고, 타입이 맞고, 필수 값이 빠지지 않았는지를요. 이것은 상류의 모든 것을 빠져나간 잘못된 형식의 응답을 잡아냅니다.
  • 의미적 검증내용이 여러분의 도메인에서 말이 되는지 확인합니다. 날짜가 실제 날짜인지, 카테고리가 허용된 값 중 하나인지, 수량이 그럴듯한 범위에 있는지, 참조된 식별자가 실제로 존재하는지를요. 응답은 완벽하게 유효한 JSON이면서도 여전히 헛소리일 수 있으며, 오직 도메인 검사만이 그것을 잡아냅니다.

검증을 사후 처리가 아니라 관문으로 실행하십시오. 관문을 통과하지 못한 출력은 결코 멀쩡한 것처럼 시스템의 나머지에 닿아서는 안 됩니다. 관문에서 무엇을 하는지가 다음 지렛대의 주제입니다.

지렛대 넷: 여전히 마주칠 실패를 처리하라

위의 어떤 조합도 완벽하지 않으니, 잔여 실패가 일어나지 않을 척하는 대신 그것에 대비해 설계하십시오. 검증이 실패할 때, 대체로 선호 순서대로 몇 가지 온전한 선택지가 있습니다.

첫째는 경계가 있는 재시도입니다. 많은 구조화 출력 실패는 일회성이며, 그저 다시 요청하는 것 — 이상적으로는 이전 시도의 무엇이 잘못됐는지 모델에게 알려 주면서 — 으로 성공합니다. 지속적인 실패가 영원히 루프 돌지 않도록 재시도에 경계를 두십시오. 둘째는, 사소하고 예측 가능한 문제에 대한 수리입니다. 떠도는 코드 펜스를 다듬고, 명백한 형식 오류를 고치고, 거의 맞는 결과를 기대한 형태로 강제하는 것이죠. 수리는 좁고 보수적으로 유지하십시오. 공격적인 자동 수정은 진짜 문제를 숨기고 데이터를 손상시킬 수 있으니까요. 셋째는, 재시도와 수리가 소진됐을 때의 깔끔하고 로깅된 실패입니다 — 나쁜 데이터를 하류로 넘기는 대신 폴백 경로나 사람 검토로 사례를 보내고, 패턴을 볼 수 있도록 로깅하십시오. 끊임없이 검증에 실패하는 필드는 또 다른 수리 규칙을 더하라는 게 아니라 프롬프트나 스키마를 고치라는 신호입니다.

스키마는 일이 허용하는 만큼 단순하게 유지하라

따로 언급할 가치가 있는 조용한 지렛대입니다. 여러분이 요청하는 것의 복잡함은 그것을 얼마나 믿을 수 있게 얻는지에 직접 영향을 미칩니다. 깊게 중첩된 객체, 선택적 필드의 긴 목록, 정교한 조건부 구조는 모두, 평평하고 작고 필수 필드만 있는 형태보다 모델이 일관되게 만들어 내기 더 어렵습니다. 바로크적인 스키마를 다루려 영리한 프롬프트에 손을 뻗기 전에, 스키마가 정말 그렇게 바로크적일 필요가 있는지 물으십시오. 흔히 복잡한 추출 하나를 단순한 둘로 나누거나, 필요가 아니라 깔끔함 때문에 중첩한 구조를 평평하게 펼 수 있습니다. 가장 믿을 수 있는 구조화 출력은 여러분이 과도하게 복잡하게 만들지 않은 구조입니다.

정리

모델에서 믿을 수 있는 JSON을 얻는 것은 단일한 묘수가 아니라 서로를 보강하는 습관의 더미입니다. 정밀하게 요청하고 예시를 보여 주십시오. 모델이 단지 의도하는 게 아니라 플랫폼이 형태를 강제하도록 제공자의 구조화 출력 기능을 사용하십시오. 모든 응답을 구조적으로도 의미적으로도 검증하고, 통과하기 전까지 신뢰할 수 없는 것으로 다루십시오. 경계가 있는 재시도, 좁은 수리, 깔끔한 폴백으로 남는 실패에 대비해 설계하십시오. 그리고 스키마를 일이 요구하는 것 이상으로 복잡하게 만들지 마십시오. 이것들을 함께 해내면, 프로덕션에서 중요한 선을 넘게 됩니다. 보통 파싱 가능한 데이터를 반환하는 모델에서, 실제로 의존할 수 있는 파이프라인으로요.

#structured-output#json#schema#validation