API Interactions: guia de migração de mudanças interruptivas (maio de 2026)

A API Interactions v1beta está introduzindo mudanças interruptivas que reestruturam o formato da API para oferecer suporte a recursos futuros, como direcionamento em tempo real e chamadas de ferramentas assíncronas. Esta página explica o que está mudando e fornece exemplos de código antes e depois para ajudar na migração. Há duas categorias de mudanças:

  1. Esquema de etapas: uma nova matriz steps substitui a matriz outputs, fornecendo um cronograma estruturado de cada turno de interação.
  2. Configuração do formato de saída: um novo polimórfico response_format consolida todos os controles de formato de saída e remove response_mime_type.

Siga as etapas em Como migrar para o novo esquema para atualizar sua integração.

Mudança principal: outputs para steps

O novo esquema substitui a matriz outputs por uma matriz steps.

  • Legado: as respostas retornavam uma matriz outputs simples que continha apenas o conteúdo gerado do modelo.
  • Novo esquema: as respostas retornam uma matriz steps que inclui entradas de usuário e saídas de modelo, fornecendo um cronograma completo do turno de interação.

As respostas unárias (não de streaming) repetem sua entrada como a primeira etapa na matriz steps. As respostas de streaming ignoram a etapa de entrada e emitem apenas deltas de conteúdo gerado.

Entrada/saída básica (unária)

Antes (legado)

Python

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

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

JavaScript

// 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?"
    }
  ]
}

Depois (novo esquema)

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

JavaScript

// 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?"
        }
      ]
    }
  ]
}

Chamadas de função

A estrutura da solicitação permanece inalterada, mas a resposta substitui o conteúdo outputs simples por etapas estruturadas.

Antes (legado)

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}")

JavaScript

// 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" }
    }
  ]
}

Depois (novo esquema)

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}")

JavaScript

// 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" }
    }
  ]
}

Ferramentas do lado do servidor

As ferramentas do lado do servidor (como a Pesquisa Google ou a execução de código) agora geram tipos de etapas específicos na matriz steps. Embora o esquema legado tenha retornado essas operações como tipos de conteúdo específicos na matriz outputs, o novo esquema as move para a matriz steps. Os exemplos a seguir usam a Pesquisa Google.

Antes (legado)

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}")

JavaScript

// 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"
}

Depois (novo esquema)

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}")

JavaScript

// 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"
}

Streaming

O streaming expõe novos tipos de eventos:

Novos tipos de eventos

  • interaction.created
  • interaction.status_update : agora abrange todos os estados do ciclo de vida, incluindo conclusão e erros (consulte os status abaixo)
  • step.start
  • step.delta
  • step.stop
Status interaction.status_update
  • in_progress
  • active
  • completed
  • interrupted
  • requires_action
  • error

Tipos de eventos descontinuados

Os seguintes tipos de eventos legados são substituídos pelos novos eventos listados acima:

  • interaction.startinteraction.created
  • content.startstep.start
  • content.deltastep.delta
  • content.stopstep.stop
  • interaction.completeinteraction.status_update com status: "completed"
  • errorinteraction.status_update com status: "error"
  • interaction.status_updateinteraction.status_update (inalterado, mas agora abrange estados adicionais)

Chamadas de função de streaming: quando você usa o streaming com chamadas de função, o evento step.start entrega o nome da função, e os eventos step.delta transmitem os argumentos como strings JSON parciais (usando arguments_delta). É necessário acumular esses deltas para receber os argumentos completos. Isso é diferente das chamadas unárias, em que você recebe o objeto de chamada de função completo de uma só vez.

Exemplos

Antes (legado)

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)

JavaScript

// 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}}
Depois (novo esquema)

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="")

JavaScript

// 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

Histórico de conversas sem estado

Se você gerenciar o histórico de conversas manualmente no lado do cliente (caso de uso sem estado), será necessário atualizar a forma como você encadeia os turnos anteriores.

  • Legado: os desenvolvedores costumavam coletar a matriz outputs das respostas e enviá-las de volta no campo input no próximo turno.
  • Novo esquema: agora você precisa coletar a matriz steps da resposta e transmiti-la no campo input da próxima solicitação, anexando o novo turno do usuário como uma etapa user_input.

Configuração do formato de saída: mudanças em response_format

A API atualizada consolida todos os controles de formato de saída em um campo response_format unificado e polimórfico. Isso centraliza a configuração de saída no nível superior e mantém generation_config focado no comportamento do modelo (como temperatura, top_p e pensamento).

Mudanças importantes

  • A API remove response_mime_type. Agora você especifica o tipo MIME por entrada de formato dentro de response_format.
  • response_format agora é um objeto polimórfico (ou matriz). Cada entrada tem um discriminador type (text, audio, image) e campos específicos do tipo. Para solicitar várias modalidades de saída, transmita uma matriz de entradas de formato.
  • image_config é movido de generation_config para response_format. Agora você especifica as configurações de saída de imagem, como aspect_ratio e image_size em uma entrada response_format com "type": "image".

Saída estruturada (JSON)

O novo esquema remove o campo response_mime_type. Em vez disso, especifique o tipo MIME e o esquema JSON dentro de um response_format objeto com "type": "text".

Antes (legado)

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)

JavaScript

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" }
    }
  }
}

Depois (novo esquema)

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)

JavaScript

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" }
      }
    }
  }
}

Configuração de imagem

O novo esquema remove image_config de generation_config. Agora você especifica as configurações de saída de imagem em uma entrada response_format com "type": "image".

Antes (legado)

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"
        }
    },
)

JavaScript

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"
    }
  }
}

Depois (novo esquema)

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"
    },
)

JavaScript

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
  }
}

Para solicitar várias modalidades de saída (por exemplo, texto e áudio juntos), transmita uma matriz de entradas de formato para response_format em vez de um único objeto.

Como migrar para o novo esquema

Usuários do SDK

Faça upgrade para a versão mais recente do SDK (Python ≥1.76.0, JavaScript ≥1.53.0). O SDK ativa automaticamente o novo esquema. Não é necessário mudar o código além de atualizar a forma como você lê as respostas (consulte os exemplos acima). Somente o novo esquema é compatível com essas versões do SDK. As versões mais antigas do SDK (Python ≤1.73.1, JavaScript ≤1.50.1) vão continuar funcionando até que o esquema legado seja removido em 6 de junho de 2026.

Usuários da API REST

Adicione o cabeçalho Api-Revision: 2026-05-20 às suas solicitações para ativar o novo esquema agora. Após 20 de maio, o novo esquema se tornará o padrão para todas as solicitações. Você pode desativar temporariamente com Api-Revision: 2026-05-06 até 6 de junho, quando a API remover permanentemente o esquema legado.

Cronograma

Data Fase Usuários do SDK Usuários da API REST
6 de maio Ativar Nova versão principal do SDK disponível (Python ≥2.0.0, JS ≥2.0.0). Faça upgrade para receber o novo esquema automaticamente. Adicione o cabeçalho Api-Revision: 2026-05-20 para ativar. O padrão permanece legado.
20 de maio Inversão padrão Nenhuma ação necessária se já tiver feito upgrade. Os SDKs mais antigos (Python 1.x.x, JS 1.x.x) ainda funcionam, mas retornam respostas legadas. O novo esquema agora é o padrão. Envie o cabeçalho Api-Revision: 2026-05-06 para desativar.
6 de junho Pôr do sol As versões 1.x.x do SDK para Python e JS vão falhar para chamadas da API Interactions. Esquema legado removido para a API Interactions. Cabeçalho Api-Revision ignorado.

Lista de verificação de migração

Esquema de etapas (steps)

  • Atualize o código para ler o conteúdo da resposta da matriz steps em vez de outputs. Consulte exemplos.
  • Verifique se o código processa os tipos de etapa user_input e model_output. Consulte exemplos.
  • (Chamada de função) Atualize o código para encontrar etapas function_call na matriz steps. Consulte exemplos.
  • (Ferramentas do lado do servidor) Atualize o código para processar etapas específicas da ferramenta (por exemplo, google_search_call, google_search_result). Consulte exemplos.
  • (Histórico sem estado) Atualize o gerenciamento do histórico para transmitir a matriz steps no campo input da próxima solicitação. Consulte detalhes.
  • (Somente streaming) Atualize o cliente para detectar novos tipos de eventos SSE (interaction.created, step.delta etc.). Consulte exemplos.

Configuração do formato de saída (response_format)

  • Substitua response_mime_type por um campo mime_type dentro de response_format. Consulte exemplos.
  • Encapsule o esquema JSON response_format atual em um objeto {"type": "text", "schema": ...}. Consulte exemplos.
  • (Geração de imagens) Mova image_config de generation_config para uma entrada {"type": "image", ...} em response_format. Consulte exemplos.
  • (Multimodal) Converta response_format de um único objeto para uma matriz ao solicitar várias modalidades de saída.