Interfejs API interakcji: przewodnik po migracji w związku ze zmianami powodującymi niezgodność (maj 2026 r.)

v1beta Interactions API wprowadzamy zmiany powodujące niezgodność wsteczną, które zmieniają strukturę interfejsu API, aby obsługiwać przyszłe funkcje, takie jak sterowanie w trakcie działania i asynchroniczne wywołania narzędzi. Na tej stronie wyjaśniamy, co się zmienia, i podajemy przykłady kodu przed i po zmianach, aby ułatwić Ci migrację. Istnieją 2 kategorie zmian:

  1. Schemat kroków: nowa tablica steps zastępuje tablicę outputs, zapewniając uporządkowaną oś czasu każdej interakcji.
  2. Konfiguracja formatu wyjściowego: nowy polimorficzny response_format konsoliduje wszystkie elementy sterujące formatem wyjściowym i usuwa response_mime_type.

Aby zaktualizować integrację, wykonaj czynności opisane w sekcji Jak przeprowadzić migrację do nowego schematu.

Najważniejsza zmiana: outputs na steps

Nowy schemat zastępuje tablicę outputs tablicą steps.

  • Starsza wersja: odpowiedzi zwracały płaską tablicę outputs zawierającą tylko wygenerowaną przez model treść.
  • Nowy schemat: odpowiedzi zwracają tablicę steps zawierającą uporządkowane kroki z dyskryminatorami typu.

POST /interactions zwraca tylko kroki wyjściowe. GET /interactions/{id} zwraca pełną oś czasu kroków, w tym początkowy krok user_input.

Podstawowe dane wejściowe/wyjściowe (unarne)

Przed (starsza wersja)

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

Po aktualizacji (nowy schemat)

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

// POST Response
{
  "id": "int_123",
  "steps": [
    {
      "type": "model_output",
      "content": [
        {
          "type": "text",
          "text": "Why did the chicken cross the road?"
        }
      ]
    }
  ]
}

// GET /v1beta/interactions/int_123 (returns full timeline including input)
{
  "id": "int_123",
  "steps": [
    {
      "type": "user_input",
      "content": [
        { "type": "text", "text": "Tell me a joke." }
      ]
    },
    {
      "type": "model_output",
      "content": [
        {
          "type": "text",
          "text": "Why did the chicken cross the road?"
        }
      ]
    }
  ]
}

Wywoływanie funkcji

Struktura żądania pozostaje bez zmian, ale odpowiedź zastępuje płaską treśćoutputs uporządkowanymi krokami.

Przed (starsza wersja)

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

Po aktualizacji (nowy schemat)

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

// POST Response
{
  "id": "int_001",
  "status": "requires_action",
  "steps": [
    {
      "type": "thought",
      "summary": [{
        "type": "text",
        "text": "I need to check the weather in Boston..."
      }],
      "signature": "abc123..."
    },
    {
      "type": "function_call",
      "id": "fc_1",
      "name": "get_weather",
      "arguments": { "location": "Boston, MA" }
    }
  ]
}

Narzędzia po stronie serwera

Narzędzia po stronie serwera (np. wyszukiwarka Google czy wykonywanie kodu) zwracają teraz w tablicy steps określone typy kroków. W starszym schemacie te operacje były zwracane jako określone typy treści w tablicy outputs, a w nowym schemacie są przenoszone do tablicy steps. W przykładach poniżej używamy wyszukiwarki Google.

Przed (starsza wersja)

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

Po aktualizacji (nowy schemat)

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

// POST Response
{
  "id": "int_456",
  "steps": [
    {
      "type": "google_search_call",
      "id": "gs_1",
      "arguments": { "queries": ["last Super Bowl winner"] },
      "signature": "abc123..."
    },
    {
      "type": "google_search_result",
      "call_id": "gs_1",
      "result": {
        "search_suggestions": "<div>...</div>"
      },
      "signature": "abc123..."
    },
    {
      "type": "model_output",
      "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

Streaming udostępnia nowe typy zdarzeń:

Nowe typy zdarzeń

  • interaction.created
  • interaction.status_update – obejmuje teraz wszystkie stany cyklu życia, w tym ukończenie i błędy (patrz stany poniżej).
  • step.start
  • step.delta
  • step.stop
interaction.status_update stanu
  • in_progress
  • active
  • completed
  • interrupted
  • requires_action
  • error

Wycofane typy zdarzeń

Te starsze typy zdarzeń zostały zastąpione nowymi zdarzeniami wymienionymi powyżej:

  • interaction.startinteraction.created
  • content.startstep.start
  • content.deltastep.delta
  • content.stopstep.stop
  • interaction.completeinteraction.status_updatestatus: "completed"
  • errorinteraction.status_updatestatus: "error"
  • interaction.status_updateinteraction.status_update (bez zmian, ale teraz obejmuje dodatkowe stany)

Wywoływanie funkcji strumieniowych: gdy używasz strumieniowania z wywoływaniem funkcji, zdarzenie step.start dostarcza nazwę funkcji, a zdarzenia step.delta przesyłają argumenty jako częściowe ciągi JSON (za pomocą arguments_delta). Musisz zgromadzić te różnice, aby uzyskać pełne argumenty. Różni się to od wywołań binarnych, w których od razu otrzymujesz cały obiekt wywołania funkcji.

Przykłady

Przed (starsza wersja)

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}}
Po aktualizacji (Nowy schemat)

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

Historia rozmowy bezstanowej

Jeśli zarządzasz historią rozmów ręcznie po stronie klienta (przypadek użycia bezstanowego), musisz zaktualizować sposób łączenia poprzednich tur.

  • Starsze: deweloperzy często zbierali tablicę outputs z odpowiedzi i odsyłali ją w polu input w kolejnej turze.
  • Nowy schemat: z odpowiedzi należy teraz zebrać tablicę steps i przekazać ją w polu input kolejnego żądania, dodając nowy zwrot użytkownika jako krok user_input.

Konfiguracja formatu wyjściowego: response_format zmiany

Zaktualizowany interfejs API łączy wszystkie opcje formatu wyjściowego w ujednolicone, polimorficzne pole response_format. Dzięki temu konfiguracja danych wyjściowych jest scentralizowana na najwyższym poziomie, a generation_config skupia się na zachowaniu modelu (np. temperatura, top_p i proces myślowy).

Najważniejsze zmiany

  • Interfejs API usuwa response_mime_type. Teraz możesz określić typ MIME dla każdego wpisu formatu w sekcji response_format.
  • response_format jest teraz obiektem (lub tablicą) polimorficznym. Każdy wpis ma wyróżnik type (text, audio, image) i pola specyficzne dla typu. Aby poprosić o wiele trybów wyjściowych, przekaż tablicę wpisów formatu.
  • image_config przenosi się z generation_config do response_format. Ustawienia wyjściowe obrazu, takie jak aspect_ratioimage_size, określasz teraz we wpisie response_format z parametrem "type": "image".

Uporządkowane dane wyjściowe (JSON)

Nowy schemat usuwa pole response_mime_type. Zamiast tego określ typ MIME i schemat JSON w obiekcie response_format z wartością "type": "text".

Przed (starsza wersja)

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

Po aktualizacji (nowy schemat)

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

Konfiguracja obrazu

Nowy schemat usuwa image_configgeneration_config. Ustawienia wyjściowe obrazu określasz teraz w response_format"type": "image".

Przed (starsza wersja)

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

Po aktualizacji (nowy schemat)

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

Aby poprosić o wiele trybów wyjściowych (np. tekst i dźwięk), przekaż do parametru response_format tablicę wpisów formatu zamiast pojedynczego obiektu.

Jak przeprowadzić migrację do nowego schematu

Użytkownicy pakietu SDK

Uaktualnij pakiet SDK do najnowszej wersji (Python ≥1.76.0, JavaScript ≥1.53.0). Pakiet SDK automatycznie włącza nowy schemat – nie musisz wprowadzać żadnych zmian w kodzie poza aktualizacją sposobu odczytywania odpowiedzi (patrz przykłady powyżej). Pamiętaj, że w tych wersjach pakietu SDK obsługiwany jest tylko nowy schemat. Starsze wersje pakietu SDK (Python ≤1.73.1, JavaScript ≤1.50.1) będą nadal działać do momentu usunięcia starszego schematu 6 czerwca 2026 r.

Użytkownicy interfejsu API REST

Dodaj do żądań nagłówek Api-Revision: 2026-05-20, aby już teraz włączyć nowy schemat. Po 20 maja nowy schemat stanie się domyślnym schematem dla wszystkich żądań. Możesz tymczasowo zrezygnować z tej funkcji za pomocą Api-Revision: 2026-05-06 do 6 czerwca, kiedy interfejs API trwale usunie starszy schemat.

Oś czasu

Data Faza Użytkownicy pakietu SDK Użytkownicy interfejsu API REST
6 maja Włącz Dostępna jest nowa wersja główna pakietu SDK (Python ≥2.0.0, JS ≥2.0.0). Przejdź na wyższą wersję, aby automatycznie uzyskać nowy schemat. Aby wyrazić zgodę, dodaj nagłówek Api-Revision: 2026-05-20. Domyślne ustawienie pozostaje starsze.
20 maja Domyślne odwrócenie Jeśli masz już uaktualnioną wersję, nie musisz nic robić. Starsze pakiety SDK (Python 1.x.x, JS 1.x.x) nadal działają, ale zwracają starsze odpowiedzi. Nowy schemat jest teraz domyślny. Wyślij nagłówek Api-Revision: 2026-05-06, aby zrezygnować.
6 czerwca Zachód słońca Wersje pakietu SDK 1.x.x dla Pythona i JS przestaną działać w przypadku wywołań interfejsu API interakcji. Usunięto starszy schemat interfejsu API interakcji. Nagłówek Api-Revision został zignorowany.

Lista kontrolna migracji

Schemat kroków (steps)

  • Zaktualizuj kod, aby odczytywać treść odpowiedzi z tablicy steps zamiast z outputs. Zobacz przykłady.
  • Sprawdź, czy kod obsługuje typy kroków user_inputmodel_output. Zobacz przykłady.
  • (Function Calling) Zaktualizuj kod, aby znaleźć kroki function_call w tablicy steps. Zobacz przykłady.
  • (Narzędzia po stronie serwera) Zaktualizuj kod, aby obsługiwał kroki specyficzne dla narzędzia (np. google_search_call, google_search_result). Zobacz przykłady
  • (Historia bezstanowa) Zaktualizuj zarządzanie historią, aby przekazywać tablicę steps w polu input następnego żądania. Zobacz szczegóły
  • (Tylko przesyłanie strumieniowe) Zaktualizuj klienta, aby nasłuchiwał nowych typów zdarzeń SSE (interaction.created, step.delta itp.). Zobacz przykłady

Konfiguracja formatu wyjściowego (response_format)

  • Zastąp response_mime_type polem mime_type wewnątrz response_format. Zobacz przykłady
  • Umieść istniejący schemat JSON response_format w obiekcie {"type": "text", "schema": ...}. Zobacz przykłady
  • (Generowanie obrazów) Przenieś image_configgeneration_config do pozycji {"type": "image", ...}response_format. Zobacz przykłady
  • (Multimodal) Convert response_format from a single object to an array when requesting multiple output modalities..