L'API Interactions v1beta introduit des modifications destructives qui restructurent la forme de l'API pour prendre en charge de futures fonctionnalités telles que le pilotage en cours de vol et les appels d'outils asynchrones. Cette page explique les modifications et fournit des exemples de code avant et après pour vous aider à effectuer la migration. Il existe deux catégories de modifications :
- Schéma des étapes : un nouveau tableau
stepsremplace le tableauoutputs, fournissant une chronologie structurée de chaque tour d'interaction. - Configuration du format de sortie : un nouveau polymorphe
response_formatconsolide tous les contrôles de format de sortie et supprimeresponse_mime_type.
Suivez les étapes décrites dans Migrer vers le nouveau schéma pour mettre à jour votre intégration.
Modification principale : outputs vers steps
Le nouveau schéma remplace le tableau outputs par un tableau steps.
- Ancien : les réponses renvoyaient un tableau
outputsplat contenant uniquement le contenu généré par le modèle. - Nouveau schéma : les réponses renvoient un tableau
stepsqui inclut à la fois les entrées utilisateur répétées et les sorties du modèle, fournissant une chronologie complète du tour d'interaction.
Les réponses unaires (non diffusées en streaming) répètent votre entrée comme première étape du tableau steps. Les réponses diffusées en streaming ignorent l'étape d'entrée et n'émettent que des deltas de contenu généré.
Entrée/sortie de base (unaire)
Avant (ancien)
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?"
}
]
}
Après (nouveau schéma)
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?"
}
]
}
]
}
Appel de fonction
La structure de la requête reste inchangée, mais la réponse remplace le contenu outputs plat par des étapes structurées.
Avant (ancien)
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" }
}
]
}
Après (nouveau schéma)
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" }
}
]
}
Outils côté serveur
Les outils côté serveur (comme la recherche Google ou l'exécution de code) génèrent désormais des types d'étapes spécifiques dans le tableau steps. Alors que l'ancien schéma renvoyait ces opérations en tant que types de contenu spécifiques dans le tableau outputs, le nouveau schéma les déplace dans le tableau steps. L'exemple suivant utilise la recherche Google.
Avant (ancien)
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"
}
Après (nouveau schéma)
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
Le streaming expose de nouveaux types d'événements :
Nouveaux types d'événements
interaction.createdinteraction.status_update: couvre désormais tous les états du cycle de vie, y compris la finalisation et les erreurs (voir les états ci-dessous)step.startstep.deltastep.stop
États interaction.status_update
in_progressactivecompletedinterruptedrequires_actionerror
Types d'événements obsolètes
Les types d'événements hérités suivants sont remplacés par les nouveaux événements listés ci-dessus :
interaction.start→interaction.createdcontent.start→step.startcontent.delta→step.deltacontent.stop→step.stopinteraction.complete→interaction.status_updateavecstatus: "completed"error→interaction.status_updateavecstatus: "error"interaction.status_update→interaction.status_update(inchangé, mais couvre désormais des états supplémentaires)
Appels de fonction en streaming : lorsque vous utilisez le streaming avec l'appel de fonction,
l'événement step.start fournit le nom de la fonction, et les événements step.delta diffusent les arguments en tant que chaînes JSON partielles (à l'aide de arguments_delta). Vous
devez cumuler ces deltas pour obtenir les arguments complets. Cela diffère des appels unaires, où vous recevez l'objet d'appel de fonction complet en une seule fois.
Exemples
Avant (ancien)
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}}
Après (nouveau schéma)
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
Historique des conversations sans état
Si vous gérez manuellement l'historique des conversations côté client (cas d'utilisation sans état), vous devez modifier la façon dont vous enchaînez les tours précédents.
- Ancien : les développeurs collectaient souvent le tableau
outputsà partir des réponses et les renvoyaient dans le champinputau tour suivant. - Nouveau schéma : vous devez maintenant collecter le tableau
stepsà partir de la réponse et le transmettre dans le champinputde la requête suivante, en ajoutant votre nouveau tour d'utilisateur en tant qu'étapeuser_input.
Configuration du format de sortie : modifications de response_format
L'API mise à jour consolide tous les contrôles de format de sortie dans un champ response_format unifié et polymorphe. Cela centralise la configuration de la sortie au niveau supérieur et permet à generation_config de se concentrer sur le comportement du modèle (comme la température, le top_p et la réflexion).
Principales modifications
- L'API supprime
response_mime_type. Vous spécifiez désormais le type MIME par entrée de format dansresponse_format. response_formatest désormais un objet (ou un tableau) polymorphe. Chaque entrée comporte un discriminateurtype(text,audio,image) et des champs spécifiques au type. Pour demander plusieurs modalités de sortie, transmettez un tableau d'entrées de format.image_configpasse degeneration_configàresponse_format. Vous spécifiez désormais les paramètres de sortie d'image tels queaspect_ratioetimage_sizedans une entréeresponse_formatavec"type": "image".
Sortie structurée (JSON)
Le nouveau schéma supprime le champ response_mime_type. Spécifiez plutôt le
type MIME et le schéma JSON dans un response_format objet avec
"type": "text".
Avant (ancien)
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" }
}
}
}
Après (nouveau schéma)
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" }
}
}
}
}
Configuration des images
Le nouveau schéma supprime image_config de generation_config. Vous spécifiez désormais les paramètres de sortie d'image dans une entrée response_format avec "type": "image".
Avant (ancien)
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"
}
}
}
Après (nouveau schéma)
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
}
}
Pour demander plusieurs modalités de sortie (par exemple, du texte et de l'audio ensemble), transmettez un tableau d'entrées de format à response_format au lieu d'un seul objet.
Migrer vers le nouveau schéma
Utilisateurs du SDK
Effectuez une mise à niveau vers la dernière version du SDK (Python ≥1.76.0, JavaScript ≥1.53.0). Le SDK vous inscrit automatiquement au nouveau schéma. Aucune modification de code n'est nécessaire au-delà de la mise à jour de la façon dont vous lisez les réponses (voir les exemples ci-dessus). Notez que seul le nouveau schéma est compatible avec ces versions du SDK. Les anciennes versions du SDK (Python ≤1.73.1, JavaScript ≤1.50.1) continueront de fonctionner jusqu'à la suppression de l'ancien schéma le 6 juin 2026.
Utilisateurs de l'API REST
Ajoutez l'en-tête Api-Revision: 2026-05-20 à vos requêtes pour activer le nouveau schéma dès maintenant. Après le 20 mai, le nouveau schéma deviendra la valeur par défaut pour toutes les
requêtes. Vous pouvez temporairement désactiver cette option avec Api-Revision: 2026-05-06
jusqu'au 6 juin, date à laquelle l'API supprimera définitivement l'ancien schéma.
Chronologie
| Date | Phase | Utilisateurs du SDK | Utilisateurs de l'API REST |
|---|---|---|---|
| 6 mai | Activer | Nouvelle version majeure du SDK disponible (Python ≥2.0.0, JS ≥2.0.0). Effectuez une mise à niveau pour obtenir automatiquement le nouveau schéma. | Ajoutez l'en-tête Api-Revision: 2026-05-20 pour activer le nouveau schéma. L'ancien schéma reste la valeur par défaut. |
| 20 mai | Changement de valeur par défaut | Aucune action n'est requise si la mise à niveau a déjà été effectuée. Les anciens SDK (Python 1.x.x, JS 1.x.x) fonctionnent toujours, mais renvoient des réponses héritées. | Le nouveau schéma est désormais la valeur par défaut. Envoyez l'en-tête Api-Revision: 2026-05-06 pour désactiver le nouveau schéma. |
| 6 juin | Coucher du soleil | Les versions 1.x.x du SDK pour Python et JS ne fonctionneront plus pour les appels de l'API Interactions. | L'ancien schéma est supprimé pour l'API Interactions. L'en-tête Api-Revision est ignoré. |
Liste de contrôle de la migration
Schéma des étapes (steps)
- Mettez à jour le code pour lire le contenu de la réponse à partir du tableau
stepsau lieu deoutputs. Voir des exemples.. - Vérifiez que votre code gère les types d'étapes
user_inputetmodel_output. Voir des exemples.. - (Appel de fonction) Mettez à jour le code pour trouver les étapes
function_calldans le tableausteps. Voir des exemples.. - (Outils côté serveur) Mettez à jour le code pour gérer les étapes spécifiques à l'outil (par exemple,
google_search_call,google_search_result). Voir des exemples. - (Historique sans état) Mettez à jour la gestion de l'historique pour transmettre le tableau
stepsdans le champinputde la requête suivante. Voir les détails. - (Streaming uniquement) Mettez à jour le client pour écouter les nouveaux types d'événements SSE (
interaction.created,step.delta, etc.). Voir des exemples.
Configuration du format de sortie (response_format)
- Remplacez
response_mime_typepar un champmime_typedansresponse_format. Voir des exemples. - Encapsulez votre schéma JSON
response_formatexistant dans un objet{"type": "text", "schema": ...}. Voir des exemples. - (Génération d'images) Déplacez
image_configdegeneration_configvers une entrée{"type": "image", ...}dansresponse_format. Voir des exemples. - (Multimodal) Convertissez
response_formatd'un seul objet en tableau lorsque vous demandez plusieurs modalités de sortie.