Interactions API: 브레이킹 체인지 이전 가이드 (2026년 5월)

v1beta Interactions API는 비행 중 조향, 비동기 도구 호출과 같은 향후 기능을 지원하기 위해 API 모양을 재구성하는 브레이킹 체인지를 도입합니다. 이 페이지에서는 변경사항을 설명하고 마이그레이션에 도움이 되는 변경 전후 코드 예시를 제공합니다. 변경사항에는 두 가지 카테고리가 있습니다.

  1. 단계 스키마: 새로운 steps 배열이 outputs 배열을 대체하여 각 상호작용 턴의 구조화된 타임라인을 제공합니다.
  2. 출력 형식 구성: 새로운 다형성 response_format이 모든 출력 형식 컨트롤을 통합하고 response_mime_type을 삭제합니다.

새 스키마로 이전하는 방법의 단계에 따라 통합을 업데이트하세요.

핵심 변경사항: outputs에서 steps(으)로

새 스키마는 outputs 배열을 steps 배열로 대체합니다.

  • 기존: 대답은 모델의 생성된 콘텐츠만 포함하는 플랫 outputs 배열을 반환했습니다.
  • 새 스키마: 응답은 에코된 사용자 입력과 모델 출력을 모두 포함하는 steps 배열을 반환하여 상호작용 턴의 전체 타임라인을 제공합니다.

단항 (비스트리밍) 응답은 steps 배열의 첫 번째 단계로 입력을 다시 에코합니다. 스트리밍 응답은 입력 단계를 건너뛰고 생성된 콘텐츠 델타만 내보냅니다.

기본 입력/출력 (단항)

이전 (기존)

Python

# Request
interaction = client.interactions.create(
    model="gemini-3-flash-preview", input="Tell me a joke."
)

# Response access
print(interaction.outputs[0].text)

자바스크립트

// Request
const interaction = await client.interactions.create({
    model: 'gemini-3-flash-preview',
    input: 'Tell me a joke.'
});

// Response access
console.log(interaction.outputs[0].text);

REST

// Request: POST /v1beta/interactions
{
  "model": "gemini-3-flash-preview",
  "input": "Tell me a joke."
}

// Response
{
  "id": "int_123",
  "role": "model",
  "outputs": [
    {
      "type": "text",
      "text": "Why did the chicken cross the road?"
    }
  ]
}

After (새 스키마)

Python

# Request
interaction = client.interactions.create(
    model="gemini-3-flash-preview", input="Tell me a joke."
)

# Response access
print(interaction.steps[-1].content[0].text)  # CHANGED: steps instead of outputs

자바스크립트

// Request
const interaction = await client.interactions.create({
    model: 'gemini-3-flash-preview',
    input: 'Tell me a joke.'
});

// Response access
console.log(interaction.steps.at(-1).content[0].text);

REST

// Request: POST /v1beta/interactions
{
  "model": "gemini-3-flash-preview",
  "input": "Tell me a joke."
}

// Response
{
  "id": "int_123",
  "steps": [
    {
      "type": "user_input",
      "status": "done",
      "content": [
        {
          "type": "text",
          "text": "Tell me a joke."
        }
      ]
    },
    {
      "type": "model_output",
      "status": "done",
      "content": [
        {
          "type": "text",
          "text": "Why did the chicken cross the road?"
        }
      ]
    }
  ]
}

함수 호출

요청 구조는 변경되지 않지만 대답에서는 플랫 outputs 콘텐츠가 구조화된 단계로 대체됩니다.

이전 (기존)

Python

# Accessing function call in legacy schema
for output in interaction.outputs:
    if output.type == "function_call":
        print(f"Calling {output.name} with {output.arguments}")

자바스크립트

// Accessing function call in legacy schema
for (const output of interaction.outputs) {
    if (output.type === 'function_call') {
        console.log(`Calling {output.name} with {JSON.stringify(output.arguments)}`);
    }
}

REST

// Response
{
  "id": "int_001",
  "role": "model",
  "status": "requires_action",
  "outputs": [
    {
      "type": "thought",
      "signature": "abc123..."
    },
    {
      "type": "function_call",
      "id": "fc_1",
      "name": "get_weather",
      "arguments": { "location": "Boston, MA" }
    }
  ]
}

After (새 스키마)

Python

# Accessing function call in new steps schema
for step in interaction.steps:
    if step.type == "function_call":
        print(f"Calling {step.name} with {step.arguments}")

자바스크립트

// Accessing function call in new steps schema
for (const step of interaction.steps) {
    if (step.type === 'function_call') {
        console.log(`Calling {step.name} with {JSON.stringify(step.arguments)}`);
    }
}

REST

// Response
{
  "id": "int_001",
  "status": "requires_action",
  "steps": [
    {
      "type": "user_input",
      "status": "done",
      "content": [
        { "type": "text", "text": "What's the weather in Boston?" }
      ]
    },
    {
      "type": "thought",
      "status": "done",
      "signature": "abc123..."
    },
    {
      "type": "function_call",
      "status": "waiting",
      "id": "fc_1",
      "name": "get_weather",
      "arguments": { "location": "Boston, MA" }
    }
  ]
}

서버 측 도구

이제 서버 측 도구 (예: Google 검색 또는 코드 실행)가 steps 배열에서 특정 단계 유형을 생성합니다. 기존 스키마는 이러한 작업을 outputs 배열 내의 특정 콘텐츠 유형으로 반환했지만 새 스키마는 이를 steps 배열로 이동합니다. 다음 예에서는 Google 검색을 사용합니다.

이전 (기존)

Python

# Accessing search results in legacy schema
for output in interaction.outputs:
    if output.type == "google_search_call":
        print(f"Searched for: {output.arguments.queries}")
    elif output.type == "google_search_result":
        print(f"Found results: {output.result.rendered_content}")

자바스크립트

// Accessing search results in legacy schema
for (const output of interaction.outputs) {
    if (output.type === 'google_search_call') {
        console.log(`Searched for: {output.arguments.queries}`);
    } else if (output.type === 'google_search_result') {
        console.log(`Found results: {output.result.renderedContent}`);
    }
}

REST

// Request: POST /v1beta/interactions
{
  "model": "gemini-3-flash-preview",
  "input": "Who won the last Super Bowl?",
  "tools": [
    { "type": "google_search" }
  ]
}

// Response
{
  "id": "int_456",
  "outputs": [
    {
      "type": "google_search_call",
      "id": "gs_1",
      "arguments": { "queries": ["last Super Bowl winner"] }
    },
    {
      "type": "google_search_result",
      "call_id": "gs_1",
      "result": {
        "rendered_content": "<div>...</div>",
        "url": "https://www.nfl.com/super-bowl"
      }
    },
    {
      "type": "text",
      "text": "The Kansas City Chiefs won the last Super Bowl.",
      "annotations": [
        {
          "start_index": 4,
          "end_index": 22,
          "source": "https://www.nfl.com/super-bowl"
        }
      ]
    }
  ],
  "status": "completed"
}

After (새 스키마)

Python

# Accessing search results in new steps schema
for step in interaction.steps:
    if step.type == "google_search_call":
        print(f"Searched for: {step.arguments.queries}")
    elif step.type == "google_search_result":
        print(f"Found results: {step.result.search_suggestions}")

자바스크립트

// Accessing search results in new steps schema
for (const step of interaction.steps) {
    if (step.type === 'google_search_call') {
        console.log(`Searched for: {step.arguments.queries}`);
    } else if (step.type === 'google_search_result') {
        console.log(`Found results: {step.result.searchSuggestions}`);
    }
}

REST

// Request: POST /v1beta/interactions
{
  "model": "gemini-3-flash-preview",
  "input": "Who won the last Super Bowl?",
  "tools": [
    { "type": "google_search" }
  ]
}

// Response
{
  "id": "int_456",
  "steps": [
    {
      "type": "user_input",
      "status": "done",
      "content": [
        { "type": "text", "text": "Who won the last Super Bowl?" }
      ]
    },
    {
      "type": "google_search_call",
      "status": "done",
      "id": "gs_1",
      "arguments": { "queries": ["last Super Bowl winner"] },
      "signature": "abc123..."
    },
    {
      "type": "google_search_result",
      "status": "done",
      "call_id": "gs_1",
      "result": {
        "search_suggestions": "<div>...</div>"
      },
      "signature": "abc123..."
    },
    {
      "type": "model_output",
      "status": "done",
      "content": [
        {
          "type": "text",
          "text": "The Kansas City Chiefs won the last Super Bowl.",
          "annotations": [
            {
              "type": "url_citation",
              "url": "https://www.nfl.com/super-bowl",
              "title": "NFL.com",
              "start_index": 4,
              "end_index": 22
            }
          ]
        }
      ]
    }
  ],
  "status": "completed"
}

스트리밍

스트리밍은 다음과 같은 새로운 이벤트 유형을 노출합니다.

새 이벤트 유형

  • interaction.created
  • interaction.status_update: 이제 완료 및 오류를 포함한 모든 수명 주기 상태를 다룹니다 (아래 상태 참고).
  • step.start
  • step.delta
  • step.stop
interaction.status_update 상태
  • in_progress
  • active
  • completed
  • interrupted
  • requires_action
  • error

지원 중단된 이벤트 유형

다음 기존 이벤트 유형은 위에 나열된 새 이벤트로 대체됩니다.

  • interaction.startinteraction.created
  • content.startstep.start
  • content.deltastep.delta
  • content.stopstep.stop
  • interaction.completeinteraction.status_update(status: "completed" 포함)
  • errorinteraction.status_update(status: "error" 포함)
  • interaction.status_updateinteraction.status_update (변경되지 않았지만 이제 추가 상태를 포함함)

스트리밍 함수 호출: 함수 호출과 함께 스트리밍을 사용하면 step.start 이벤트가 함수 이름을 전달하고 step.delta 이벤트가 인수를 부분 JSON 문자열로 스트리밍합니다 (arguments_delta 사용). 이러한 델타를 누적하여 전체 인수를 가져와야 합니다. 한 번에 전체 함수 호출 객체를 수신하는 단항 호출과는 다릅니다.

이전 (기존)

Python

# Legacy streaming used content.delta
stream = client.interactions.create(
    model="gemini-3-flash-preview",
    input="Explain quantum entanglement in simple terms.",
    stream=True,
)

for chunk in stream:
    if chunk.event_type == "content.delta":
        if chunk.delta.type == "text":
            print(chunk.delta.text, end="", flush=True)

자바스크립트

// Legacy streaming used content.delta
const stream = await client.interactions.create({
    model: 'gemini-3-flash-preview',
    input: 'Explain quantum entanglement in simple terms.',
    stream: true,
});

for await (const chunk of stream) {
    if (chunk.event_type === 'content.delta') {
        if (chunk.delta.type === 'text') {
            process.stdout.write(chunk.delta.text);
        }
    }
}

REST

// Request: POST /v1beta/interactions
{
  "model": "gemini-3-flash-preview",
  "input": "Explain quantum entanglement in simple terms.",
  "stream": true
}

// Response (SSE Lines)
// event: interaction.start
// data: {"id": "int_123", "status": "in_progress"}
//
// event: content.start
// data: {"index": 0, "type": "text"}
//
// event: content.delta
// data: {"delta": {"type": "text", "text": "Quantum entanglement is..."}}
//
// event: content.stop
// data: {"index": 0}
//
// event: interaction.complete
// data: {"id": "int_123", "status": "done", "usage": {"total_tokens": 42}}
After (새 스키마)

Python

# Consuming stream and handling new event types
for event in client.interactions.create(
    model="gemini-3-flash-preview",
    input="Tell me a story.",
    stream=True,
):
    if event.type == "step.delta":  # CHANGED: step.delta instead of content.delta
        if event.delta.type == "text":
            print(event.delta.text, end="")

자바스크립트

// Consuming stream and handling new event types
const stream = await client.interactions.create({
    model: 'gemini-3-flash-preview',
    input: 'Tell me a story.',
    stream: true,
});

for await (const event of stream) {
    if (event.type === 'step.delta') {  // CHANGED: step.delta instead of content.delta
        if (event.delta.type === 'text') {
            process.stdout.write(event.delta.text);
        }
    }
}

REST

 // Request: POST /v1beta/interactions
 // Accept: text/event-stream
 {
   "model": "gemini-3-flash-preview",
   "input": "Tell me a story."
 }

 // Response (SSE Lines)
 // event: interaction.created
 // data: {"type": "interaction.created", "interaction": {"id": "int_xyz", "status": "created"}} // CHANGED: 'type' instead of 'event_type'
 //
 // event: interaction.status_update
 // data: {"type": "interaction.status_update", "status": "in_progress"} // NEW: Lifecycle status updates in stream (postpone until Sessions launch dependency)
 //
 // event: step.start
 // data: {"type": "step.start", "index": 0, "step": {"type": "thought"}} // NEW: Replaces content.start, 'step' instead of 'content'
 //
 // event: step.delta
 // data: {"type": "step.delta", "index": 0, "delta": {"type": "thought", "text": "User wants an explanation."}} // NEW: Delta type matches step type
 //
 // event: step.stop
 // data: {"type": "step.stop", "index": 0, "status": "done"} // NEW: Includes status
 //
 // event: step.start
 // data: {"type": "step.start", "index": 1, "step": {"type": "model_output"}} // NEW: Step wrapper for output
 //
 // event: step.delta
 // data: {"type": "step.delta", "index": 1, "delta": {"type": "text", "text": "Hello"}}
 //
 // event: step.stop
 // data: {"type": "step.stop", "index": 1, "status": "done"}
 //
 // event: interaction.complete
 // data: {"type": "interaction.complete", "interaction": {"id": "int_xyz", "status": "completed", "usage": {"prompt_tokens": 10, "completion_tokens": 5, "total_tokens": 15}}} // NEW: End of stream event with interaction details

스테이트리스 대화 기록

클라이언트 측에서 대화 기록을 수동으로 관리하는 경우 (스테이트리스 사용 사례) 이전 턴을 연결하는 방식을 업데이트해야 합니다.

  • 기존: 개발자는 응답에서 outputs 배열을 수집하고 다음 턴의 input 필드에 다시 전송하는 경우가 많았습니다.
  • 새 스키마: 이제 대답에서 steps 배열을 수집하고 다음 요청의 input 필드에 전달하여 새 사용자 턴을 user_input 단계로 추가해야 합니다.

출력 형식 구성: response_format 변경사항

업데이트된 API는 모든 출력 형식 컨트롤을 통합된 다형성 response_format 필드로 통합합니다. 이렇게 하면 최상위 수준에서 출력 구성이 중앙 집중화되고 generation_config는 온도, top_p, 사고와 같은 모델 동작에 집중할 수 있습니다.

주요 변경사항

  • API가 response_mime_type를 삭제합니다. 이제 response_format 내의 형식 항목별로 MIME 유형을 지정합니다.
  • response_format이 이제 다형 객체 (또는 배열)입니다. 각 항목에는 type 판별자 (text, audio, image)와 유형별 필드가 있습니다. 여러 출력 모달리티를 요청하려면 형식 항목의 배열을 전달하세요.
  • image_configgeneration_config에서 response_format로 이동합니다. 이제 "type": "image"를 사용하여 response_format 항목에서 aspect_ratioimage_size과 같은 이미지 출력 설정을 지정합니다.

구조화된 출력 (JSON)

새 스키마에서는 response_mime_type 필드가 삭제됩니다. 대신 "type": "text"이 있는 response_format 객체 내에 MIME 유형과 JSON 스키마를 지정하세요.

이전 (기존)

Python

interaction = client.interactions.create(
    model="gemini-3-flash-preview",
    input="Summarize this article.",
    response_mime_type="application/json",
    response_format={
        "type": "object",
        "properties": {
            "summary": {"type": "string"}
        }
    },
)

print(interaction.outputs[0].text)

자바스크립트

const interaction = await client.interactions.create({
    model: 'gemini-3-flash-preview',
    input: 'Summarize this article.',
    responseMimeType: 'application/json',
    responseFormat: {
        type: 'object',
        properties: {
            summary: { type: 'string' }
        }
    },
});

console.log(interaction.outputs[0].text);

REST

// Request: POST /v1beta/interactions
{
  "model": "gemini-3-flash-preview",
  "input": "Summarize this article.",
  "response_mime_type": "application/json",
  "response_format": {
    "type": "object",
    "properties": {
      "summary": { "type": "string" }
    }
  }
}

After (새 스키마)

Python

interaction = client.interactions.create(
    model="gemini-3-flash-preview",
    input="Summarize this article.",
    # response_mime_type is removed — specify mime_type inside response_format
    response_format={
        "type": "text",
        "mime_type": "application/json",
        "schema": {
            "type": "object",
            "properties": {
                "summary": {"type": "string"}
            }
        }
    },
)

print(interaction.steps[-1].content[0].text)

자바스크립트

const interaction = await client.interactions.create({
    model: 'gemini-3-flash-preview',
    input: 'Summarize this article.',
    // responseMimeType is removed — specify mimeType inside responseFormat
    responseFormat: {
        type: 'text',
        mimeType: 'application/json',
        schema: {
            type: 'object',
            properties: {
                summary: { type: 'string' }
            }
        }
    },
});

console.log(interaction.steps.at(-1).content[0].text);

REST

// Request: POST /v1beta/interactions
{
  "model": "gemini-3-flash-preview",
  "input": "Summarize this article.",
  // response_mime_type is removed
  "response_format": {
    "type": "text",                          // NEW: type discriminator
    "mime_type": "application/json",          // MOVED: from response_mime_type
    "schema": {                              // RENAMED: was response_format directly
      "type": "object",
      "properties": {
        "summary": { "type": "string" }
      }
    }
  }
}

이미지 구성

새 스키마는 generation_config에서 image_config를 삭제합니다. 이제 "type": "image"을 사용하여 response_format 항목에서 이미지 출력 설정을 지정합니다.

이전 (기존)

Python

interaction = client.interactions.create(
    model="gemini-3-flash-preview",
    input="Generate an image of a sunset over the ocean.",
    generation_config={
        "image_config": {
            "aspect_ratio": "1:1",
            "image_size": "1K"
        }
    },
)

자바스크립트

const interaction = await client.interactions.create({
    model: 'gemini-3-flash-preview',
    input: 'Generate an image of a sunset over the ocean.',
    generationConfig: {
        imageConfig: {
            aspectRatio: '1:1',
            imageSize: '1K'
        }
    },
});

REST

// Request: POST /v1beta/interactions
{
  "model": "gemini-3-flash-preview",
  "input": "Generate an image of a sunset over the ocean.",
  "generation_config": {
    "image_config": {
      "aspect_ratio": "1:1",
      "image_size": "1K"
    }
  }
}

After (새 스키마)

Python

interaction = client.interactions.create(
    model="gemini-3-flash-preview",
    input="Generate an image of a sunset over the ocean.",
    # image_config is removed from generation_config — use response_format
    response_format={
        "type": "image",
        "mime_type": "image/jpeg",
        "delivery": "inline",
        "aspect_ratio": "1:1",
        "image_size": "1K"
    },
)

자바스크립트

const interaction = await client.interactions.create({
    model: 'gemini-3-flash-preview',
    input: 'Generate an image of a sunset over the ocean.',
    // imageConfig is removed from generationConfig — use responseFormat
    responseFormat: {
        type: 'image',
        mimeType: 'image/jpeg',
        delivery: 'inline',
        aspectRatio: '1:1',
        imageSize: '1K'
    },
});

REST

// Request: POST /v1beta/interactions
{
  "model": "gemini-3-flash-preview",
  "input": "Generate an image of a sunset over the ocean.",
  // image_config removed from generation_config
  "response_format": {
    "type": "image",                         // NEW: type discriminator
    "mime_type": "image/jpeg",
    "delivery": "inline",
    "aspect_ratio": "1:1",                   // MOVED: from generation_config.image_config
    "image_size": "1K"                       // MOVED: from generation_config.image_config
  }
}

여러 출력 모달리티 (예: 텍스트와 오디오를 함께)를 요청하려면 단일 객체 대신 형식 항목 배열을 response_format에 전달하세요.

새 스키마로 마이그레이션하는 방법

SDK 사용자

최신 SDK 버전 (Python ≥1.76.0, JavaScript ≥1.53.0)으로 업그레이드합니다. SDK는 자동으로 새 스키마를 선택하므로 응답을 읽는 방식을 업데이트하는 것 외에는 코드를 변경할 필요가 없습니다 (위의 예 참고). 이러한 SDK 버전에서는 새 스키마만 지원됩니다. 이전 SDK 버전(Python ≤1.73.1, JavaScript ≤1.50.1)은 2026년 6월 6일에 기존 스키마가 삭제될 때까지 계속 작동합니다.

REST API 사용자

지금 새 스키마를 선택하려면 요청에 Api-Revision: 2026-05-20 헤더를 추가하세요. 5월 20일이 지나면 새 스키마가 모든 요청의 기본값이 됩니다. API가 기존 스키마를 영구적으로 삭제하는 6월 6일까지 Api-Revision: 2026-05-06를 사용하여 일시적으로 선택 해제할 수 있습니다.

타임라인

날짜 단계 SDK 사용자 REST API 사용자
5월 6일 선택 새 주요 SDK 버전이 제공됩니다 (Python ≥2.0.0, JS ≥2.0.0). 새 스키마를 자동으로 받으려면 업그레이드하세요. Api-Revision: 2026-05-20 헤더를 추가하여 선택합니다. 기본값은 기존으로 유지됩니다.
5월 20일 기본 뒤집기 이미 업그레이드한 경우 별도의 조치가 필요하지 않습니다. 이전 SDK (Python 1.x.x, JS 1.x.x)는 여전히 작동하지만 기존 응답을 반환합니다. 이제 새 스키마가 기본값입니다. 선택 해제하려면 Api-Revision: 2026-05-06 헤더를 전송하세요.
6월 6일 일몰 Python 및 JS용 1.x.x SDK 버전은 Interactions API 호출에서 작동하지 않습니다. 상호작용 API의 기존 스키마가 삭제되었습니다. Api-Revision 헤더가 무시되었습니다.

마이그레이션 체크리스트

걸음 수 스키마 (steps)

  • outputs 대신 steps 배열에서 응답 콘텐츠를 읽도록 코드를 업데이트합니다. 예시 보기
  • 코드가 user_inputmodel_output 단계 유형을 모두 처리하는지 확인합니다. 예시 보기
  • (함수 호출) steps 배열에서 function_call 단계를 찾도록 코드를 업데이트합니다. 예시 보기
  • (서버 측 도구) 도구별 단계를 처리하도록 코드를 업데이트합니다 (예: google_search_call, google_search_result). 예시 보기
  • (상태 비저장 기록) 다음 요청의 input 필드에 steps 배열을 전달하도록 기록 관리를 업데이트합니다. 세부정보 보기
  • (스트리밍만 해당) 새 SSE 이벤트 유형 (interaction.created, step.delta 등)을 수신하도록 클라이언트를 업데이트합니다. 예시 보기

출력 형식 구성 (response_format)

  • response_mime_typeresponse_format 내의 mime_type 필드로 바꿉니다. 예시 보기
  • 기존 response_format JSON 스키마를 {"type": "text", "schema": ...} 객체로 래핑합니다. 예시 보기
  • (이미지 생성) image_configgeneration_config에서 response_format{"type": "image", ...} 항목으로 이동합니다. 예시 보기
  • (멀티모달) 여러 출력 모달리티를 요청할 때 단일 객체에서 배열로 response_format 변환