AI_COMPLETE

AI_COMPLETE (구조화 출력)

AI_COMPLETE는 완성 응답이 따라야 할 JSON 스키마 또는 SQL 타입 리터럴을 제공받아 구조화 출력을 만들어요. 구조화 출력은 AI 데이터 파이프라인에서 후처리(post-processing)의 필요성을 줄이고 결정적 응답을 요구하는 시스템과의 원활한 통합을 가능하게 해요. AI_COMPLETE는 생성된 각 토큰을 구조화 출력 정의와 대조해 검증해 응답이 타입 구조를 준수하게 해요.

AI_COMPLETE가 지원하는 모든 모델이 구조화 출력을 지원하지만, 일반적으로 가장 강력한 모델이 더 높은 품질의 응답을 생성해요.

출처: Snowflake SQL Reference

본문

타입 리터럴과 함께 AI_COMPLETE 사용

타입 리터럴을 사용하면 SQL 타입으로 AI_COMPLETE의 구조화 출력을 정의할 수 있어, Snowflake의 SQL과 JSON 타입 사이 내장 매핑을 활용해요. 타입 리터럴을 TYPE 키워드로 시작하고 최상위 타입으로 SQL OBJECT를 사용하세요. 최상위 객체의 속성은 JSON으로의 지원되는 매핑을 가진 모든 SQL 타입일 수 있어요.

참고: 타입 리터럴은 AI_COMPLETE의 단일 문자열 텍스트 프롬프트 버전에서만 지원돼요. 자세한 내용은 AI_COMPLETE (Single string) 문서를 참고하세요.

다음 예제는 프롬프트에 대해 구조화 출력을 만들기 위해 타입 리터럴을 사용해요. 프롬프트에는 모델에 대한 지침과 처리할 데이터가 모두 담겨 있어요. response_format 타입 리터럴은 모델의 응답을 최상위 note에 date, address, items_count와 price 배열을 담은 JSON 객체로 만들어요.

SELECT AI_COMPLETE(
    model => 'llama3.3-70b',
    prompt => 'Extract structured data from this customer interaction note: Customer Sarah Jones complained about the mobile app crashing during checkout. She tried to purchase 3 items: a red XL jacket ($89.99), blue running shoes ($129.50), and a fitness tracker ($199.00). The app crashed after she entered her shipping address at 123 Main St, Portland OR, 97201. She has been a premium member since January 2024.',
    response_format => TYPE OBJECT(note OBJECT(items_count NUMBER, price ARRAY(STRING), address STRING, member_date STRING)),
    show_details => TRUE
);

다음은 이 쿼리에 대한 완전한 응답이에요:

{
  "created": 1758755328,
  "model": "llama3.3-70b",
  "structured_output": [
    {
      "raw_message": {
        "note": {
          "items_count": 3,
          "price": [
            "$89.99",
            "$129.50",
            "$199.00"
          ]
        }
      },
      "type": "json"
    }
  ],
  "usage": {
    "completion_tokens": 49,
    "prompt_tokens": 100,
    "total_tokens": 149
  }
}

타입 리터럴 노트 및 제한 사항

구조화 출력 스키마를 타입 리터럴로 지정하면 다음 규칙을 따릅니다.

  • STRING과 VARCHAR 타입은 JSON 문자열로 매핑돼요.
  • VARCHAR 타입은 특정 길이의 출력을 보장하지 않아요.
  • 스케일이 없는 FIXED 타입은 JSON 정수로 매핑돼요. 다른 모든 숫자 타입은 JSON 숫자로 매핑돼요.

타입 리터럴은 지원되는 타입에 제한이 있어요.

  • 빈 객체 OBJECT()는 타입 리터럴로 허용되지 않아요.
  • 모든 SQL 타입이 구조화 출력에 매핑을 가지는 것은 아니에요. 여기에는 다음이 포함되지만 이에 국한되지는 않아요.
    • VARIANT
    • MAP
    • 날짜·시간 데이터 타입

지원되지 않는 데이터 타입을 사용하면 오류가 반환돼요.

JSON 스키마와 함께 AI_COMPLETE 사용

구조화 출력에 대해 더 많은 제어가 필요하면 response_format 값으로 JSON 스키마를 사용하세요. 제공된 JSON 스키마는 필수 필드를 포함해 생성된 텍스트가 따라야 할 구조, 데이터 타입, 제약 조건을 정의해요.

간단한 작업에서는 출력 형식의 세부 사항을 지정하거나 모델에 "respond in JSON"이라고 지시할 필요조차 없어요. 더 복잡한 작업에서는 모델이 JSON으로 응답하도록 프롬프트하는 것이 정확도를 높일 수 있어요. JSON 준수 정확도 최적화 참고.

다음은 구조화 출력 형식을 지정하기 위해 JSON 스키마를 사용하는 AI_COMPLETE 함수 호출의 문법을 보여줘요. 스키마는 최상위 객체, properties를 정의하며, string 타입의 property_name 속성을 가집니다. 이 필드는 응답에서 필수예요.

AI_COMPLETE(
    ...
    response_format => {
        'type': 'json',
        'schema': {
            'type': 'object',
            'properties': {
                'property_name': {
                    'type': 'string'
                },
                ...
            },
            'required': ['property_name', ...]
        }
    }
)

중요: OpenAI (GPT) 모델의 경우 다음 요구사항이 적용돼요.

  • 스키마의 모든 노드에서 additionalProperties 필드가 false로 설정되어야 해요.
  • required 필드가 포함되어야 하고 스키마의 모든 속성 이름을 담고 있어야 해요.

다른 모델은 이 필드를 요구하지 않지만, OpenAI 모델용으로 다른 스키마가 필요 없도록 포함해도 좋아요.

SQL 예제

다음 예제는 단일 문자열 입력과 함께 AI_COMPLETE를 사용하는 더 완전한 데모예요.

SELECT AI_COMPLETE(
    model => 'mistral-large2',
    prompt => 'Return the customer sentiment for the following review: New kid on the block, this pizza joint! The pie arrived neither in a flash nor a snail\'s pace, but the taste? Divine! Like a symphony of Italian flavors, it was a party in my mouth. But alas, the party was a tad pricey for my humble abode\'s standards. A mixed bag, I\'d say!',
    response_format => {
            'type':'json',
            'schema':{'type' : 'object','properties' : {'sentiment_categories':{'type': 'object','properties':
            {'food_quality' : {'type' : 'string'},'food_taste': {'type':'string'}, 'wait_time': {'type':'string'}, 'food_cost': {'type':'string'}},'required':['food_quality','food_taste' ,'wait_time','food_cost']}}}

    }
);

응답:

{
    "sentiment_categories":
    {
        "food_cost": "negative",
        "food_quality": "positive",
        "food_taste": "positive",
        "wait_time": "neutral"
    }
}

다음 예제는 응답용 JSON 스키마를 지정하기 위해 response_format 인자를, 추론 메타데이터를 반환하기 위해 show_details 인자를 사용하는 방법을 보여줘요.

SELECT AI_COMPLETE(
    model => 'mistral-large2',
    prompt => 'Return the customer sentiment for the following review: New kid on the block, this pizza joint! The pie arrived neither in a flash nor a snail\'s pace, but the taste? Divine! Like a symphony of Italian flavors, it was a party in my mouth. But alas, the party was a tad pricey for my humble abode\'s standards. A mixed bag, I\'d say!',
    response_format => {
            'type':'json',
            'schema':{'type' : 'object','properties' : {'sentiment_categories':{'type': 'object','properties':
            {'food_quality' : {'type' : 'string'},'food_taste': {'type':'string'}, 'wait_time': {'type':'string'}, 'food_cost': {'type':'string'}},'required':['food_quality','food_taste' ,'wait_time','food_cost']}}}

    },
    show_details => TRUE
);

응답:

{
    "created": 1738683744,
    "model": "mistral-large2",
    "structured_output": [
        {
        "raw_message": {
            "sentiment_categories":
            {
                "food_cost": "negative",
                "food_quality": "positive",
                "food_taste": "positive",
                "wait_time": "neutral"
            }
        },
        "type": "json"
        }
    ],
    "usage": {
        "completion_tokens": 60,
        "prompt_tokens": 94,
        "total_tokens": 154
    }
}

Python 예제

참고: 구조화 출력은 snowflake-ml-python 버전 1.8.0 이상에서 지원돼요.

다음 예제는 응답용 JSON 스키마를 지정하기 위해 response_format 인자를 사용하는 방법을 보여줘요.

from snowflake.cortex import complete, CompleteOptions

response_format = {
    "type": "json",
    "schema": {
        "type": "object",
        "properties": {
            "people": {
                "type": "array",
                "items": {
                    "type": "object",
                    "properties": {
                        "name": {"type": "string"},
                        "age": {"type": "number"},
                    },
                    "required": ["name", "age"],
                },
            }
        },
        "required": ["people"],
    },
}
prompt = [{
    "role": "user",
    "content": "Please prepare me a data set of 5 ppl and their age",
}]

options = CompleteOptions(
        max_tokens=4096,
        temperature=0.7,
        top_p=1,
        guardrails=False,
        response_format=response_format
    )


result = complete(
model="claude-sonnet-4-6",
prompt=prompt,
session={session_object}, # session created via connector
stream=True,
options=options,
)

output = "".join(result)
print(output)

응답:

{"people": [{"name":"John Smith","age":32},{"name":"Sarah Johnson","age":28},
{"name":"Michael Chen","age":45},{"name":"Emily Davis","age":19},{"name":"Robert Wilson","age":56}]}

Pydantic 예제

Pydantic은 Python용 데이터 검증 및 설정 관리 라이브러리예요. 이 예제는 응답 형식의 스키마를 정의하기 위해 Pydantic을 사용해요. 코드는 다음 단계를 수행해요.

  • Pydantic으로 스키마를 정의
  • model_json_schema 메서드로 Pydantic 모델을 JSON 스키마로 변환
  • JSON 스키마를 response_format 인자로 complete 함수에 전달

참고: 이 예제는 Snowflake에 이미 연결되어 있는 Snowsight Python 워크시트에서 실행하도록 만들어졌어요. 다른 환경에서 실행하려면 Snowflake Connector for Python으로 Snowflake에 연결을 설정해야 할 수 있어요.

from pydantic import BaseModel, Field
import json
from snowflake.cortex import complete, CompleteOptions
from snowflake.snowpark.context import get_active_session

class Person(BaseModel):
    age: int = Field(description="Person age")
    name: str = Field(description="Person name")

class People(BaseModel):
    people: list[Person] = Field(description="People list")

ppl = People.model_json_schema()
'''
This is the ppl object, keep in mind there's a '$defs' key used

{'$defs': {'Person': {'properties': {'age': {'description': 'Person age', 'title': 'Age', 'type': 'integer'}, 'name': {'description': 'Person name', 'title': 'Name', 'type': 'string'}}, 'required': ['age', 'name'], 'title': 'Person', 'type': 'object'}}, 'properties': {'people': {'description': 'People list', 'items': {'$ref': '#/$defs/Person'}, 'title': 'People', 'type': 'array'}}, 'required': ['people'], 'title': 'People', 'type': 'object'}

'''

response_format_pydantic={
    "type": "json",
    "schema": ppl,
}
prompt=[{"role": "user", "content": "Please prepare me a data set of 5 ppl and their age"}]
options_pydantic = CompleteOptions(  # random params
        max_tokens=4096,
        temperature=0.7,
        top_p=1,
        guardrails=False,
        response_format=response_format_pydantic
    )
model_name = "claude-sonnet-4-6"


session = get_active_session()
try:
    result_pydantic = complete(
        model=model_name,
        prompt=prompt,
        session=session,
        stream=True,
        options=options_pydantic,
    )
except Exception as err:
    result_pydantic = (chunk for chunk in err.response.text) # making sure it's generator, similar to the valid response

output_pydantic = "".join(result_pydantic)
print(output_pydantic)

응답:

{"people": [{"name":"John Smith","age":32},{"name":"Sarah Johnson","age":45},
{"name":"Mike Chen","age":28},{"name":"Emma Wilson","age":19},{"name":"Robert Brown","age":56}]}

REST API 예제

Snowflake Cortex LLM REST API로 원하는 LLM을 사용해 COMPLETE를 호출할 수 있어요. 아래는 Cortex LLM REST API에 스키마를 제공하는 예제예요:

curl --location --request POST 'https://<account_identifier>.snowflakecomputing.com/api/v2/cortex/inference:complete'
--header 'Authorization: Bearer ***' \
--header 'Accept: application/json, text/event-stream' \
--header 'Content-Type: application/json' \
--data-raw '{
    "model": "claude-sonnet-4-6",
    "messages": [{
        "role": "user",
        "content": "Order a pizza for a hungry space traveler heading to the planet Zorgon. Make sure to include a special instruction to avoid any intergalactic allergens."
    }],
    "max_tokens": 1000,
    "response_format": {
            "type": "json",
            "schema":
            {
                "type": "object",
                "properties":
                {
                    "crust":
                    {
                        "type": "string",
                        "enum":
                        [
                            "thin",
                            "thick",
                            "gluten-free",
                            "Rigellian fungus-based"
                        ]
                    },
                    "toppings":
                    {
                        "type": "array",
                        "items":
                        {
                            "type": "string",
                            "enum":
                            [
                                "Gnorchian sausage",
                                "Andromedian mushrooms",
                                "Quasar cheese"
                            ]
                        }
                    },
                    "delivery_planet":
                    {
                        "type": "string"
                    },
                    "special_instructions":
                    {
                        "type": "string"
                    }
                },
                "required":
                [
                    "crust",
                    "toppings",
                    "delivery_planet"
                ]
            }
        }
    }'

응답:

data: {"id":"4d62e41a-d2d7-4568-871a-48de1463ed2a","model":"claude-sonnet-4-6","choices":[{"delta":{"content":"{\"crust\":","content_list":[{"type":"text","text":"{\"crust\":"}]}}],"usage":{}}

data: {"id":"4d62e41a-d2d7-4568-871a-48de1463ed2a","model":"claude-sonnet-4-6","choices":[{"delta":{"content":" \"thin\"","content_list":[{"type":"text","text":" \"thin\""}]}}],"usage":{}}

data: {"id":"4d62e41a-d2d7-4568-871a-48de1463ed2a","model":"claude-sonnet-4-6","choices":[{"delta":{"content":", \"topping","content_list":[{"type":"text","text":", \"topping"}]}}],"usage":{}}

data: {"id":"4d62e41a-d2d7-4568-871a-48de1463ed2a","model":"claude-sonnet-4-6","choices":[{"delta":{"content":"s\": [\"Quasar","content_list":[{"type":"text","text":"s\": [\"Quasar"}]}}],"usage":{}}

JSON 스키마 정의 만들기

COMPLETE Structured Outputs에서 최상의 정확도를 얻으려면 다음 지침을 따르세요.

스키마에서 "required" 필드를 사용해 필수 필드를 지정하세요. 필수 필드를 추출할 수 없으면 COMPLETE는 오류를 발생시켜요.

다음 예제에서 스키마는 COMPLETE가 문서에서 언급된 사람들을 찾도록 지시해요. 사람들이 식별되도록 people 필드는 required로 표시돼요.

{
 'type': 'object',
 'properties': {
     'dataset_name': {
         'type': 'string'
     },
     'created_at': {
         'type': 'string'
     },
     'people': {
         'type': 'array',
         'items': {
             'type': 'object',
             'properties': {
                 'name': {
                     'type': 'string'
                 },
                 'age': {
                     'type': 'number'
                 },
                 'isAdult': {
                     'type': 'boolean'
                 }
             }
         }
     }
 },
 'required': [
     'dataset_name',
     'created_at',
     'people'
 ]
}

응답:

{
 "dataset_name": "name",
 "created_at": "date",
 "people": [
     {
         "name": "Andrew",
         "isAdult": true
     }
 ]
}

추출할 필드의 상세한 설명을 제공해 모델이 더 정확하게 식별하게 하세요. 예를 들어 다음 스키마는 people의 각 필드(name, age, isAdult)에 대한 설명을 포함해요.

{
 'type': 'object',
 'properties': {
     'dataset_name': {
         'type': 'string'
     },
     'created_at': {
         'type': 'string'
     },
     'people': {
         'type': 'array',
         'items': {
             'type': 'object',
             'properties': {
                 'name': {
                     'type': 'string',
                     'description': 'name should be between 9 to 10 characters'
                 },
                 'age': {
                     'type': 'number',
                     'description': 'Should be a value between 0 and 200'
                 },
                 'isAdult': {
                     'type': 'boolean',
                     'description': 'Persons is older than 18'
                 }
             }
         }
     }
 }
}

JSON 참조 사용

스키마 참조는 Cortex COMPLETE Structured Outputs를 사용할 때 실질적인 문제를 해결해요. $ref로 표현되는 참조로 주소나 가격 같은 공통 객체를 한 번 정의한 뒤 스키마 전체에서 재사용할 수 있어요. 이 방식으로 검증 로직을 갱신하거나 필드를 추가해야 할 때 여러 위치가 아니라 한 곳에서 변경할 수 있어요.

참조를 사용하면 코딩 노력이 줄고 불일치 구현으로 인한 버그가 줄며 코드 리뷰가 단순해져요. 참조된 컴포넌트는 데이터 모델의 엔티티 관계를 더 잘 나타내는 더 깔끔한 계층 구조를 만들어요. 프로젝트가 복잡해질수록 이 모듈식 접근 방식은 스키마 무결성을 유지하면서 기술 부채를 관리하는 데 도움이 돼요.

Pydantic 같은 서드파티 라이브러리는 Python에서 참조 메커니즘을 natively 지원해 코드에서 스키마 사용을 단순화해요.

JSON 스키마에서 참조 사용에는 다음 지침이 적용돼요.

  • 범위 제한: $ref 메커니즘은 사용자 스키마 내로만 제한돼요. 외부 스키마 참조(HTTP URL 같은)는 지원되지 않아요.
  • 정의 배치: 객체 정의는 스키마 최상위, 특히 definitions 또는 $defs 키 아래에 배치해야 해요.
  • 강제: JSON Schema 사양은 정의에 $defs 키 사용을 권장하지만 Snowflake의 검증 메커니즘은 이 구조를 엄격히 강제해요. 다음은 유효한 $defs 객체의 예예요.
{
    '$defs': {
        'person':{'type':'object','properties':{'name' : {'type' : 'string'},'age': {'type':'number'}}, 'required':['name','age']}},
    'type': 'object',
    'properties': {'title':{'type':'string'},'people':{'type':'array','items':{'$ref':'#/$defs/person'}}}
}
JSON 참조 예제

이 SQL 예제는 JSON 스키마에서 참조 사용을 보여줘요.

select ai_complete(
    model => 'claude-sonnet-4-6',
    prompt => 'Extract structured data from this customer interaction note: Customer Sarah Jones complained about the mobile app crashing during checkout. She tried to purchase 3 items: a red XL jacket ($89.99), blue running shoes ($129.50), and a fitness tracker ($199.00). The app crashed after she entered her shipping address at 123 Main St, Portland OR, 97201. She has been a premium member since January 2024.',
    'response_format' => {
            'type': 'json',
            'schema': {
'type': 'object',
'$defs': {
    'price': {
        'type': 'object',
        'properties': {
            'amount': {'type': 'number'},
            'currency': {'type': 'string'}
        },
        'required': ['amount']
    },
    'address': {
        'type': 'object',
        'properties': {
            'street': {'type': 'string'},
            'city': {'type': 'string'},
            'state': {'type': 'string'},
            'zip': {'type': 'string'},
            'country': {'type': 'string'}
        },
        'required': ['street', 'city', 'state']
    },
    'product': {
        'type': 'object',
        'properties': {
            'name': {'type': 'string'},
            'category': {'type': 'string'},
            'color': {'type': 'string'},
            'size': {'type': 'string'},
            'price': {'$ref': '#/$defs/price'}
        },
        'required': ['name', 'price']
    }
},
'properties': {
    'customer': {
        'type': 'object',
        'properties': {
            'name': {'type': 'string'},
            'membership': {
                'type': 'object',
                'properties': {
                    'type': {'type': 'string'},
                    'since': {'type': 'string'}
                }
            },
            'shipping_address': {'$ref': '#/$defs/address'}
        },
        'required': ['name']
    },
    'issue': {
        'type': 'object',
        'properties': {
            'type': {'type': 'string'},
            'platform': {'type': 'string'},
            'stage': {'type': 'string'},
            'severity': {'type': 'string', 'enum': ['low', 'medium', 'high', 'critical']}
        },
        'required': ['type', 'platform']
    },
    'cart': {
        'type': 'object',
        'properties': {
            'items': {
                'type': 'array',
                'items': {'$ref': '#/$defs/product'}
            },
            'total': {'$ref': '#/$defs/price'},
            'item_count': {'type': 'integer'}
        }
    },
    'recommended_actions': {
        'type': 'array',
        'items': {
            'type': 'object',
            'properties': {
                'department': {'type': 'string'},
                'action': {'type': 'string'},
                'priority': {'type': 'string', 'enum': ['low', 'medium', 'high', 'urgent']}
            }
        }
    }
},
'required': ['customer', 'issue','cart']
}
        }
    }
);

응답:

{
  "created": 1747313083,
  "model": "claude-sonnet-4-6",
  "structured_output": [
    {
      "raw_message": {
        "cart": {
          "item_count": 3,
          "items": [
            {
              "color": "red",
              "name": "jacket",
              "price": {
                "amount": 89.99,
                "currency": "USD"
              },
              "size": "XL"
            },
            {
              "color": "blue",
              "name": "running shoes",
              "price": {
                "amount": 129.5,
                "currency": "USD"
              }
            },
            {
              "name": "fitness tracker",
              "price": {
                "amount": 199,
                "currency": "USD"
              }
            }
          ],
          "total": {
            "amount": 418.49,
            "currency": "USD"
          }
        },
        "customer": {
          "membership": {
            "since": "2024-01",
            "type": "premium"
          },
          "name": "Sarah Jones",
          "shipping_address": {
            "city": "Portland",
            "state": "OR",
            "street": "123 Main St",
            "zip": "97201"
          }
        },
        "issue": {
          "platform": "mobile",
          "severity": "high",
          "stage": "checkout",
          "type": "app_crash"
        }
      },
      "type": "json"
    }
  ],
  "usage": {
    "completion_tokens": 57,
    "prompt_tokens": 945,
    "total_tokens": 1002
  }
}

JSON 준수 정확도 최적화 (Optimizing JSON adherence accuracy)

COMPLETE Structured Outputs는 보통 프롬프트를 요구하지 않아요. 응답이 지정한 스키마를 따라야 한다는 것을 이미 이해하고 있어요. 그러나 작업 복잡성은 LLM이 JSON 응답 형식을 따르는 능력에 크게 영향을 줄 수 있어요. 작업이 복잡할수록 프롬프트를 지정해 결과 정확도를 개선할 수 있어요.

  • 텍스트 분류, 엔티티 추출, 의역, 요약 같은 간단한 작업은 복잡한 추론을 요구하지 않으므로 일반적으로 추가 프롬프트를 필요로 하지 않아요. 지능이 낮은 더 작은 모델의 경우 Structured Outputs를 사용하는 것만으로도 JSON 준수 정확도를 크게 개선하는데, 모델이 제공한 스키마와 무관한 텍스트를 무시하기 때문이에요.
  • 중간 복잡도 작업에는 분류 결정에 대한 근거 제공 같은 추가 추론을 모델이 요구받는 간단한 작업이 포함돼요. 이런 사용 사례에는 성능 최적화를 위해 프롬프트에 "Respond in JSON"을 추가할 것을 권장해요.
  • 복잡한 추론 작업은 모델이 더 개방형이고 모호한 작업을 수행하도록 유도해요. 예를 들어 답변의 관련성, 전문성, 충실성에 기반해 통화 품질을 평가하고 채점하는 것 같은 작업이에요. 이런 사용 사례에는 Anthropic의 claude-sonnet-4-6이나 Mistral AI의 mistral-large2 같은 가장 강력한 모델을 사용하고, 프롬프트에 "Respond in JSON"과 생성할 스키마에 대한 세부 사항을 추가할 것을 권장해요.

작업이나 모델에 관계없이 COMPLETE를 호출할 때 가장 일관된 결과를 위해 temperature 옵션을 0으로 설정하세요.

팁: 모델이 발생시킬 수 있는 오류를 처리하려면 COMPLETE보다 TRY_COMPLETE를 사용하세요.

비용 고려사항 (Cost considerations)

Cortex COMPLETE Structured Outputs는 처리된 토큰 수에 따라 컴퓨팅 비용이 발생하며, 각 토큰을 제공된 JSON 스키마에 대해 검증하는 오버헤드에 대해서는 추가 컴퓨팅 비용이 발생하지 않아요. 그러나 처리되고(청구되는) 토큰 수는 스키마 복잡성에 따라 증가해요. 일반적으로 제공된 스키마가 더 크고 복잡할수록 더 많은 입력·출력 토큰이 소비돼요. 깊은 중첩(예: 계층적 데이터)이 있는 고도로 구조화된 응답은 더 간단한 스키마보다 더 많은 토큰을 소비해요.

제한 사항

  • 스키마 키에 공백을 사용할 수 없어요.
  • 속성 이름에 허용되는 문자는 문자, 숫자, 하이픈, 밑줄이에요. 이름은 최대 64자예요.
  • $ref 또는 $dynamicRef로 외부 스키마를 참조할 수 없어요.

다음 제약 키워드는 지원되지 않아요. 지원되지 않는 제약 키워드를 사용하면 오류가 발생해요.

타입 키워드
integer multipleOf
number multipleOf, minimum, maximum, exclusiveMinimum, exclusiveMaximum
string minLength, maxLength, format
array uniqueItems, contains, minContains, maxContains, minItems, maxItems
object patternProperties, minProperties, maxProperties, propertyNames

이 제한 사항은 향후 릴리스에서 해결될 수 있어요.

오류 조건 (Error conditions)

상황 예시 메시지 HTTP 상태 코드
요청 검증 실패. 모델이 유효한 응답을 생성할 수 없을 것이라 쿼리가 취소됨. 잘못된 요청으로 발생할 수 있음. please provide a type for the response format object, please provide a schema for the response format object 400
입력 스키마 검증 실패. 요청 페이로드에 필수 속성이 없거나, 제약 조건 같은 지원되지 않는 json schema 기능을 사용하거나, $ref 메커니즘의 부적절한 사용(예: 스키마 밖 참조)으로 발생할 수 있음. input schema validation error: . 이유 예: /properties/city additional properties are not allowed; /properties/arrondissement regexp pattern ^[a-zA-Z0-9_-]{1,64}$ mismatch on string; /properties/province/type sting should be one of ["object", "array", "string", "number", "integer", "boolean", "null"]; Invalid ref #/http://example.com/custom-email-validator.json#. Please define a valid object in #/$defs/ section 400
모델 출력 검증 실패. 모델이 스키마와 일치하는 응답을 생성할 수 없음. json mode output validation error: . 이유 예: An error occurred while unmarshalling the model output. Model returned invalid JSON that cannot be parsed due to: unexpected end of JSON input 422

더 알아보기 (Learn more)