Structured Output 정규화
2026년 8월 28일
Structured Output 정규화
- with_structured_output이 항상 스키마 인스턴스를 돌려주지 않는다. provider·모델·버전에 따라 반환 모양이 최소 네 가지다.
- 이 경계가 없으면 유효한 모델 출력이 ValidationError로 버려진다 — 토큰을 쓰고도 Fail-soft 경로로 빠진다.
들어오는 네 가지 모양
| 모양 | 언제 |
|---|---|
Schema 인스턴스 | 정상 |
다른 BaseModel | 래퍼가 감싼 경우 |
envelope dict {raw, parsed, parsing_error} | include_raw=True |
message dict / AIMessage — content에 JSON 문자열 | Ollama가 파싱을 건너뛴 경우 |
정규화 함수
Python
model_validate와 model_validate_json을 나눠 쓰는 게 핵심이다. 앞은 dict를, 뒤는 JSON 문자열을 받는다.
지켜야 할 선 — 의미를 보정하지 않는다
의미를 보정하지 않는다. schema 필드 검증에 실패한 envelope의
contentJSON을 같은 schema로 다시 검증할 뿐이며, 그래도 안 맞으면 원래 예외를 그대로 낸다.
Mermaid스크롤로 확대 · 드래그로 이동
허용되는 것: 모양(shape) 정규화 — 껍데기를 벗겨 같은 스키마로 다시 검증. 금지되는 것: 값 추측 — 빠진 필드 채우기, 정규식으로 값 뽑기, 기본값으로 대체.
정규식으로 억지로 값을 만들어 내면 모델이 안 한 판단을 코드가 한 것이 된다. 그게 실행을 유발하면 원인 추적이 불가능해진다 (Guardrails).
진단 정보를 남긴다
Python
원문을 통째로 로그에 남기지 않고 길이 + sha256 만 남긴다. 같은 실패가 반복되는지는 해시로 알 수 있고, 민감 정보는 안 남는다.
한 줄 정리
정규화는 모양만 통일하고 의미는 절대 만들지 않는 경계다. 실패는 진단 가능한 형태로 호출자에게 넘긴다.
관련
- with_structured_output
- Structured Output
- Pydantic v2 메서드 사전
- JSON Schema
- Ollama
- Fail-soft
- Guardrails
- AI Pipeline Error Normalization
- hashlib과 결정적 ID