구조화된 출력

제공된 JSON 스키마를 준수하는 대답을 생성하도록 Gemini 모델을 구성할 수 있습니다. 이렇게 하면 예측 가능하고 유형이 안전한 결과를 얻을 수 있으며 구조화되지 않은 텍스트에서 구조화된 데이터를 추출하는 작업이 간소화됩니다.

구조화된 출력을 사용하는 것이 적합한 경우는 다음과 같습니다.

  • 데이터 추출: 텍스트에서 이름, 날짜와 같은 특정 정보를 추출합니다.
  • 구조화된 분류: 텍스트를 사전 정의된 카테고리로 분류합니다.
  • 에이전트 워크플로: 도구 또는 API를 위한 구조화된 입력을 생성합니다.

REST API에서 JSON 스키마를 지원하는 것 외에도 Google 생성형 AI SDK를 사용하면 Pydantic (Python) 및 Zod (JavaScript)를 사용하여 스키마를 정의할 수 있습니다.

이 예에서는 object, array, string, integer과 같은 기본 JSON 스키마 유형을 사용하여 텍스트에서 구조화된 데이터를 추출하는 방법을 보여줍니다.

Python

# This will only work for SDK newer than 2.0.0
from google import genai
from pydantic import BaseModel, Field
from typing import List, Optional

class Ingredient(BaseModel):
    name: str = Field(description="Name of the ingredient.")
    quantity: str = Field(description="Quantity of the ingredient, including units.")

class Recipe(BaseModel):
    recipe_name: str = Field(description="The name of the recipe.")
    prep_time_minutes: Optional[int] = Field(description="Optional time in minutes to prepare the recipe.")
    ingredients: List[Ingredient]
    instructions: List[str]

client = genai.Client()

prompt = """
Please extract the recipe from the following text.
The user wants to make delicious chocolate chip cookies.
They need 2 and 1/4 cups of all-purpose flour, 1 teaspoon of baking soda,
1 teaspoon of salt, 1 cup of unsalted butter (softened), 3/4 cup of granulated sugar,
3/4 cup of packed brown sugar, 1 teaspoon of vanilla extract, and 2 large eggs.
For the best part, they'll need 2 cups of semisweet chocolate chips.
First, preheat the oven to 375°F (190°C). Then, in a small bowl, whisk together the flour,
baking soda, and salt. In a large bowl, cream together the butter, granulated sugar, and brown sugar
until light and fluffy. Beat in the vanilla and eggs, one at a time. Gradually beat in the dry
ingredients until just combined. Finally, stir in the chocolate chips. Drop by rounded tablespoons
onto ungreased baking sheets and bake for 9 to 11 minutes.
"""

interaction = client.interactions.create(
    model="gemini-3-flash-preview",
    input=prompt,
    response_format={
        "type": "text",
        "mime_type": "application/json",
        "schema": Recipe.model_json_schema()
    },
)

recipe = Recipe.model_validate_json(interaction.steps[-1].content[0].text)
print(recipe)

자바스크립트

// This will only work for SDK newer than 2.0.0
import { GoogleGenAI } from "@google/genai";
import * as z from "zod";

const recipeJsonSchema = {
  type: "object",
  properties: {
    recipe_name: {
      type: "string",
      description: "The name of the recipe."
    },
    prep_time_minutes: {
        type: "integer",
        description: "Optional time in minutes to prepare the recipe."
    },
    ingredients: {
      type: "array",
      items: {
        type: "object",
        properties: {
          name: { type: "string", description: "Name of the ingredient."},
          quantity: { type: "string", description: "Quantity of the ingredient, including units."}
        },
        required: ["name", "quantity"]
      }
    },
    instructions: {
      type: "array",
      items: { type: "string" }
    }
  },
  required: ["recipe_name", "ingredients", "instructions"]
};

const recipeSchema = z.fromJSONSchema(recipeJsonSchema);

const client = new GoogleGenAI({});

const prompt = `
Please extract the recipe from the following text.
The user wants to make delicious chocolate chip cookies.
They need 2 and 1/4 cups of all-purpose flour, 1 teaspoon of baking soda,
1 teaspoon of salt, 1 cup of unsalted butter (softened), 3/4 cup of granulated sugar,
3/4 cup of packed brown sugar, 1 teaspoon of vanilla extract, and 2 large eggs.
For the best part, they'll need 2 cups of semisweet chocolate chips.
First, preheat the oven to 375°F (190°C). Then, in a small bowl, whisk together the flour,
baking soda, and salt. In a large bowl, cream together the butter, granulated sugar, and brown sugar
until light and fluffy. Beat in the vanilla and eggs, one at a time. Gradually beat in the dry
ingredients until just combined. Finally, stir in the chocolate chips. Drop by rounded tablespoons
onto ungreased baking sheets and bake for 9 to 11 minutes.
`;

const interaction = await client.interactions.create({
  model: "gemini-3-flash-preview",
  input: prompt,
  response_format: {
    type: 'text',
    mime_type: 'application/json',
    schema: recipeJsonSchema
  },
});

const recipe = recipeSchema.parse(JSON.parse(interaction.steps.at(-1).content[0].text));
console.log(recipe);

REST

# Specifies the API revision to avoid breaking changes when they become default
curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
    -H "x-goog-api-key: $GEMINI_API_KEY" \
    -H 'Content-Type: application/json' \
    -H "Api-Revision: 2026-05-20" \
    -d '{
      "model": "gemini-3-flash-preview",
      "input": "Please extract the recipe from the following text.\nThe user wants to make delicious chocolate chip cookies.\nThey need 2 and 1/4 cups of all-purpose flour, 1 teaspoon of baking soda,\n1 teaspoon of salt, 1 cup of unsalted butter (softened), 3/4 cup of granulated sugar,\n3/4 cup of packed brown sugar, 1 teaspoon of vanilla extract, and 2 large eggs.\nFor the best part, they will need 2 cups of semisweet chocolate chips.\nFirst, preheat the oven to 375°F (190°C). Then, in a small bowl, whisk together the flour,\nbaking soda, and salt. In a large bowl, cream together the butter, granulated sugar, and brown sugar\nuntil light and fluffy. Beat in the vanilla and eggs, one at a time. Gradually beat in the dry\ningredients until just combined. Finally, stir in the chocolate chips. Drop by rounded tablespoons\nonto ungreased baking sheets and bake for 9 to 11 minutes.",
      "response_format": {
        "type": "text",
        "mime_type": "application/json",
        "schema": {
          "type": "object",
          "properties": {
            "recipe_name": {
              "type": "string",
              "description": "The name of the recipe."
            },
            "prep_time_minutes": {
                "type": "integer",
                "description": "Optional time in minutes to prepare the recipe."
            },
            "ingredients": {
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "name": { "type": "string", "description": "Name of the ingredient."},
                  "quantity": { "type": "string", "description": "Quantity of the ingredient, including units."}
                },
                "required": ["name", "quantity"]
              }
            },
            "instructions": {
              "type": "array",
              "items": { "type": "string" }
            }
          },
          "required": ["recipe_name", "ingredients", "instructions"]
        }
      }
      }
    }'

응답 예시:

{
  "recipe_name": "Delicious Chocolate Chip Cookies",
  "ingredients": [
    { "name": "all-purpose flour", "quantity": "2 and 1/4 cups" },
    { "name": "baking soda", "quantity": "1 teaspoon" },
    { "name": "salt", "quantity": "1 teaspoon" },
    { "name": "unsalted butter (softened)", "quantity": "1 cup" },
    { "name": "granulated sugar", "quantity": "3/4 cup" },
    { "name": "packed brown sugar", "quantity": "3/4 cup" },
    { "name": "vanilla extract", "quantity": "1 teaspoon" },
    { "name": "large eggs", "quantity": "2" },
    { "name": "semisweet chocolate chips", "quantity": "2 cups" }
  ],
  "instructions": [
    "Preheat the oven to 375°F (190°C).",
    "In a small bowl, whisk together the flour, baking soda, and salt.",
    "In a large bowl, cream together the butter, granulated sugar, and brown sugar until light and fluffy.",
    "Beat in the vanilla and eggs, one at a time.",
    "Gradually beat in the dry ingredients until just combined.",
    "Stir in the chocolate chips.",
    "Drop by rounded tablespoons onto ungreased baking sheets and bake for 9 to 11 minutes."
  ]
}

스트리밍 결과

구조화된 출력을 스트리밍하여 대답이 생성되는 대로 처리를 시작할 수 있습니다. 스트리밍된 청크는 연결하여 최종 JSON 객체를 형성할 수 있는 유효한 부분 JSON 문자열입니다.

Python

# This will only work for SDK newer than 2.0.0
from google import genai
from pydantic import BaseModel
from typing import Literal

class Feedback(BaseModel):
    sentiment: Literal["positive", "neutral", "negative"]
    summary: str

client = genai.Client()
prompt = "The new UI is incredibly intuitive. Add a very long summary to test streaming!"

stream = client.interactions.create(
    model="gemini-3-flash-preview",
    input=prompt,
    response_format={
        "type": "text",
        "mime_type": "application/json",
        "schema": Feedback.model_json_schema()
    },
    stream=True
)
for event in stream:
    if event.event_type == "step.delta" and event.delta.text:
        print(event.delta.text, end="")

자바스크립트

// This will only work for SDK newer than 2.0.0
import { GoogleGenAI } from "@google/genai";
import * as z from "zod";

const feedbackJsonSchema = {
  type: "object",
  properties: {
    sentiment: { type: "string", enum: ["positive", "neutral", "negative"] },
    summary: { type: "string" }
  },
  required: ["sentiment", "summary"]
};

const feedbackSchema = z.fromJSONSchema(feedbackJsonSchema);

const client = new GoogleGenAI({});

const stream = await client.interactions.create({
  model: "gemini-3-flash-preview",
  input: "The new UI is incredibly intuitive. Add a very long summary!",
  response_format: {
    type: 'text',
    mime_type: 'application/json',
    schema: feedbackJsonSchema
  },
  stream: true,
});

for await (const event of stream) {
  if (event.type === "step.delta" && event.delta?.text) {
    process.stdout.write(event.delta.text);
  }
}

도구를 사용한 구조화된 출력

Gemini 3를 사용하면 Google 검색을 사용한 그라운딩, URL 컨텍스트, 코드 실행, 파일 검색, 함수 호출을 비롯한 기본 제공 도구와 구조화된 출력을 결합할 수 있습니다.

Python

# This will only work for SDK newer than 2.0.0
from google import genai
from pydantic import BaseModel, Field
from typing import List

class MatchResult(BaseModel):
    winner: str = Field(description="The name of the winner.")
    final_match_score: str = Field(description="The final match score.")
    scorers: List[str] = Field(description="The name of the scorer.")

client = genai.Client()

interaction = client.interactions.create(
    model="gemini-3.1-pro-preview",
    input="Search for all details for the latest Euro.",
    tools=[{"type": "google_search"}, {"type": "url_context"}],
    response_format={
        "type": "text",
        "mime_type": "application/json",
        "schema": MatchResult.model_json_schema()
    },
)

result = MatchResult.model_validate_json(interaction.steps[-1].content[0].text)
print(result)

자바스크립트

// This will only work for SDK newer than 2.0.0
import { GoogleGenAI } from "@google/genai";
import * as z from "zod";

const matchJsonSchema = {
  type: "object",
  properties: {
    winner: { type: "string" },
    final_match_score: { type: "string" },
    scorers: { type: "array", items: { type: "string" } }
  },
  required: ["winner", "final_match_score", "scorers"]
};

const matchSchema = z.fromJSONSchema(matchJsonSchema);

const client = new GoogleGenAI({});

const interaction = await client.interactions.create({
  model: "gemini-3.1-pro-preview",
  input: "Search for all details for the latest Euro.",
  tools: [{type: "google_search"}, {type: "url_context"}],
  response_format: {
    type: 'text',
    mime_type: 'application/json',
    schema: matchJsonSchema
  },
});

const match = matchSchema.parse(JSON.parse(interaction.steps.at(-1).content[0].text));
console.log(match);

REST

# Specifies the API revision to avoid breaking changes when they become default
curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
  -H "x-goog-api-key: $GEMINI_API_KEY" \
  -H 'Content-Type: application/json' \
  -H "Api-Revision: 2026-05-20" \
  -d '{
    "model": "gemini-3.1-pro-preview",
    "input": "Search for all details for the latest Euro.",
    "tools": [{"type": "google_search"}, {"type": "url_context"}],
    "response_format": {
      "type": "text",
      "mime_type": "application/json",
      "schema": {
        "type": "object",
        "properties": {
            "winner": {"type": "string"},
            "final_match_score": {"type": "string"},
            "scorers": {"type": "array", "items": {"type": "string"}}
        },
        "required": ["winner", "final_match_score", "scorers"]
      }
    }
  }'

JSON 스키마 지원

JSON 객체를 생성하려면 text 유형의 객체 (또는 객체가 포함된 배열)로 response_format를 구성하고 mime_typeapplication/json로 설정합니다. 스키마는 schema 필드에 제공해야 합니다.

Gemini의 구조화된 출력 모드는 JSON 스키마 사양의 일부를 지원합니다.

다음 type 값이 지원됩니다.

  • string: 텍스트
  • number: 부동 소수점 숫자의 경우
  • integer: 정수의 경우
  • boolean: true 또는 false 값입니다.
  • object: 키-값 쌍이 있는 구조화된 데이터에 사용됩니다.
  • array: 항목 목록의 경우
  • null: 속성이 null이 되도록 허용하려면 유형 배열에 "null"를 포함합니다 (예: {"type": ["string", "null"]}).

이러한 설명 속성은 모델을 안내하는 데 도움이 됩니다.

  • title: 속성에 대한 간단한 설명입니다.
  • description: 속성에 대한 더 길고 자세한 설명입니다.

유형별 속성

object 값:

  • properties: 각 키가 속성 이름이고 각 값이 해당 속성의 스키마인 객체입니다.
  • required: 필수 속성을 나열하는 문자열 배열입니다.
  • additionalProperties: properties에 나열되지 않은 속성이 허용되는지 여부를 제어합니다. 불리언 또는 스키마일 수 있습니다.

string 값:

  • enum: 분류 작업에 사용할 수 있는 특정 문자열 집합을 나열합니다.
  • format: 문자열의 구문을 지정합니다(예: date-time, date, time).

numberinteger 값:

  • enum: 가능한 숫자 값의 특정 집합을 나열합니다.
  • minimum: 최소 포함 값입니다.
  • maximum: 최대 포함 값입니다.

array 값:

  • items: 배열의 모든 항목에 대한 스키마를 정의합니다.
  • prefixItems: 튜플과 유사한 구조를 허용하여 처음 N개 항목의 스키마 목록을 정의합니다.
  • minItems: 배열의 최소 항목 수입니다.
  • maxItems: 배열의 최대 항목 수입니다.

구조화된 출력과 함수 호출 비교

기능 기본 사용 사례
구조화된 출력 최종 대답의 형식을 지정합니다. 모델의 답변을 특정 형식으로 표시하고 싶을 때 사용합니다.
함수 호출 대화 중에 조치를 취합니다. 모델이 최종 답변을 제공하기 전에 사용자에게 작업을 수행하도록 요청해야 하는 경우에 사용합니다.

권장사항

  • 명확한 설명: description 필드를 사용하여 모델을 안내합니다.
  • 강한 형식 지정: 특정 유형 (integer, string, enum)을 사용합니다.
  • 프롬프트 엔지니어링: 모델이 수행하기를 원하는 작업을 명확하게 명시합니다.
  • 유효성 검사: 출력은 구문상 올바른 JSON이지만 애플리케이션에서 항상 값을 검증하세요.
  • 오류 처리: 스키마를 준수하지만 의미적으로 잘못된 출력에 대해 강력한 오류 처리를 구현합니다.

제한사항

  • 스키마 하위 집합: 일부 JSON 스키마 기능은 지원되지 않습니다.
  • 스키마 복잡성: 매우 크거나 깊이 중첩된 스키마는 거부될 수 있습니다.