포맷

Sume Format 구조화 출력: JSON Schema대로 받는 JSON

JSON Schema를 output_schema로 바인딩하면 Sume Format 실행이 그 형태로 output을 돌려줍니다. 미디어 URL은 모두 실행이 만든 미디어와 대조됩니다.

읽는 시간 6분Sume
전체 글

Sume Format 실행에서 타입이 지정된 JSON을 받으려면 실행 요청에 JSON Schema를 output_schema로 보내세요. 끝난 실행의 output은 그 형태로 돌아오며, 안에 든 모든 미디어 URL은 실행이 실제로 만든 미디어와 대조를 거친 것입니다. 그렇지 않으면 output은 null로 돌아오고, 이유를 알려 주는 output_error가 함께 옵니다.

아래 규칙은 모두 2026-09-25에 확인한 Sume 문서 구조화 출력 (영문)과 Format 호출하기 (영문) 페이지에서 가져왔습니다.

Format 실행에 JSON Schema를 어떻게 바인딩하나요?

Sume Format이란?에서 설명한 호출인 POST /v1/formats/{handle}/{slug}/runs의 본문에 output_schema를 추가하세요. 여기에는 name(필수, 1–64자. 모든 영수증에 나타나므로 네임스페이스를 두세요), strict(기본값 true), schema(필수)가 들어갑니다. 요청별 스키마는 Format에 바인딩된 기본 스키마보다 우선합니다.

OpenAI Chat Completions 기반 클라이언트는 대신 type: "json_schema"를 담은 response_format을 보내도 됩니다. Responses API의 평평한 text.format 형태는 받지 않으며, 두 필드를 모두 보내면 400 invalid_request입니다.

curl -sS -X POST "https://api.sume.com/v1/formats/acme/product-promo/runs" \
  -H "Authorization: Bearer $SUME_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-8823-hero-v1" \
  -d '{
    "instruction": "Make one hero image for the linked product.",
    "input": { "product_url": "https://shop.example.com/p/8823" },
    "output_schema": {
      "name": "acme/promo-hero/v1",
      "strict": true,
      "schema": {
        "type": "object",
        "additionalProperties": false,
        "required": ["headline", "hero_image", "alt_text"],
        "properties": {
          "headline": { "type": "string" },
          "hero_image": { "$ref": "SumeMediaFile#" },
          "alt_text": { "type": ["string", "null"] }
        }
      }
    },
    "primary_output_key": "hero_image"
  }'

Sume는 어떤 JSON Schema 키워드를 받나요?

스키마는 OpenAI strict 모드 부분집합에 맞아야 하며, 이 부분집합은 허용 목록으로 강제됩니다. 목록에 없는 키워드는 무시되지 않고 위반이 됩니다. 부분집합을 벗어난 스키마는 제출 시 400 output_schema_invalid로 실패하고, details.violations[]가 모든 문제를 짚어 주며, 비용은 청구되지 않습니다. 지원 스키마 (영문)에서 가져온, 대부분의 스키마가 걸리는 규칙은 다음과 같습니다.

  • 루트의 type은 정확히 object여야 합니다. 최상위 배열은 객체로 감싸세요.
  • items와 $defs 안의 객체를 포함해 모든 객체에 additionalProperties: false가 필요합니다.
  • 선언한 모든 속성은 required에 있어야 합니다. 필드를 선택 사항으로 두려면 "type": ["string", "null"] 같은 nullable union을 쓰세요.
  • 모든 노드에는 type, $ref, anyOf 중 하나가 필요합니다. oneOf가 아니라 anyOf를 쓰세요. allOf와 nullable: true는 거절됩니다.
  • $ref는 루트의 #/$defs/* 항목과 SumeMediaFile#로만 해석됩니다.
  • 한도는 중첩 10단계, 속성 5000개, enum 하나당 값 1000개, 문자열 합계 120,000자입니다.
허용 키워드, 구조화 출력 (영문) 기준, 2026-09-25 확인.
그룹허용 키워드
구조type, properties, required, additionalProperties, items, $defs, $ref, anyOf
값enum, const
문자열format, pattern, minLength, maxLength
숫자minimum, maximum, exclusiveMinimum, exclusiveMaximum, multipleOf
배열minItems, maxItems
주석title, description, default, examples, $schema, $id

JSON 객체는 어디에서 오나요?

권장 경로인 filled_by: "agent"에서는 스키마가 실행이 끝나기 전에 반드시 호출해야 하는 도구로 실행에 전달되므로, 작업을 한 모델이 직접 객체를 채웁니다. 실행이 유효한 객체 없이 끝나면 폴백 패스인 filled_by: "projection"이 temperature 0의 OpenAI strict json_schema completion으로 객체를 만듭니다.

이 projection이 보는 것은 실행이 생성한 미디어와 마무리 텍스트의 앞 8000자뿐이며, input이나 instruction은 절대 보지 못합니다. 그래서 이 경로에서는 보낸 주문 ID가 되돌아오지 않습니다. 식별자는 실행 ID나 보낸 Idempotency-Key를 키로 삼아 여러분 쪽에 보관하고, Format이 실제로 만드는 것만 요구하세요.

출력에 미디어 URL은 어떻게 넣나요?

실행의 미디어를 넣고 싶은 자리마다 { "$ref": "SumeMediaFile#" } 참조를 두세요. 이 형태의 필드는 모두 필수이고, type과 url을 제외한 모든 필드는 nullable입니다.

  • 커스텀 output에 든 모든 URL은 이 실행이 생성한 미디어와 정확히 일치해야 합니다. 그럴듯한 media.sume.com URL이든 실행이 업로드만 한 파일이든, 그 밖의 URL은 모두 projection을 실패시킵니다.
  • UI에 보여 줄 하나를 primary_output_key(최대 64자)로 지정하면 영수증이 primary_output_url을 해석해 줍니다.
SumeMediaFile 필드, 구조화 출력 (영문) 기준, 2026-09-25 확인.
필드값
typeimage, video, audio, file 중 하나
url이 실행이 실제로 만든 URL
content_type, file_name, size_bytes, width, height파일 메타데이터 또는 null
duration_ms영상과 오디오 길이. 실행이 길이를 기록해 둔 경우 그 값과 10% 이내로 일치해야 함
expires_at일반적인 경우인 내구성 있는 media.sume.com URL에서는 null

출력이 스키마와 맞지 않으면 어떻게 되나요?

output을 읽기 전에 output_error를 확인하세요. API에서는 projection 실패가 곧 실행 실패입니다. status는 failed가 되고, artifacts[]에는 실행이 만든 모든 파일이 그대로 나열됩니다. 실패한 실행은 스키마가 허용할 때만 output에 부분 결과를 보고할 수 있으므로, nullable 필드를 쓰고 일부만이라도 돌려받고 싶은 배열에는 minItems를 두지 마세요. 상태와 웹훅은 Sume Format 실행 수명주기를 참고하세요.

문서화된 코드는 아래와 같으며, 출력을 만들 수 없을 때 (영문)에서 가져왔습니다. 이 집합은 열려 있다고 보세요.

  • output_schema_unsatisfied: 객체가 스키마와 맞지 않았거나, 이 실행이 만들지 않은 미디어를 참조했습니다.
  • output_extraction_failed: projection을 실행할 수 없었습니다. 실행을 한 번 더 읽으세요. harvest_unavailable은 그것만으로 해소됩니다.
  • deliverable_missing: Format이 선언한 미디어를 실행이 만들지 않았습니다.
  • primary_output_missing: 스키마는 충족했지만 지정한 primary_output_key에 값이 없습니다.
  • unattended_blocked, agent_reported_failure: 실행 스스로 결과를 전달하지 못했다고 보고합니다.

Sume 구조화 출력이 하지 않는 일은 무엇인가요?

  • JSON 모드는 없습니다. 스키마를 바인딩하거나 내장 스키마 sume/action-run-output/v1을 쓰세요. 내장 스키마는 nullable text와 images, videos, audio, files 배열로 이루어지고 모델 없이 결정적으로 채워지므로, 커스텀 스키마처럼 실패할 수 없습니다.
  • 탈출구는 없습니다. strict: false는 수락되어 저장되지만 부분집합에 대해서는 아무것도 바꾸지 않습니다.
  • 부분 JSON 스트리밍은 없습니다. output은 종료 영수증에 한 번 나타납니다.
  • 실행이 무엇을 만들지는 제어하지 않습니다. 스키마는 끝난 실행을 어떻게 되읽을지를 제약하므로, Format이 영상을 만들게 할 수는 없습니다.

출처

관련 글

작성자 Sume