표준 JSON 모델

발행: (2025년 12월 17일 오전 07:49 GMT+9)
11 min read
원문: Dev.to

Source: Dev.to

목적

Canonical JSON 모델은 FACET‑compliant 시스템이 생성하는 AI 실행 상태의 안정적이고 결정론적인 표현을 정의합니다. 그 목표는 다음을 보장하는 것입니다:

  • 동일한 입력이 바이트 단위로 동일한 JSON을 생성하도록
  • 출력이 비교 가능하고, 캐시 가능하며, 차이점 확인 가능하고, 재생 가능하도록
  • 제공자별 형식이 다운스트림 시스템에 비결정성을 유출하지 않도록

Canonical JSON은 결정론적 컴파일과 확률적 모델 실행 사이의 경계 아티팩트입니다.

왜 결정론적 JSON이 중요한가

현대 LLM 스택은 숨겨진 비결정성을 겪고 있습니다:

비결정성 원인영향
JSON 객체의 필드 재정렬캐시 신뢰성 저하
선택적 필드의 등장/소멸재생 불가능
공급자별 메시지 레이아웃회귀 테스트 무의미
스트리밍 vs 비스트리밍 구조적 변동감사 및 규정 준수 취약
런타임에 적용되는 암시적 기본값

이러한 영향으로:

  • 캐시 신뢰성 저하
  • 재생 불가능
  • 회귀 테스트 무의미
  • 감사 및 규정 준수 취약

정규화된 JSON은 단일 정규화 형태를 강제함으로써 이러한 오류 모드를 제거합니다.

Source:

정규 JSON 문서

정규 JSON 문서는 다음 모든 조건을 만족하는 JSON 객체입니다:

  1. 결정적인 필드 순서
  2. 모든 선택적 필드의 명시적 존재 여부
  3. 안정적인 숫자 및 문자열 인코딩
  4. 제공자에 구애받지 않는 구조
  5. 타입이 지정된 실행 상태에서 완전히 파생

FACET는 정규 JSON을 직렬화 편의성이 아니라 컴파일된 산출물로 취급합니다.

최상위 순서 (규범)

meta
system
tools
examples
history
user
assistant
output

모든 호환 구현은 이 순서를 반드시 유지해야 합니다.

중첩 객체는 다음을 따릅니다:

  • 사전식 키 순서 (UTF‑8, 코드 포인트 순)
  • 실행 순서 또는 명시적 키에서 파생된 안정적인 리스트 순서

정규 JSON은 암시적 기본값 및 구조적 모호성을 금지합니다.

핵심 규칙

RuleRequirement
Optional Fields스키마에 정의되어 있지만 런타임 값에 존재하지 않는 필드는 null 로 렌더링되어야 합니다. 알려진 필드를 생략하는 것은 금지됩니다.
Empty Lists[] 로 렌더링됩니다.
Empty Objects{} 로 렌더링됩니다.
Booleans항상 명시적으로 (true / false) 표시합니다.
Integers앞에 0을 붙이지 않고 렌더링합니다.
Floats정규화된 소수 형태로 (필요한 경우를 제외하고 지수 표기 사용 안 함) 렌더링합니다.
StringsUTF‑8, NFC‑정규화된 문자열이어야 합니다.
EscapingJSON 표준을 따르며, 다른 인코딩 방식은 사용하지 않습니다.
Disallowed valuesNaN, Infinity, 로케일에 의존하는 숫자 형식은 허용되지 않습니다.

Rationale – 명시적인 null 은 JSON 키 집합이 데이터 내용에 관계없이 일정하게 유지되도록 보장합니다. 이는 O(1) 형태 검증과 언어별 기본 직렬화 동작 차이(예: JavaScript vs. Rust)에도 안정적인 해싱을 가능하게 합니다.

Production Pipeline

Input:  [.facet] → [AST] → [R‑DAG] → [Token Box]

Core:              [[ CANONICAL JSON IR ]] ─┤

Views:       ┌──────────────┼───────────────┐
             ▼              ▼               ▼
          [OpenAI]     [Anthropic]      [Gemini]
             │              │               │
Output:      └──────────────┼───────────────┘

                       [ API Call ]
  • Canonical JSON 은 단일 진실의 원천입니다.
  • 제공자 페이로드(OpenAI, Anthropic, Gemini 등)는 파생된 뷰이며, 진실의 원천이 아닙니다.

FACET은 다음 규칙을 강제합니다:

모든 제공자 페이로드는 일시적입니다. Canonical JSON은 영구적입니다.

결과

  • 제공자를 전환해도 이력이 무효화되지 않습니다.
  • 저장된 실행은 벤더 API가 변경되더라도 재생 가능합니다.
  • 감사 및 규정 준수 보고서는 제공자 스키마 변동에 영향을 받지 않습니다.
  • 제공자 어댑터의 버그가 핵심 실행 기록을 손상시킬 수 없습니다.

실제로:

  • Canonical JSON은 저장, 해시, 차이 비교, 그리고 캐시됩니다.
  • 제공자 페이로드는 즉시 생성되어 바로 폐기됩니다.

따라서 실행 레이어에서 벤더 종속성은 구조적으로 불가능합니다. 제공자가:

  • 페이로드를 거부하거나
  • 문서화되지 않은 제약을 적용하거나
  • 스트리밍 의미를 변경하면

그 실패는 어댑터 레이어에만 국한되고, Canonical JSON은 유효하고 안정적이며 재사용 가능합니다.

@test / 스냅샷 테스트

Canonical JSON은 다음과 같은 이유로 AI 시스템에 대한 진정한 스냅샷 테스트를 가능하게 합니다:

  • byte‑for‑byte deterministic
  • provider‑agnostic
  • fully explicit in structure

일반적인 테스트 흐름

  1. 전체 실행 파이프라인을 Pure Mode(순수 모드)로 실행합니다.
  2. 정규 JSON을 생성합니다.
  3. JSON을 해시하거나 스냅샷으로 저장합니다.
  4. 이후 실행은 이 스냅샷과 비교합니다.
@test "payment flow"
  vars:
    amount: 100
    currency: "USD"

  assert:
    - canonical_json_hash == "b3e2…"

보장 사항

  • 로직 변경이 즉시 표시됩니다.
  • 공급자 드리프트가 테스트를 무효화할 수 없습니다.
  • 회귀는 배포 전에 감지됩니다.

기업 시스템에 대해 다음을 가능하게 합니다:

  • deterministic CI pipelines → 결정론적 CI 파이프라인
  • audit‑safe execution logs → 감사‑안전 실행 로그
  • reproducible incident analysis → 재현 가능한 사고 분석
  • long‑term caching with cryptographic guarantees → 암호학적 보장을 갖춘 장기 캐싱

다음 모든 조건이 충족될 경우:

  • 동일한 FACET 문서
  • 동일한 입력
  • 동일한 실행 모드 (Pure)
  • 동일한 렌즈 레지스트리
    그렇다면:
  • 정규 JSON은 동일해야 합니다
  • Hash(canonical_json)동일해야 합니다
  • 하위 동작은 재현 가능해야 합니다

이는 다음의 기반이 됩니다:

  • memoization → 메모이제이션
  • snapshot testing → 스냅샷 테스트
  • deterministic agents → 결정론적 에이전트

Comparison: Ad‑hoc JSON vs. Canonical JSON

PropertyAd‑hoc JSONCanonical JSON
Field orderUnstableDeterministic
Optional fieldsImplicitExplicit (null)
Provider leakageHighNone
Diff‑friendlyNoYes
Cache‑safeNoYes

Canonical JSON은 AI 행동을 버전 관리되고 테스트 가능한 아티팩트로 전환합니다—일시적인 모델 출력이 아닙니다.

재플레이 가능성

재플레이 가능아니오

JSON은 데이터 형식이 아니다.

시맨틱 경계.

Canonical JSON은 그 경계를 논리적으로 다루고, 테스트하며, 신뢰할 수 있는 것으로 변환합니다.
FACET Canonical JSON은 AI 시스템에서 LLVM IR이 컴파일러에서 하는 역할과 동일합니다.

컴파일러 스택

FACET Stack
계층설명
소스 코드.facet 문서
AST타입이 지정된 FACET AST
LLVM IR정규화된 JSON
타깃 백엔드제공자 어댑터 (OpenAI / Anthropic / Gemini)
머신 코드제공자 페이로드

LLVM IR과 공유되는 주요 특성

  • 제공자 독립적인 표현
  • 결정적이며 안정적인 형태
  • 차이점 비교 가능 및 검사 가능
  • 최적화, 캐싱 및 재생을 위한 안전한 대상

LLVM이 하나의 프로그램이 소스 코드를 변경하지 않고도 x86, ARM, WebAssembly 등을 타깃으로 할 수 있는 것처럼, FACET은 하나의 에이전트 아키텍처가 실행 의미론을 변경하지 않고도 여러 LLM 제공자를 타깃으로 할 수 있게 합니다.

이것이 Canonical JSONIntermediate Representation 으로 취급되고, 단순한 직렬화 세부 사항이 아닌 이유입니다. 이 계층이 존재하면 제공자 페이로드는 교체 가능한 구현 세부 사항이 됩니다.

규범적 정규 JSON 모델

이 문서는 FACET v2.0 및 이후 버전에 대한 규범적인 정규 JSON 모델을 정의합니다.

모든 호환 구현은 정규 실행 출력을 생성할 때 이 규칙을 MUST 따라야 합니다.

Back to Blog

관련 글

더 보기 »