Ten przewodnik pomoże Ci przejść z interfejsu generateContent API na interfejs Interactions API.
Interactions API to najprostszy i najlepszy sposób na tworzenie aplikacji z użyciem modeli Gemini i agentów. Chociaż interfejs generateContent jest nadal w pełni obsługiwany, zalecamy korzystanie z Interactions API we wszystkich nowych projektach.
Dlaczego warto przeprowadzić migrację?
Interactions API to najprostszy i najlepszy sposób na tworzenie aplikacji z użyciem modeli Gemini i agentów:
- Zarządzanie historią po stronie serwera: uproszczone wieloetapowe procesy dzięki
previous_interaction_id. Serwer domyślnie włącza stan (store=true), ale możesz wybrać zachowanie bezstanowe, ustawiającstore=false. - Obserwowalne etapy wykonywania: etapy z określonym typem ułatwiają debugowanie złożonych przepływów i renderowanie interfejsu na potrzeby zdarzeń pośrednich (takich jak myśli lub widżety wyszukiwania).
- Korzystanie z narzędzi i Agentic Workflows: natywna obsługa wieloetapowego korzystania z narzędzi, orkiestracji i złożonych procesów rozumowania dzięki wpisanym krokom wykonywania.
- Długotrwałe zadania i zadania w tle: umożliwia przenoszenie czasochłonnych operacji, takich jak Deep Think i Deep Research, do procesów w tle za pomocą
background=true.
Podstawowe dane wejściowe/wyjściowe
W tej sekcji dowiesz się, jak przenieść proste żądanie generowania tekstu.
Przed (generateContent)
Interfejs API generateContent jest bezstanowy i zwraca odpowiedź bezpośrednio. Struktura odpowiedzi zawiera dane wyjściowe w postaci listy candidates, z których każda zawiera content z listą parts do przeanalizowania.
Python
from google import genai
client = genai.Client()
response = client.models.generate_content(
model="gemini-2.5-flash-lite", contents="Tell me a joke."
)
print(response.text)
JavaScript
import { GoogleGenAI } from '@google/genai';
const ai = new GoogleGenAI({});
const response = await ai.models.generateContent({
model: "gemini-2.5-flash-lite",
contents: "Tell me a joke.",
});
console.log(response.text);
Java
import com.google.genai.Client;
import com.google.genai.types.GenerateContentResponse;
Client client = new Client();
GenerateContentResponse response =
client.models.generateContent("gemini-2.5-flash-lite", "Tell me a joke.", null);
System.out.println(response.text());
Go
package main
import (
"context"
"fmt"
"log"
"google.golang.org/genai"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
response, err := client.Models.GenerateContent(
ctx,
"gemini-2.5-flash-lite",
genai.Text("Tell me a joke."),
nil,
)
if err != nil {
log.Fatal(err)
}
fmt.Println(response.Text())
}
REST
# Request
curl -X POST "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-lite:generateContent" \
-H "Content-Type: application/json" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-d '{
"contents": [{
"parts": [{
"text": "Tell me a joke."
}]
}]
}'
# Response
{
"candidates": [
{
"content": {
"parts": [
{
"text": "Why did the chicken cross the road? To get to the other side!"
}
],
"role": "model"
},
"finishReason": "STOP",
"index": 0
}
],
"usageMetadata": {
"promptTokenCount": 4,
"candidatesTokenCount": 12,
"totalTokenCount": 16
}
}
Interactions API zwraca zasób przechowywanej interakcji z osią czasu steps. Możesz ręcznie sprawdzić tablicę steps, aby znaleźć zdarzenia pośrednie, ale pakiety SDK Google GenAI udostępniają właściwości ułatwiające dostęp do ostatecznych danych wyjściowych bezpośrednio w zwracanym obiekcie Interaction.
Najczęstszą właściwością ułatwiającą jest .output_text (String), która automatycznie wyodrębnia i łączy kolejne bloki TextContent na końcu odpowiedzi modelu. Chociaż działa to idealnie w przypadku prostych odpowiedzi, nie obejmuje wcześniejszych bloków tekstu oddzielonych treściami nietekstowymi (takimi jak przemyślenia, obrazy, dźwięk lub wywołania narzędzi). W przypadku złożonych lub przeplatanych odpowiedzi multimodalnych musisz ręcznie iterować po steps.
Python
from google import genai
client = genai.Client()
interaction = client.interactions.create(
model="gemini-3.8-flash", input="Tell me a joke."
)
print(interaction.output_text)
JavaScript
import { GoogleGenAI } from '@google/genai';
const client = new GoogleGenAI({});
let interaction = await client.interactions.create({
model: 'gemini-3.8-flash',
input: 'Tell me a joke.'
});
console.log(interaction.output_text);
Java
import com.google.genai.Client;
import com.google.genai.gaos.models.interactions.CreateModelInteraction;
import com.google.genai.gaos.models.interactions.Interaction;
import com.google.genai.gaos.models.interactions.InteractionsInput;
import com.google.genai.gaos.models.interactions.Model;
import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;
Client client = new Client();
CreateModelInteraction request =
CreateModelInteraction.builder()
.model(Model.of("gemini-3.8-flash"))
.input(InteractionsInput.of("Tell me a joke."))
.build();
Interaction interaction =
client.interactions.create(CreateInteractionRequestBody.of(request)).interaction().get();
System.out.println(interaction.outputText().orElse(""));
Go
package main
import (
"context"
"fmt"
"log"
"google.golang.org/genai"
"google.golang.org/genai/interactions/models/interactions"
"google.golang.org/genai/interactions/models/operations"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{
Model: interactions.Model("gemini-3.8-flash"),
Input: interactions.NewInteractionsInput("Tell me a joke."),
}),
})
if err != nil {
log.Fatal(err)
}
if res.Interaction.OutputText != nil {
fmt.Println(*res.Interaction.OutputText)
}
}
REST
# Request
curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "Content-Type: application/json" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-d '{
"model": "gemini-3.8-flash",
"input": "Tell me a joke."
}'
# Response
{
"id": "int_123",
"status": "completed",
"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?"
}
]
}
]
}
Rozmowy wieloetapowe
Interactions API domyślnie przechowuje interakcje, co umożliwia zarządzanie stanem po stronie serwera w przypadku wieloetapowych rozmów.
Przed (generateContent)
W generateContent musisz ręcznie zarządzać historią rozmów za pomocą tablicy contents lub asystenta czatu po stronie klienta.
Python
Za pomocą asystenta czatu (zalecane)
from google import genai
client = genai.Client()
chat = client.chats.create(model="gemini-2.5-flash-lite")
response1 = chat.send_message("Hi, my name is Phil.")
print(response1.text)
response2 = chat.send_message("What is my name?")
print(response2.text)
Ręczne zarządzanie historią
from google import genai
from google.genai import types
client = genai.Client()
response = client.models.generate_content(
model="gemini-2.5-flash-lite",
contents=[
types.Content(
role="user", parts=[types.Part.from_text(text="Hi, my name is Phil.")]
),
types.Content(
role="model",
parts=[types.Part.from_text(text="Hi Phil, how can I help you?")],
),
types.Content(
role="user", parts=[types.Part.from_text(text="What is my name?")]
),
],
)
print(response.text)
JavaScript
Za pomocą asystenta czatu (zalecane)
import { GoogleGenAI } from '@google/genai';
const client = new GoogleGenAI({});
const chat = client.chats.create({ model: 'gemini-2.5-flash-lite' });
let response = await chat.sendMessage({ message: 'Hi, my name is Phil.' });
console.log(response.text);
response = await chat.sendMessage({ message: 'What is my name?' });
console.log(response.text);
Ręczne zarządzanie historią
import { GoogleGenAI } from '@google/genai';
const client = new GoogleGenAI({});
const response = await client.models.generateContent({
model: 'gemini-2.5-flash-lite',
contents: [
{ role: 'user', parts: [{ text: 'Hi, my name is Phil.' }] },
{ role: 'model', parts: [{ text: 'Hi Phil, how can I help you?' }] },
{ role: 'user', parts: [{ text: 'What is my name?' }] }
]
});
console.log(response.text);
Java
import com.google.genai.Chat;
import com.google.genai.Client;
import com.google.genai.types.Content;
import com.google.genai.types.GenerateContentResponse;
import com.google.genai.types.Part;
import java.util.Arrays;
Client client = new Client();
// Using the chat helper (recommended)
Chat chat = client.chats.create("gemini-2.5-flash-lite");
GenerateContentResponse response1 = chat.sendMessage("Hi, my name is Phil.");
System.out.println(response1.text());
GenerateContentResponse response2 = chat.sendMessage("What is my name?");
System.out.println(response2.text());
// Manually managing history
GenerateContentResponse manualResponse =
client.models.generateContent(
"gemini-2.5-flash-lite",
Arrays.asList(
Content.builder()
.role("user")
.parts(Arrays.asList(Part.fromText("Hi, my name is Phil.")))
.build(),
Content.builder()
.role("model")
.parts(Arrays.asList(Part.fromText("Hi Phil, how can I help you?")))
.build(),
Content.builder()
.role("user")
.parts(Arrays.asList(Part.fromText("What is my name?")))
.build()),
null);
System.out.println(manualResponse.text());
Go
package main
import (
"context"
"fmt"
"log"
"google.golang.org/genai"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
// Using the chat helper (recommended)
chat, err := client.Chats.Create(ctx, "gemini-2.5-flash-lite", nil, nil)
if err != nil {
log.Fatal(err)
}
response1, err := chat.SendMessage(ctx, genai.Part{Text: "Hi, my name is Phil."})
if err != nil {
log.Fatal(err)
}
fmt.Println(response1.Text())
response2, err := chat.SendMessage(ctx, genai.Part{Text: "What is my name?"})
if err != nil {
log.Fatal(err)
}
fmt.Println(response2.Text())
// Manually managing history
history := []*genai.Content{
genai.NewContentFromText("Hi, my name is Phil.", genai.RoleUser),
genai.NewContentFromText("Hi Phil, how can I help you?", genai.RoleModel),
genai.NewContentFromText("What is my name?", genai.RoleUser),
}
manualResponse, err := client.Models.GenerateContent(ctx, "gemini-2.5-flash-lite", history, nil)
if err != nil {
log.Fatal(err)
}
fmt.Println(manualResponse.Text())
}
REST
# Request (the second turn requires sending the entire history)
curl -X POST "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-lite:generateContent" \
-H "Content-Type: application/json" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-d '{
"contents": [
{"role": "user", "parts": [{"text": "Hi, my name is Phil."}]},
{"role": "model", "parts": [{"text": "Hi Phil, how can I help you?"}]},
{"role": "user", "parts": [{"text": "What is my name?"}]}
]
}'
# Response
{
"candidates": [
{
"content": {
"parts": [
{
"text": "Your name is Phil."
}
],
"role": "model"
},
"finishReason": "STOP",
"index": 0
}
]
}
Po (Interactions API)
Interactions API zarządza stanem na serwerze. Kontynuujesz rozmowę, odwołując się do previous_interaction_id.
Python
from google import genai
client = genai.Client()
interaction1 = client.interactions.create(
model="gemini-3.8-flash", input="Hi, my name is Phil."
)
print("Response 1:", interaction1.output_text)
interaction2 = client.interactions.create(
model="gemini-3.8-flash",
previous_interaction_id=interaction1.id,
input="What is my name?",
)
print("Response 2:", interaction2.output_text)
JavaScript
import { GoogleGenAI } from '@google/genai';
const client = new GoogleGenAI({});
let interaction = await client.interactions.create({
model: 'gemini-3.8-flash',
input: 'Hi, my name is Phil.'
});
console.log("Response 1:", interaction.output_text);
interaction = await client.interactions.create({
model: 'gemini-3.8-flash',
previous_interaction_id: interaction.id,
input: 'What is my name?'
});
console.log("Response 2:", interaction.output_text);
Java
import com.google.genai.Client;
import com.google.genai.gaos.models.interactions.CreateModelInteraction;
import com.google.genai.gaos.models.interactions.Interaction;
import com.google.genai.gaos.models.interactions.InteractionsInput;
import com.google.genai.gaos.models.interactions.Model;
import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;
Client client = new Client();
CreateModelInteraction req1 =
CreateModelInteraction.builder()
.model(Model.of("gemini-3.8-flash"))
.input(InteractionsInput.of("Hi, my name is Phil."))
.build();
Interaction interaction1 =
client.interactions.create(CreateInteractionRequestBody.of(req1)).interaction().get();
System.out.println("Response 1: " + interaction1.outputText().orElse(""));
CreateModelInteraction req2 =
CreateModelInteraction.builder()
.model(Model.of("gemini-3.8-flash"))
.previousInteractionId(interaction1.id().orElse(""))
.input(InteractionsInput.of("What is my name?"))
.build();
Interaction interaction2 =
client.interactions.create(CreateInteractionRequestBody.of(req2)).interaction().get();
System.out.println("Response 2: " + interaction2.outputText().orElse(""));
Go
package main
import (
"context"
"fmt"
"log"
"google.golang.org/genai"
"google.golang.org/genai/interactions/models/interactions"
"google.golang.org/genai/interactions/models/operations"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
res1, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{
Model: interactions.Model("gemini-3.8-flash"),
Input: interactions.NewInteractionsInput("Hi, my name is Phil."),
}),
})
if err != nil {
log.Fatal(err)
}
if res1.Interaction.OutputText != nil {
fmt.Println("Response 1:", *res1.Interaction.OutputText)
}
res2, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{
Model: interactions.Model("gemini-3.8-flash"),
PreviousInteractionID: res1.Interaction.ID,
Input: interactions.NewInteractionsInput("What is my name?"),
}),
})
if err != nil {
log.Fatal(err)
}
if res2.Interaction.OutputText != nil {
fmt.Println("Response 2:", *res2.Interaction.OutputText)
}
}
REST
# First Request
curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "Content-Type: application/json" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-d '{
"model": "gemini-3.8-flash",
"input": "Hi, my name is Phil."
}'
# Second Request (using ID from first response)
curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "Content-Type: application/json" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-d '{
"model": "gemini-3.8-flash",
"previous_interaction_id": "int_123",
"input": "What is my name?"
}'
# Response to Second Request
{
"id": "int_123",
"steps": [
{
"type": "user_input",
"status": "done",
"content": [{ "type": "text", "text": "Hi, my name is Phil." }]
},
{
"type": "model_output",
"status": "done",
"content": [{ "type": "text", "text": "Hello Phil! How can I help you today?" }]
},
{
"type": "user_input",
"status": "done",
"content": [{ "type": "text", "text": "What is my name?" }]
},
{
"type": "model_output",
"status": "done",
"content": [{ "type": "text", "text": "Your name is Phil." }]
}
]
}
Dane wejściowe multimodalne
Oba interfejsy API obsługują dane wejściowe w różnych formatach (tekst, obrazy, filmy itp.).
Przed (generateContent)
W generateContent przekazujesz listę parts w tablicy contents. Odpowiedź zwraca dane wyjściowe w polu parts pierwszego kandydata.
Python
from google import genai
from google.genai import types
client = genai.Client()
with open("sample.jpg", "rb") as f:
image_bytes = f.read()
response = client.models.generate_content(
model="gemini-2.5-flash-lite",
contents=[
types.Part.from_bytes(data=image_bytes, mime_type="image/jpeg"),
"Describe this image.",
],
)
print(response.text)
JavaScript
import { GoogleGenAI } from '@google/genai';
import * as fs from 'fs';
const client = new GoogleGenAI({});
const imageBytes = fs.readFileSync('sample.jpg').toString('base64');
const response = await client.models.generateContent({
model: 'gemini-2.5-flash-lite',
contents: [
{
inlineData: {
data: imageBytes,
mimeType: 'image/jpeg',
},
},
'Describe this image.',
],
});
console.log(response.text);
Java
import com.google.genai.Client;
import com.google.genai.types.Content;
import com.google.genai.types.GenerateContentResponse;
import com.google.genai.types.Part;
import java.nio.file.Files;
import java.nio.file.Paths;
Client client = new Client();
byte[] imageBytes = Files.readAllBytes(Paths.get("sample.jpg"));
GenerateContentResponse response =
client.models.generateContent(
"gemini-2.5-flash-lite",
Content.fromParts(
Part.fromBytes(imageBytes, "image/jpeg"), Part.fromText("Describe this image.")),
null);
System.out.println(response.text());
Go
package main
import (
"context"
"fmt"
"log"
"os"
"google.golang.org/genai"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
imageBytes, err := os.ReadFile("sample.jpg")
if err != nil {
log.Fatal(err)
}
contents := []*genai.Content{
genai.NewContentFromParts([]*genai.Part{
genai.NewPartFromBytes(imageBytes, "image/jpeg"),
genai.NewPartFromText("Describe this image."),
}, genai.RoleUser),
}
response, err := client.Models.GenerateContent(ctx, "gemini-2.5-flash-lite", contents, nil)
if err != nil {
log.Fatal(err)
}
fmt.Println(response.Text())
}
REST
# Request
curl -X POST "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-lite:generateContent" \
-H "Content-Type: application/json" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-d '{
"contents": [{
"parts": [
{
"inlineData": {
"mimeType": "image/jpeg",
"data": "..."
}
},
{
"text": "Describe this image."
}
]
}]
}'
# Response
{
"candidates": [
{
"content": {
"parts": [
{
"text": "This is a picture of a beautiful sunset."
}
],
"role": "model"
}
}
]
}
Po (Interactions API)
W interfejsie Interactions API przekazujesz tablicę do pola input. Aby pobrać wygenerowane treści, znajdź krok model_output na osi czasu.
Python
import base64
from google import genai
client = genai.Client()
with open("sample.jpg", "rb") as f:
image_bytes = f.read()
image_b64 = base64.b64encode(image_bytes).decode("utf-8")
interaction = client.interactions.create(
model="gemini-3.8-flash",
input=[
{
"type": "image",
"mime_type": "image/jpeg",
"data": image_b64,
},
{"type": "text", "text": "Describe this image."},
],
)
print(interaction.output_text)
JavaScript
import { GoogleGenAI } from '@google/genai';
import * as fs from 'fs';
const client = new GoogleGenAI({});
const imageBytes = fs.readFileSync('sample.jpg').toString('base64');
const interaction = await client.interactions.create({
model: 'gemini-3.8-flash',
input: [
{
type: 'image',
mime_type: 'image/jpeg',
data: imageBytes
},
{
type: 'text',
text: 'Describe this image.'
}
]
});
console.log(interaction.output_text);
Java
import com.google.genai.Client;
import com.google.genai.gaos.models.interactions.CreateModelInteraction;
import com.google.genai.gaos.models.interactions.ImageContent;
import com.google.genai.gaos.models.interactions.ImageContentMimeType;
import com.google.genai.gaos.models.interactions.Interaction;
import com.google.genai.gaos.models.interactions.InteractionsInput;
import com.google.genai.gaos.models.interactions.Model;
import com.google.genai.gaos.models.interactions.TextContent;
import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Base64;
Client client = new Client();
byte[] imageBytes = Files.readAllBytes(Paths.get("sample.jpg"));
String base64ImageData = Base64.getEncoder().encodeToString(imageBytes);
CreateModelInteraction request =
CreateModelInteraction.builder()
.model(Model.of("gemini-3.8-flash"))
.input(
InteractionsInput.ofContent(
Arrays.asList(
ImageContent.builder()
.mimeType(ImageContentMimeType.IMAGE_JPEG)
.data(base64ImageData)
.build(),
TextContent.builder().text("Describe this image.").build())))
.build();
Interaction interaction =
client.interactions.create(CreateInteractionRequestBody.of(request)).interaction().get();
System.out.println(interaction.outputText().orElse(""));
Go
package main
import (
"context"
"encoding/base64"
"fmt"
"log"
"os"
"google.golang.org/genai"
"google.golang.org/genai/interactions/models/interactions"
"google.golang.org/genai/interactions/models/operations"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
imageBytes, err := os.ReadFile("sample.jpg")
if err != nil {
log.Fatal(err)
}
base64ImageData := base64.StdEncoding.EncodeToString(imageBytes)
res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{
Model: interactions.Model("gemini-3.8-flash"),
Input: interactions.NewInteractionsInput([]interactions.Content{
interactions.NewContent(interactions.ImageContent{
MimeType: interactions.ImageContentMimeType("image/jpeg").ToPointer(),
Data: genai.Ptr(base64ImageData),
}),
interactions.NewContent(interactions.TextContent{
Text: "Describe this image.",
}),
}),
}),
})
if err != nil {
log.Fatal(err)
}
if res.Interaction.OutputText != nil {
fmt.Println(*res.Interaction.OutputText)
}
}
REST
# Request
curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "Content-Type: application/json" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-d '{
"model": "gemini-3.8-flash",
"input": [
{
"type": "image",
"mime_type": "image/jpeg",
"data": "..."
},
{
"type": "text",
"text": "Describe this image."
}
]
}'
# Response
{
"id": "int_multimodal",
"steps": [
{
"type": "user_input",
"status": "done",
"content": [
{
"type": "image",
"mime_type": "image/jpeg",
"data": "..."
},
{
"type": "text",
"text": "Describe this image."
}
]
},
{
"type": "model_output",
"status": "done",
"content": [
{
"type": "text",
"text": "This is a picture of a beautiful sunset over the mountains."
}
]
}
]
}
Uporządkowane dane wyjściowe
Aby model zwracał dane JSON zgodne z określonym schematem, skonfiguruj format odpowiedzi.
Przed (generateContent)
W generateContent format wyjściowy konfigurujesz za pomocą pól response_mime_type i response_schema zagnieżdżonych w obiekcie config (lub generationConfig).
Python
from google import genai
from google.genai import types
from pydantic import BaseModel
client = genai.Client()
class Recipe(BaseModel):
recipe_name: str
ingredients: list[str]
response = client.models.generate_content(
model="gemini-2.5-flash-lite",
contents="Give me a recipe for chocolate chip cookies.",
config=types.GenerateContentConfig(
response_mime_type="application/json",
response_schema=Recipe,
),
)
print(response.text)
JavaScript
import { GoogleGenAI, Type } from '@google/genai';
const ai = new GoogleGenAI({});
const response = await ai.models.generateContent({
model: 'gemini-2.5-flash-lite',
contents: 'Give me a recipe for chocolate chip cookies.',
config: {
responseMimeType: 'application/json',
responseSchema: {
type: Type.OBJECT,
properties: {
recipe_name: { type: Type.STRING },
ingredients: {
type: Type.ARRAY,
items: { type: Type.STRING },
},
},
required: ['recipe_name', 'ingredients'],
},
},
});
console.log(response.text);
Java
import com.google.genai.Client;
import com.google.genai.types.GenerateContentConfig;
import com.google.genai.types.GenerateContentResponse;
import com.google.genai.types.Schema;
import com.google.genai.types.Type;
import java.util.Arrays;
import java.util.Map;
Client client = new Client();
Schema recipeSchema =
Schema.builder()
.type(Type.Known.OBJECT)
.properties(
Map.of(
"recipe_name", Schema.builder().type(Type.Known.STRING).build(),
"ingredients",
Schema.builder()
.type(Type.Known.ARRAY)
.items(Schema.builder().type(Type.Known.STRING).build())
.build()))
.required(Arrays.asList("recipe_name", "ingredients"))
.build();
GenerateContentResponse response =
client.models.generateContent(
"gemini-2.5-flash-lite",
"Give me a recipe for chocolate chip cookies.",
GenerateContentConfig.builder()
.responseMimeType("application/json")
.responseSchema(recipeSchema)
.build());
System.out.println(response.text());
Go
package main
import (
"context"
"fmt"
"log"
"google.golang.org/genai"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
recipeSchema := &genai.Schema{
Type: genai.TypeObject,
Properties: map[string]*genai.Schema{
"recipe_name": {Type: genai.TypeString},
"ingredients": {
Type: genai.TypeArray,
Items: &genai.Schema{Type: genai.TypeString},
},
},
Required: []string{"recipe_name", "ingredients"},
}
response, err := client.Models.GenerateContent(
ctx,
"gemini-2.5-flash-lite",
genai.Text("Give me a recipe for chocolate chip cookies."),
&genai.GenerateContentConfig{
ResponseMIMEType: "application/json",
ResponseSchema: recipeSchema,
},
)
if err != nil {
log.Fatal(err)
}
fmt.Println(response.Text())
}
REST
# Request
curl -X POST "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-lite:generateContent" \
-H "Content-Type: application/json" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-d '{
"contents": [{
"parts": [{
"text": "Give me a recipe for chocolate chip cookies."
}]
}],
"generationConfig": {
"responseMimeType": "application/json",
"responseSchema": {
"type": "OBJECT",
"properties": {
"recipe_name": { "type": "STRING" },
"ingredients": {
"type": "ARRAY",
"items": { "type": "STRING" }
}
},
"required": ["recipe_name", "ingredients"]
}
}
}'
# Response
{
"candidates": [
{
"content": {
"parts": [
{
"text": "{\n \"recipe_name\": \"Chocolate Chip Cookies\",\n \"ingredients\": [\n \"1 cup butter\",\n \"1 cup sugar\",\n \"2 cups flour\",\n \"1 cup chocolate chips\"\n ]\n}"
}
],
"role": "model"
}
}
]
}
Po (Interactions API)
W interfejsie Interactions API ustawienia formatu wyjściowego zostały przeniesione do pola response_format najwyższego poziomu. Przekaż pojedynczy obiekt formatu lub tablicę obiektów formatu, jeśli żądasz więcej niż 1 typu danych wyjściowych.
Python
from google import genai
from pydantic import BaseModel
client = genai.Client()
class Recipe(BaseModel):
recipe_name: str
ingredients: list[str]
interaction = client.interactions.create(
model="gemini-3.8-flash",
input="Give me a recipe for chocolate chip cookies.",
response_format={
"type": "text",
"mime_type": "application/json",
"schema": Recipe.model_json_schema(),
},
)
print(interaction.output_text)
JavaScript
import { GoogleGenAI } from '@google/genai';
const client = new GoogleGenAI({});
const interaction = await client.interactions.create({
model: 'gemini-3.8-flash',
input: 'Give me a recipe for chocolate chip cookies.',
response_format: {
type: 'text',
mime_type: 'application/json',
schema: {
type: 'object',
properties: {
recipe_name: { type: 'string' },
ingredients: {
type: 'array',
items: { type: 'string' }
}
},
required: ['recipe_name', 'ingredients']
}
}
});
console.log(interaction.output_text);
Java
import com.google.genai.Client;
import com.google.genai.gaos.models.interactions.CreateModelInteraction;
import com.google.genai.gaos.models.interactions.CreateModelInteractionResponseFormat;
import com.google.genai.gaos.models.interactions.Interaction;
import com.google.genai.gaos.models.interactions.InteractionsInput;
import com.google.genai.gaos.models.interactions.Model;
import com.google.genai.gaos.models.interactions.ResponseFormat;
import com.google.genai.gaos.models.interactions.TextResponseFormat;
import com.google.genai.gaos.models.interactions.TextResponseFormatMimeType;
import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
Client client = new Client();
Map<String, Object> properties = new HashMap<>();
properties.put("recipe_name", Map.of("type", "string"));
properties.put("ingredients", Map.of("type", "array", "items", Map.of("type", "string")));
Map<String, Object> schema = new HashMap<>();
schema.put("type", "object");
schema.put("properties", properties);
schema.put("required", Arrays.asList("recipe_name", "ingredients"));
CreateModelInteraction request =
CreateModelInteraction.builder()
.model(Model.of("gemini-3.8-flash"))
.input(InteractionsInput.of("Give me a recipe for chocolate chip cookies."))
.responseFormat(
CreateModelInteractionResponseFormat.of(
ResponseFormat.of(
TextResponseFormat.builder()
.mimeType(TextResponseFormatMimeType.APPLICATION_JSON)
.schema(schema)
.build())))
.build();
Interaction interaction =
client.interactions.create(CreateInteractionRequestBody.of(request)).interaction().get();
System.out.println(interaction.outputText().orElse(""));
Go
package main
import (
"context"
"fmt"
"log"
"google.golang.org/genai"
"google.golang.org/genai/interactions/models/interactions"
"google.golang.org/genai/interactions/models/operations"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
schema := map[string]any{
"type": "object",
"properties": map[string]any{
"recipe_name": map[string]any{"type": "string"},
"ingredients": map[string]any{
"type": "array",
"items": map[string]any{"type": "string"},
},
},
"required": []string{"recipe_name", "ingredients"},
}
res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{
Model: interactions.Model("gemini-3.8-flash"),
Input: interactions.NewInteractionsInput("Give me a recipe for chocolate chip cookies."),
ResponseFormat: genai.Ptr(interactions.NewCreateModelInteractionResponseFormat(
interactions.NewResponseFormat(interactions.TextResponseFormat{
MimeType: interactions.TextResponseFormatMimeType("application/json").ToPointer(),
Schema: schema,
}),
)),
}),
})
if err != nil {
log.Fatal(err)
}
if res.Interaction.OutputText != nil {
fmt.Println(*res.Interaction.OutputText)
}
}
REST
# Request
curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "Content-Type: application/json" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-d '{
"model": "gemini-3.8-flash",
"input": "Give me a recipe for chocolate chip cookies.",
"response_format": {
"type": "text",
"mime_type": "application/json",
"schema": {
"type": "object",
"properties": {
"recipe_name": { "type": "string" },
"ingredients": {
"type": "array",
"items": { "type": "string" }
}
},
"required": ["recipe_name", "ingredients"]
}
}
}'
# Response
{
"id": "int_structured",
"steps": [
{
"type": "user_input",
"status": "done",
"content": [{ "type": "text", "text": "Give me a recipe for chocolate chip cookies." }]
},
{
"type": "model_output",
"status": "done",
"content": [
{
"type": "text",
"text": "{\n \"recipe_name\": \"Chocolate Chip Cookies\",\n \"ingredients\": [\n \"1 cup butter\",\n \"1 cup sugar\",\n \"2 cups flour\",\n \"1 cup chocolate chips\"\n ]\n}"
}
]
}
]
}
Generowanie multimodalne
Podczas generowania treści w modalnościach innych niż tekst (np. obrazów lub dźwięku) główną różnicą jest sposób, w jaki odpowiedź strukturyzuje wygenerowane multimedia.
Przed (generateContent)
W generateContent odpowiedź zwraca wygenerowane multimedia bezpośrednio w parts kandydata, zwykle jako dane base64 w inlineData.
# Response structure concept
{
"candidates": [
{
"content": {
"parts": [
{
"text": "Here is your generated image:"
},
{
"inlineData": {
"mimeType": "image/jpeg",
"data": "...base64..."
}
}
]
}
}
]
}
Po (Interactions API)
W interfejsie Interactions API multimedia wygenerowane przez AI są wyświetlane jako osobne elementy w tablicy content kroku model_output na osi czasu, co pozwala zachować chronologiczny przebieg interakcji.
# Response structure concept
{
"id": "int_123",
"steps": [
{
"type": "model_output",
"status": "done",
"content": [
{
"type": "text",
"text": "Here is your generated image:"
},
{
"type": "image",
"mime_type": "image/jpeg",
"data": "...base64..." // Or a reference URL in future
}
]
}
]
}
Dzięki temu analiza odpowiedzi jest spójna ze sposobem obsługi danych wejściowych i wyjściowych – wszystko jest krokiem na osi czasu.
Narzędzia po stronie serwera
Gemini obsługuje wbudowane narzędzia po stronie serwera, takie jak wyszukiwarka Google. Główna różnica polega na tym, jak odpowiedź reprezentuje wykonanie narzędzia.
Przed (generateContent)
W generateContent narzędzia po stronie serwera są w dużej mierze nieprzejrzyste. Włączasz narzędzie i otrzymujesz ostateczną odpowiedź z osobnym obiektem groundingMetadata. Co ważne, cytaty nie są wstawiane w tekście. groundingSupports używa indeksów znaków, aby mapować segmenty tekstu z powrotem na źródła internetowe w groundingChunks.
Python
from google import genai
from google.genai import types
client = genai.Client()
response = client.models.generate_content(
model="gemini-2.5-flash-lite",
contents="Who won Euro 2024?",
config=types.GenerateContentConfig(
tools=[{"google_search": {}}]
),
)
metadata = response.candidates[0].grounding_metadata
if metadata.search_entry_point:
print(f"Search Entry Point: {metadata.search_entry_point.rendered_content}")
for support in metadata.grounding_supports:
print(f"Citation: {support.segment.text}")
JavaScript
import { GoogleGenAI } from '@google/genai';
const client = new GoogleGenAI({});
const response = await client.models.generateContent({
model: 'gemini-2.5-flash-lite',
contents: 'Who won Euro 2024?',
config: {
tools: [{ google_search: {} }]
}
});
const metadata = response.candidates[0].groundingMetadata;
if (metadata.searchEntryPoint) {
console.log(`Search Entry Point: ${metadata.searchEntryPoint.renderedContent}`);
}
for (const support of metadata.groundingSupports) {
console.log(`Citation: ${support.segment.text}`);
}
Java
import com.google.genai.Client;
import com.google.genai.types.Candidate;
import com.google.genai.types.GenerateContentConfig;
import com.google.genai.types.GenerateContentResponse;
import com.google.genai.types.GoogleSearch;
import com.google.genai.types.GroundingMetadata;
import com.google.genai.types.GroundingSupport;
import com.google.genai.types.Tool;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
Client client = new Client();
GenerateContentResponse response =
client.models.generateContent(
"gemini-2.5-flash-lite",
"Who won Euro 2024?",
GenerateContentConfig.builder()
.tools(
Arrays.asList(
Tool.builder().googleSearch(GoogleSearch.builder().build()).build()))
.build());
List<Candidate> candidates = response.candidates().orElse(Collections.emptyList());
if (!candidates.isEmpty() && candidates.get(0).groundingMetadata().isPresent()) {
GroundingMetadata metadata = candidates.get(0).groundingMetadata().get();
if (metadata.searchEntryPoint().isPresent()) {
System.out.println(
"Search Entry Point: " + metadata.searchEntryPoint().get().renderedContent().orElse(""));
}
for (GroundingSupport support : metadata.groundingSupports().orElse(Collections.emptyList())) {
Optional<String> segmentText = support.segment().flatMap(s -> s.text());
segmentText.ifPresent(text -> System.out.println("Citation: " + text));
}
}
Go
package main
import (
"context"
"fmt"
"log"
"google.golang.org/genai"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
response, err := client.Models.GenerateContent(
ctx,
"gemini-2.5-flash-lite",
genai.Text("Who won Euro 2024?"),
&genai.GenerateContentConfig{
Tools: []*genai.Tool{
{GoogleSearch: &genai.GoogleSearch{}},
},
},
)
if err != nil {
log.Fatal(err)
}
if len(response.Candidates) > 0 && response.Candidates[0].GroundingMetadata != nil {
metadata := response.Candidates[0].GroundingMetadata
if metadata.SearchEntryPoint != nil {
fmt.Println("Search Entry Point:", metadata.SearchEntryPoint.RenderedContent)
}
for _, support := range metadata.GroundingSupports {
if support.Segment != nil {
fmt.Println("Citation:", support.Segment.Text)
}
}
}
}
REST
# Request
curl -X POST "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-lite:generateContent" \
-H "Content-Type: application/json" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-d '{
"contents": [{
"parts": [{
"text": "Who won Euro 2024?"
}]
}],
"tools": [{
"googleSearchRetrieval": {}
}]
}'
# Response
{
"candidates": [
{
"content": {
"parts": [
{
"text": "Spain won Euro 2024, defeating England 2-1 in the final. This victory marks Spain's record fourth European Championship title."
}
],
"role": "model"
},
"groundingMetadata": {
"webSearchQueries": [
"UEFA Euro 2024 winner",
"who won euro 2024"
],
"searchEntryPoint": {
"renderedContent": "<!-- HTML and CSS for the search widget -->"
},
"groundingChunks": [
{"web": {"uri": "https://vertexaisearch.cloud.google.com.....", "title": "aljazeera.com"}},
{"web": {"uri": "https://vertexaisearch.cloud.google.com.....", "title": "uefa.com"}}
],
"groundingSupports": [
{
"segment": {"startIndex": 0, "endIndex": 85, "text": "Spain won Euro 2024, defeatin..."},
"groundingChunkIndices": [0]
},
{
"segment": {"startIndex": 86, "endIndex": 210, "text": "This victory marks Spain's..."},
"groundingChunkIndices": [0, 1]
}
]
}
}
]
}
Po (Interactions API)
W Interactions API narzędzia po stronie serwera zapewniają pełną przejrzystość osi czasu. Interfejs API rejestruje wywołanie i wynik jako odrębne wykonanie steps (google_search_call i google_search_result), pokazując dokładnie, jakie dane pobrał model.
Ponadto interfejs API zwraca cytaty w tekście. Zamiast mapować indeksy z osobnego obiektu metadanych, element tekstowy w kroku model_output zawiera własną tablicę annotations, która prowadzi bezpośrednio do źródła.
Python
from google import genai
client = genai.Client()
interaction = client.interactions.create(
model="gemini-3.8-flash",
input="Who won Euro 2024?",
tools=[{"type": "google_search"}],
)
for step in interaction.steps:
if step.type == "google_search_result":
print(f"Search Suggestions: {step.result[0].search_suggestions}")
elif step.type == "model_output":
print(f"Answer: {step.content[0].text}")
if step.content[0].annotations:
for anno in step.content[0].annotations:
print(f"Citation: {anno.title} ({anno.uri})")
JavaScript
import { GoogleGenAI } from '@google/genai';
const client = new GoogleGenAI({});
const interaction = await client.interactions.create({
model: 'gemini-3.8-flash',
input: 'Who won Euro 2024?',
tools: [{ type: 'google_search' }]
});
for (const step of interaction.steps) {
if (step.type === 'google_search_result') {
console.log(`Search Suggestions: ${step.result[0].search_suggestions}`);
} else if (step.type === 'model_output') {
console.log(`Answer: ${step.content[0].text}`);
if (step.content[0].annotations) {
for (const anno of step.content[0].annotations) {
console.log(`Citation: ${anno.title} (${anno.uri})`);
}
}
}
}
Java
import com.google.genai.Client;
import com.google.genai.gaos.models.interactions.Annotation;
import com.google.genai.gaos.models.interactions.Content;
import com.google.genai.gaos.models.interactions.CreateModelInteraction;
import com.google.genai.gaos.models.interactions.GoogleSearch;
import com.google.genai.gaos.models.interactions.GoogleSearchResult;
import com.google.genai.gaos.models.interactions.GoogleSearchResultStep;
import com.google.genai.gaos.models.interactions.Interaction;
import com.google.genai.gaos.models.interactions.InteractionsInput;
import com.google.genai.gaos.models.interactions.Model;
import com.google.genai.gaos.models.interactions.ModelOutputStep;
import com.google.genai.gaos.models.interactions.Step;
import com.google.genai.gaos.models.interactions.TextContent;
import com.google.genai.gaos.models.interactions.URLCitation;
import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;
import java.util.Arrays;
import java.util.Collections;
Client client = new Client();
CreateModelInteraction request =
CreateModelInteraction.builder()
.model(Model.of("gemini-3.8-flash"))
.input(InteractionsInput.of("Who won Euro 2024?"))
.tools(Arrays.asList(GoogleSearch.builder().build()))
.build();
Interaction interaction =
client.interactions.create(CreateInteractionRequestBody.of(request)).interaction().get();
for (Step step : interaction.steps().orElse(Collections.emptyList())) {
if (step instanceof GoogleSearchResultStep) {
GoogleSearchResultStep searchStep = (GoogleSearchResultStep) step;
for (GoogleSearchResult res : searchStep.result().orElse(Collections.emptyList())) {
System.out.println("Search Suggestions: " + res.searchSuggestions().orElse(""));
}
} else if (step instanceof ModelOutputStep) {
ModelOutputStep modelOutput = (ModelOutputStep) step;
for (Content contentBlock : modelOutput.content().orElse(Collections.emptyList())) {
if (contentBlock instanceof TextContent) {
TextContent textContent = (TextContent) contentBlock;
System.out.println("Answer: " + textContent.text().orElse(""));
for (Annotation anno : textContent.annotations().orElse(Collections.emptyList())) {
if (anno instanceof URLCitation) {
URLCitation cit = (URLCitation) anno;
System.out.println(
"Citation: " + cit.title().orElse("") + " (" + cit.url().orElse("") + ")");
}
}
}
}
}
}
Go
package main
import (
"context"
"fmt"
"log"
"google.golang.org/genai"
"google.golang.org/genai/interactions/models/interactions"
"google.golang.org/genai/interactions/models/operations"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{
Model: interactions.Model("gemini-3.8-flash"),
Input: interactions.NewInteractionsInput("Who won Euro 2024?"),
Tools: []interactions.Tool{
interactions.NewTool(interactions.GoogleSearch{}),
},
}),
})
if err != nil {
log.Fatal(err)
}
for _, step := range res.Interaction.Steps {
if searchStep := step.GoogleSearchResultStep; searchStep != nil {
for _, r := range searchStep.Result {
if r.SearchSuggestions != nil {
fmt.Println("Search Suggestions:", *r.SearchSuggestions)
}
}
} else if modelOutput := step.ModelOutputStep; modelOutput != nil {
for _, contentBlock := range modelOutput.Content {
if textContent := contentBlock.TextContent; textContent != nil {
fmt.Println("Answer:", textContent.Text)
for _, anno := range textContent.Annotations {
if cit := anno.URLCitation; cit != nil {
fmt.Printf("Citation: %s (%s)\n", cit.GetTitle(), cit.GetURL())
}
}
}
}
}
}
}
REST
# Request
curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "Content-Type: application/json" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-d '{
"model": "gemini-3.8-flash",
"input": "Who won Euro 2024?",
"tools": [{"type": "google_search"}]
}'
# Response (showing grounding)
{
"id": "int_grounded",
"steps": [
{
"type": "user_input",
"status": "done",
"content": [{ "type": "text", "text": "Who won Euro 2024?" }]
},
{
"type": "google_search_call",
"status": "done",
"content": [{ "type": "text", "text": "UEFA Euro 2024 winner" }]
},
{
"type": "google_search_result",
"status": "done",
"content": [
{
"type": "text",
"text": "Spain won Euro 2024..."
}
]
},
{
"type": "model_output",
"status": "done",
"content": [
{
"type": "text",
"text": "Spain won Euro 2024, defeating England 2-1.",
"annotations": [
{
"start_index": 0,
"end_index": 42,
"uri": "https://vertexaisearch...",
"title": "aljazeera.com"
}
]
}
]
}
]
}
Wywoływanie funkcji
Struktura wywołań funkcji i wyników również została zmieniona, aby pasowała do schematu Steps.
Przed (generateContent)
W generateContent odpowiedź zwraca wywołania funkcji w ramach kandydatów*. {Python}
```python
from google import genai
from google.genai import types
client = genai.Client()
response = client.models.generate_content(
model="gemini-2.5-flash-lite",
contents="What's the weather in Boston?",
config=types.GenerateContentConfig(tools=[weather_tool]),
)
function_call = response.candidates[0].content.parts[0].function_call
print(f"Requested tool: {function_call.name}")
result = "52°F and rain"
response = client.models.generate_content(
model="gemini-2.5-flash-lite",
contents=[
types.Content(
role="user",
parts=[
types.Part.from_text(text="What's the weather in Boston?")
],
),
response.candidates[0].content,
types.Content(
role="user",
parts=[
types.Part.from_function_response(
name=function_call.name,
response={"result": result},
)
],
),
],
config=types.GenerateContentConfig(tools=[weather_tool]),
)
print(response.text)
```
JavaScript
import { GoogleGenAI } from '@google/genai';
const client = new GoogleGenAI({});
let response = await client.models.generateContent({
model: 'gemini-2.5-flash-lite',
contents: "What's the weather in Boston?",
config: { tools: [weatherTool] }
});
const functionCall = response.candidates[0].content.parts[0].functionCall;
console.log(`Requested tool: ${functionCall.name}`);
const result = "52°F and rain";
response = await client.models.generateContent({
model: 'gemini-2.5-flash-lite',
contents: [
{ role: 'user', parts: [{ text: "What's the weather in Boston?" }] },
response.candidates[0].content,
{
role: 'user',
parts: [{
functionResponse: {
name: functionCall.name,
response: { result: result }
}
}]
}
],
config: { tools: [weatherTool] }
});
console.log(response.text);
Java
import com.google.genai.Client;
import com.google.genai.types.Content;
import com.google.genai.types.FunctionCall;
import com.google.genai.types.FunctionDeclaration;
import com.google.genai.types.GenerateContentConfig;
import com.google.genai.types.GenerateContentResponse;
import com.google.genai.types.Part;
import com.google.genai.types.Schema;
import com.google.genai.types.Tool;
import com.google.genai.types.Type;
import java.util.Arrays;
import java.util.Map;
Client client = new Client();
FunctionDeclaration weatherFunc =
FunctionDeclaration.builder()
.name("get_weather")
.description("Gets weather")
.parameters(
Schema.builder()
.type(Type.Known.OBJECT)
.properties(Map.of("location", Schema.builder().type(Type.Known.STRING).build()))
.build())
.build();
Tool weatherTool = Tool.builder().functionDeclarations(Arrays.asList(weatherFunc)).build();
GenerateContentResponse response =
client.models.generateContent(
"gemini-2.5-flash-lite",
"What's the weather in Boston?",
GenerateContentConfig.builder().tools(Arrays.asList(weatherTool)).build());
FunctionCall functionCall = response.functionCalls().get(0);
System.out.println("Requested tool: " + functionCall.name().orElse(""));
String result = "52°F and rain";
GenerateContentResponse finalResponse =
client.models.generateContent(
"gemini-2.5-flash-lite",
Arrays.asList(
Content.builder()
.role("user")
.parts(Arrays.asList(Part.fromText("What's the weather in Boston?")))
.build(),
response.candidates().get().get(0).content().get(),
Content.builder()
.role("user")
.parts(
Arrays.asList(
Part.fromFunctionResponse(
functionCall.name().orElse(""), Map.of("result", result))))
.build()),
GenerateContentConfig.builder().tools(Arrays.asList(weatherTool)).build());
System.out.println(finalResponse.text());
Go
package main
import (
"context"
"fmt"
"log"
"google.golang.org/genai"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
weatherTool := &genai.Tool{
FunctionDeclarations: []*genai.FunctionDeclaration{
{
Name: "get_weather",
Description: "Gets weather",
Parameters: &genai.Schema{
Type: genai.TypeObject,
Properties: map[string]*genai.Schema{
"location": {Type: genai.TypeString},
},
},
},
},
}
config := &genai.GenerateContentConfig{
Tools: []*genai.Tool{weatherTool},
}
response, err := client.Models.GenerateContent(
ctx,
"gemini-2.5-flash-lite",
genai.Text("What's the weather in Boston?"),
config,
)
if err != nil {
log.Fatal(err)
}
calls := response.FunctionCalls()
if len(calls) > 0 {
functionCall := calls[0]
fmt.Println("Requested tool:", functionCall.Name)
result := "52°F and rain"
history := []*genai.Content{
genai.NewContentFromText("What's the weather in Boston?", genai.RoleUser),
response.Candidates[0].Content,
genai.NewContentFromParts([]*genai.Part{
genai.NewPartFromFunctionResponse(functionCall.Name, map[string]any{"result": result}),
}, genai.RoleUser),
}
finalResponse, err := client.Models.GenerateContent(ctx, "gemini-2.5-flash-lite", history, config)
if err != nil {
log.Fatal(err)
}
fmt.Println(finalResponse.Text())
}
}
REST
# Request
curl -X POST "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-lite:generateContent" \
-H "Content-Type: application/json" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-d '{
"contents": [{
"parts": [{
"text": "What is the weather like in Boston, MA?"
}]
}],
"tools": [{
"functionDeclarations": [{
"name": "get_weather",
"description": "Get the current weather",
"parameters": {
"type": "OBJECT",
"properties": {
"location": {"type": "STRING"}
},
"required": ["location"]
}
}]
}]
}'
# Response
{
"candidates": [
{
"content": {
"parts": [
{
"functionCall": {
"name": "get_weather",
"args": { "location": "Boston, MA" }
}
}
],
"role": "model"
},
"finishReason": "STOP",
"index": 0
}
]
}
Po (Interactions API)
Wywołania narzędzi i wyniki są teraz osobnymi krokami na osi czasu.
Python
from google import genai
client = genai.Client()
weather_tool = {
"type": "function",
"name": "get_weather",
"description": "Gets weather",
"parameters": {
"type": "object",
"properties": {
"location": {"type": "string"}
},
},
}
interaction = client.interactions.create(
model="gemini-3.8-flash",
input="What's the weather in Boston?",
tools=[weather_tool],
)
for step in interaction.steps:
if step.type == "function_call":
print(f"Executing {step.name} for {step.arguments}")
result = "52°F and rain"
interaction = client.interactions.create(
model="gemini-3.8-flash",
previous_interaction_id=interaction.id,
input=[
{
"type": "function_result",
"call_id": step.id,
"name": step.name,
"result": [{"type": "text", "text": result}],
}
],
)
print(interaction.output_text)
JavaScript
import { GoogleGenAI } from '@google/genai';
const client = new GoogleGenAI({});
const weatherTool = {
type: "function",
name: "get_weather",
description: "Get weather for a location",
parameters: {
type: "object",
properties: {
location: { type: "string" }
},
required: ["location"]
}
};
const interaction = await client.interactions.create({
model: 'gemini-3.8-flash',
input: "What's the weather in Boston?",
tools: [weatherTool]
});
for (const step of interaction.steps) {
if (step.type === 'function_call') {
console.log(`Executing ${step.name} for ${JSON.stringify(step.arguments)}`);
const result = "52°F and rain";
const nextInteraction = await client.interactions.create({
model: 'gemini-3.8-flash',
previous_interaction_id: interaction.id,
input: [
{
type: 'function_result',
call_id: step.id,
name: step.name,
result: [{ type: 'text', text: result }]
}
]
});
console.log(nextInteraction.output_text);
}
}
Java
import com.google.genai.Client;
import com.google.genai.gaos.models.interactions.CreateModelInteraction;
import com.google.genai.gaos.models.interactions.Function;
import com.google.genai.gaos.models.interactions.FunctionCallStep;
import com.google.genai.gaos.models.interactions.FunctionResultStep;
import com.google.genai.gaos.models.interactions.FunctionResultStepResultUnion;
import com.google.genai.gaos.models.interactions.Interaction;
import com.google.genai.gaos.models.interactions.InteractionsInput;
import com.google.genai.gaos.models.interactions.Model;
import com.google.genai.gaos.models.interactions.Step;
import com.google.genai.gaos.models.interactions.TextContent;
import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
Client client = new Client();
Map<String, Object> properties = new HashMap<>();
properties.put("location", Map.of("type", "string"));
Map<String, Object> parameters = new HashMap<>();
parameters.put("type", "object");
parameters.put("properties", properties);
parameters.put("required", Arrays.asList("location"));
Function weatherTool =
Function.builder()
.name("get_weather")
.description("Gets weather")
.parameters(parameters)
.build();
CreateModelInteraction request =
CreateModelInteraction.builder()
.model(Model.of("gemini-3.8-flash"))
.input(InteractionsInput.of("What's the weather in Boston?"))
.tools(Arrays.asList(weatherTool))
.build();
Interaction interaction =
client.interactions.create(CreateInteractionRequestBody.of(request)).interaction().get();
for (Step step : interaction.steps().orElse(Collections.emptyList())) {
if (step instanceof FunctionCallStep) {
FunctionCallStep fcStep = (FunctionCallStep) step;
System.out.println(
"Executing "
+ fcStep.name().orElse("")
+ " for "
+ fcStep.arguments().orElse(Collections.emptyMap()));
String result = "52°F and rain";
FunctionResultStep funcResult =
FunctionResultStep.builder()
.callId(fcStep.id().orElse(""))
.name(fcStep.name().orElse(""))
.result(
FunctionResultStepResultUnion.of(
Arrays.asList(TextContent.builder().text(result).build())))
.build();
CreateModelInteraction nextRequest =
CreateModelInteraction.builder()
.model(Model.of("gemini-3.8-flash"))
.previousInteractionId(interaction.id().orElse(""))
.input(InteractionsInput.ofStep(Arrays.asList(funcResult)))
.build();
Interaction nextInteraction =
client.interactions.create(CreateInteractionRequestBody.of(nextRequest)).interaction().get();
System.out.println(nextInteraction.outputText().orElse(""));
}
}
Go
package main
import (
"context"
"fmt"
"log"
"google.golang.org/genai"
"google.golang.org/genai/interactions/models/interactions"
"google.golang.org/genai/interactions/models/operations"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
weatherTool := interactions.NewTool(interactions.Function{
Name: genai.Ptr("get_weather"),
Description: genai.Ptr("Gets weather"),
Parameters: map[string]any{
"type": "object",
"properties": map[string]any{
"location": map[string]any{"type": "string"},
},
"required": []string{"location"},
},
})
res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{
Model: interactions.Model("gemini-3.8-flash"),
Input: interactions.NewInteractionsInput("What's the weather in Boston?"),
Tools: []interactions.Tool{weatherTool},
}),
})
if err != nil {
log.Fatal(err)
}
for _, step := range res.Interaction.Steps {
if fcStep := step.FunctionCallStep; fcStep != nil {
fmt.Printf("Executing %s for %v\n", fcStep.Name, fcStep.Arguments)
result := "52°F and rain"
funcResult := interactions.NewStep(interactions.FunctionResultStep{
CallID: fcStep.ID,
Name: genai.Ptr(fcStep.Name),
Result: interactions.NewFunctionResultStepResultUnion([]interactions.FunctionResultSubcontent{
interactions.NewFunctionResultSubcontent(interactions.TextContent{Text: result}),
}),
})
nextRes, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{
Model: interactions.Model("gemini-3.8-flash"),
PreviousInteractionID: res.Interaction.ID,
Input: interactions.NewInteractionsInput([]interactions.Step{funcResult}),
}),
})
if err != nil {
log.Fatal(err)
}
if nextRes.Interaction.OutputText != nil {
fmt.Println(*nextRes.Interaction.OutputText)
}
}
}
}
REST
# Initial Request
curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "Content-Type: application/json" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-d '{
"model": "gemini-3.8-flash",
"input": "What's the weather in Boston?",
"tools": [{
"type": "function",
"name": "get_weather",
"description": "Get weather for a location",
"parameters": {
"type": "object",
"properties": {
"location": { "type": "string" }
},
"required": ["location"]
}
}]
}'
# Response (requires action)
{
"id": "int_001",
"status": "requires_action",
"steps": [
{
"type": "user_input",
"status": "done",
"content": [
{ "type": "text", "text": "What's the weather in Boston?" }
]
},
{
"type": "function_call",
"status": "waiting",
"id": "fc_1",
"name": "get_weather",
"arguments": { "location": "Boston, MA" }
}
]
}
# Submit Tool Result Request
curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "Content-Type: application/json" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-d '{
"model": "gemini-3.8-flash",
"previous_interaction_id": "int_001",
"input": {
"type": "function_result",
"call_id": "fc_1",
"name": "get_weather",
"result": [
{ "type": "text", "text": "52°F with rain" }
]
}
}'
# Final Response
{
"id": "int_002",
"status": "completed",
"steps": [
{
"type": "function_result",
"call_id": "fc_1",
"name": "get_weather",
"result": [
{ "type": "text", "text": "52°F with rain" }
]
},
{
"type": "model_output",
"status": "done",
"content": [
{ "type": "text", "text": "It's 52°F with rain in Boston." }
]
}
]
}
Streaming
Kluczową różnicą w przypadku strumieniowania jest to, że interfejs Interactions API używa tego samego punktu końcowego z "stream": true w treści żądania, podczas gdy interfejs generateContent API wymagał wywołania dedykowanego punktu końcowego (:streamGenerateContent).
Dodatkowo zdarzenia strumieniowe używają teraz wyspecjalizowanych typów do monitorowania cyklu życia interakcji i śledzenia kroków wykonywania na osi czasu.
Przed (generateContentStream)
W przypadku generateContent wykorzystujesz strumień fragmentów odpowiedzi.
Python
from google import genai
client = genai.Client()
response = client.models.generate_content_stream(
model="gemini-2.5-flash-lite", contents="Tell me a story"
)
for chunk in response:
print(chunk.text, end="")
JavaScript
const responseStream = await client.models.generateContentStream({
model: 'gemini-2.5-flash-lite',
contents: 'Tell me a story',
});
for await (const chunk of responseStream) {
process.stdout.write(chunk.text);
}
Java
import com.google.genai.Client;
import com.google.genai.ResponseStream;
import com.google.genai.types.GenerateContentResponse;
Client client = new Client();
try (ResponseStream<GenerateContentResponse> responseStream =
client.models.generateContentStream("gemini-2.5-flash-lite", "Tell me a story", null)) {
for (GenerateContentResponse chunk : responseStream) {
System.out.print(chunk.text());
}
}
Go
package main
import (
"context"
"fmt"
"log"
"google.golang.org/genai"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
for chunk, err := range client.Models.GenerateContentStream(
ctx,
"gemini-2.5-flash-lite",
genai.Text("Tell me a story"),
nil,
) {
if err != nil {
log.Fatal(err)
}
fmt.Print(chunk.Text())
}
}
REST
# Request
curl -X POST "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-lite:streamGenerateContent" \
-H "Content-Type: application/json" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-d '{
"contents": [{
"parts": [{
"text": "Tell me a story"
}]
}]
}'
# Response stream
event: content.start
data: {"event_type": "content.start", "index": 0, "content": {"type": "thought"}}
event: content.delta
data: {"event_type": "content.delta", "index": 0, "delta": {"type": "thought_summary", "text": "User wants an explanation."}}
event: content.stop
data: {"event_type": "content.stop", "index": 0}
event: content.start
data: {"event_type": "content.start", "index": 1, "content": {"type": "text"}}
event: content.delta
data: {"event_type": "content.delta", "index": 1, "delta": {"type": "text", "text": "Hello"}}
event: content.stop
data: {"event_type": "content.stop", "index": 1}
Po (Interactions API)
W Interactions API strumieniowanie wykorzystuje zdarzenia wysyłane przez serwer (SSE) i specjalne typy delta do reprezentowania kroków wykonywania w miarę ich występowania.
Python
from google import genai
client = genai.Client()
stream = client.interactions.create(
model="gemini-3.8-flash",
input="Tell me a story",
stream=True,
)
for event in stream:
if event.event_type == "step.delta" and event.delta:
if getattr(event.delta, "type", None) == "text" and getattr(event.delta, "text", None):
print(event.delta.text, end="", flush=True)
elif event.event_type == "interaction.completed":
print(f"\n\n--- Stream Finished ---")
JavaScript
import { GoogleGenAI } from '@google/genai';
const client = new GoogleGenAI({});
const stream = await client.interactions.create({
model: 'gemini-3.8-flash',
input: 'Tell me a story',
stream: true,
});
for await (const event of stream) {
if (event.event_type === 'step.delta' && event.delta) {
if (event.delta.type === 'text' && event.delta.text) {
process.stdout.write(event.delta.text);
}
} else if (event.event_type === 'interaction.completed') {
console.log('\n\n--- Stream Finished ---');
}
}
Java
import com.google.genai.Client;
import com.google.genai.gaos.models.interactions.CreateModelInteraction;
import com.google.genai.gaos.models.interactions.InteractionCompletedEvent;
import com.google.genai.gaos.models.interactions.InteractionSSEEvent;
import com.google.genai.gaos.models.interactions.InteractionSSEStreamEvent;
import com.google.genai.gaos.models.interactions.InteractionsInput;
import com.google.genai.gaos.models.interactions.Model;
import com.google.genai.gaos.models.interactions.StepDelta;
import com.google.genai.gaos.models.interactions.TextDelta;
import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;
import com.google.genai.gaos.utils.EventStream;
Client client = new Client();
CreateModelInteraction request =
CreateModelInteraction.builder()
.model(Model.of("gemini-3.8-flash"))
.input(InteractionsInput.of("Tell me a story"))
.stream(true)
.build();
try (EventStream<InteractionSSEStreamEvent> stream =
client.interactions.create(CreateInteractionRequestBody.of(request)).events()) {
for (InteractionSSEStreamEvent streamEvent : stream) {
if (streamEvent.data().isPresent()) {
InteractionSSEEvent event = streamEvent.data().get();
if (event instanceof StepDelta) {
StepDelta stepDelta = (StepDelta) event;
if (stepDelta.delta().isPresent() && stepDelta.delta().get() instanceof TextDelta) {
TextDelta textDelta = (TextDelta) stepDelta.delta().get();
System.out.print(textDelta.text().orElse(""));
}
} else if (event instanceof InteractionCompletedEvent) {
System.out.println("\n\n--- Stream Finished ---");
}
}
}
}
Go
package main
import (
"context"
"fmt"
"log"
"google.golang.org/genai"
"google.golang.org/genai/interactions/models/interactions"
"google.golang.org/genai/interactions/models/operations"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{
Model: interactions.Model("gemini-3.8-flash"),
Input: interactions.NewInteractionsInput("Tell me a story"),
Stream: genai.Ptr(true),
}),
})
if err != nil {
log.Fatal(err)
}
stream := res.InteractionSSEStreamEvent
defer stream.Close()
for stream.Next() {
event := stream.Value()
if stepDelta := event.GetDataStepDelta(); stepDelta != nil {
if textDelta := stepDelta.GetDeltaText(); textDelta != nil {
fmt.Print(textDelta.GetText())
}
} else if event.GetDataInteractionCompleted() != nil {
fmt.Println("\n\n--- Stream Finished ---")
}
}
if err := stream.Err(); err != nil {
log.Fatal(err)
}
}
REST
# Przykładowe dane wyjściowe strumienia SSE event: interaction.created data: {"interaction": {"id": "int_xyz", "status": "in_progress"}, "event_type": "interaction.created"} event: interaction.status_update data: {"interaction_id": "int_xyz", "status": "in_progress", "event_type": "interaction.status_update"} event: step.start data: {"index": 0, "step": {"type": "thought"}, "event_type": "step.start"} event: step.delta data: {"index": 0, "delta": {"type": "thought_summary", "content": {"type": "text", "text": "User wants an explanation."}}, "event_type": "step.delta"} event: step.stop data: {"index": 0, "event_type": "step.stop"} event: step.start data: {"index": 1, "step": {"type": "model_output"}, "event_type": "step.start"} event: step.delta data: {"index": 1, "delta": {"type": "text", "text": "Hello"}, "event_type": "step.delta"} event: step.stop data: {"index": 1, "event_type": "step.stop"} event: interaction.completed data: {"interaction": {"id": "int_xyz", "status": "completed", "usage": {"total_input_tokens": 10, "total_output_tokens": 5, "total_tokens": 15}}, "event_type": "interaction.completed"} ```
Narzędzia do strumieniowania i wywołania funkcji
Sposób działania narzędzi w strumieniu znacznie się zmienił od generateContent, aby zapewnić bardziej szczegółową kontrolę i widoczność.
Przed (generateContent)
W przypadku generateContent wywołania funkcji strumieniowych były dostarczane w całości w jednym fragmencie. Nie można było zobaczyć argumentów generowanych w czasie rzeczywistym, więc moduł obsługi po prostu sprawdzał, czy obiekt functionCall jest kompletny.
Python
from google import genai
from google.genai import types
client = genai.Client()
stream = client.models.generate_content_stream(
model="gemini-2.5-flash-lite",
contents="What's the weather in Boston?",
config=types.GenerateContentConfig(tools=[weather_tool]),
)
for chunk in stream:
# Function calls arrived complete — no partial arguments
if chunk.candidates[0].content.parts[0].function_call:
fc = chunk.candidates[0].content.parts[0].function_call
print(f"Call: {fc.name}({fc.args})")
elif chunk.text:
print(chunk.text, end="")
JavaScript
import { GoogleGenAI } from '@google/genai';
const client = new GoogleGenAI({});
const stream = await client.models.generateContentStream({
model: 'gemini-2.5-flash-lite',
contents: "What's the weather in Boston?",
config: { tools: [weatherTool] }
});
for await (const chunk of stream) {
const part = chunk.candidates[0].content.parts[0];
if (part.functionCall) {
console.log(`Call: ${part.functionCall.name}(${JSON.stringify(part.functionCall.args)})`);
} else if (part.text) {
process.stdout.write(part.text);
}
}
Java
import com.google.genai.Client;
import com.google.genai.ResponseStream;
import com.google.genai.types.FunctionCall;
import com.google.genai.types.FunctionDeclaration;
import com.google.genai.types.GenerateContentConfig;
import com.google.genai.types.GenerateContentResponse;
import com.google.genai.types.Schema;
import com.google.genai.types.Tool;
import com.google.genai.types.Type;
import java.util.Arrays;
import java.util.Map;
Client client = new Client();
FunctionDeclaration weatherFunc =
FunctionDeclaration.builder()
.name("get_weather")
.description("Gets weather")
.parameters(
Schema.builder()
.type(Type.Known.OBJECT)
.properties(Map.of("location", Schema.builder().type(Type.Known.STRING).build()))
.build())
.build();
Tool weatherTool = Tool.builder().functionDeclarations(Arrays.asList(weatherFunc)).build();
try (ResponseStream<GenerateContentResponse> stream =
client.models.generateContentStream(
"gemini-2.5-flash-lite",
"What's the weather in Boston?",
GenerateContentConfig.builder().tools(Arrays.asList(weatherTool)).build())) {
for (GenerateContentResponse chunk : stream) {
if (chunk.functionCalls() != null && !chunk.functionCalls().isEmpty()) {
FunctionCall fc = chunk.functionCalls().get(0);
System.out.println("Call: " + fc.name().orElse("") + "(" + fc.args().orElse(Map.of()) + ")");
} else if (chunk.text() != null) {
System.out.print(chunk.text());
}
}
}
Go
package main
import (
"context"
"fmt"
"log"
"google.golang.org/genai"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
weatherTool := &genai.Tool{
FunctionDeclarations: []*genai.FunctionDeclaration{
{
Name: "get_weather",
Description: "Gets weather",
Parameters: &genai.Schema{
Type: genai.TypeObject,
Properties: map[string]*genai.Schema{
"location": {Type: genai.TypeString},
},
},
},
},
}
for chunk, err := range client.Models.GenerateContentStream(
ctx,
"gemini-2.5-flash-lite",
genai.Text("What's the weather in Boston?"),
&genai.GenerateContentConfig{
Tools: []*genai.Tool{weatherTool},
},
) {
if err != nil {
log.Fatal(err)
}
if calls := chunk.FunctionCalls(); len(calls) > 0 {
fc := calls[0]
fmt.Printf("Call: %s(%v)\n", fc.Name, fc.Args)
} else if text := chunk.Text(); text != "" {
fmt.Print(text)
}
}
}
REST
# Request
curl -X POST "https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-lite:streamGenerateContent" \
-H "Content-Type: application/json" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-d '{
"contents": [{"parts": [{"text": "What is the weather in Boston?"}]}],
"tools": [{"functionDeclarations": [{"name": "get_weather", "parameters": {"type": "OBJECT", "properties": {"location": {"type": "STRING"}}}}]}]
}'
# Response stream — function call arrives complete in one chunk
{"candidates": [{"content": {"parts": [{"functionCall": {"name": "get_weather", "args": {"location": "Boston, MA"}}}]}}]}
Po (Interactions API)
Interactions API przesyła argumenty wywołania funkcji znak po znaku jako zdarzenia arguments_delta. Cały cykl życia narzędzia – myśl, wywołanie, wynik i dane wyjściowe – przebiega w ramach serii odrębnych kroków.
Python
from google import genai
client = genai.Client()
stream = client.interactions.create(
model="gemini-3.8-flash",
input="What's the weather in Boston?",
tools=[get_weather_tool],
stream=True,
)
for event in stream:
if event.event_type == "step.start" and event.step:
if getattr(event.step, "type", None) == "function_call":
print(f"Calling: {event.step.name}")
elif event.event_type == "step.delta" and event.delta:
if getattr(event.delta, "type", None) == "arguments_delta":
print(f" args: {event.delta.arguments}")
elif getattr(event.delta, "type", None) == "text" and getattr(event.delta, "text", None):
print(event.delta.text, end="")
elif event.event_type == "interaction.completed":
print("\n--- Done ---")
JavaScript
import { GoogleGenAI } from '@google/genai';
const client = new GoogleGenAI({});
const stream = await client.interactions.create({
model: 'gemini-3.8-flash',
input: "What's the weather in Boston?",
tools: [getWeatherTool],
stream: true,
});
for await (const event of stream) {
if (event.event_type === 'step.start' && event.step) {
if (event.step.type === 'function_call') {
console.log(`Calling: ${event.step.name}`);
}
} else if (event.event_type === 'step.delta' && event.delta) {
if (event.delta.type === 'arguments_delta' && event.delta.arguments) {
console.log(` args: ${event.delta.arguments}`);
} else if (event.delta.type === 'text' && event.delta.text) {
process.stdout.write(event.delta.text);
}
} else if (event.event_type === 'interaction.completed') {
console.log('\n--- Done ---');
}
}
Java
import com.google.genai.Client;
import com.google.genai.gaos.models.interactions.ArgumentsDelta;
import com.google.genai.gaos.models.interactions.CreateModelInteraction;
import com.google.genai.gaos.models.interactions.Function;
import com.google.genai.gaos.models.interactions.FunctionCallStep;
import com.google.genai.gaos.models.interactions.InteractionCompletedEvent;
import com.google.genai.gaos.models.interactions.InteractionSSEEvent;
import com.google.genai.gaos.models.interactions.InteractionSSEStreamEvent;
import com.google.genai.gaos.models.interactions.InteractionsInput;
import com.google.genai.gaos.models.interactions.Model;
import com.google.genai.gaos.models.interactions.StepDelta;
import com.google.genai.gaos.models.interactions.StepDeltaData;
import com.google.genai.gaos.models.interactions.StepStart;
import com.google.genai.gaos.models.interactions.TextDelta;
import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;
import com.google.genai.gaos.utils.EventStream;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
Client client = new Client();
Map<String, Object> properties = new HashMap<>();
properties.put("location", Map.of("type", "string"));
Map<String, Object> parameters = new HashMap<>();
parameters.put("type", "object");
parameters.put("properties", properties);
parameters.put("required", Arrays.asList("location"));
Function getWeatherTool =
Function.builder()
.name("get_weather")
.description("Gets weather")
.parameters(parameters)
.build();
CreateModelInteraction request =
CreateModelInteraction.builder()
.model(Model.of("gemini-3.8-flash"))
.input(InteractionsInput.of("What's the weather in Boston?"))
.tools(Arrays.asList(getWeatherTool))
.stream(true)
.build();
try (EventStream<InteractionSSEStreamEvent> stream =
client.interactions.create(CreateInteractionRequestBody.of(request)).events()) {
for (InteractionSSEStreamEvent streamEvent : stream) {
if (streamEvent.data().isPresent()) {
InteractionSSEEvent event = streamEvent.data().get();
if (event instanceof StepStart) {
StepStart stepStart = (StepStart) event;
if (stepStart.step().isPresent() && stepStart.step().get() instanceof FunctionCallStep) {
FunctionCallStep fcStep = (FunctionCallStep) stepStart.step().get();
System.out.println("Calling: " + fcStep.name().orElse(""));
}
} else if (event instanceof StepDelta) {
StepDelta stepDelta = (StepDelta) event;
if (stepDelta.delta().isPresent()) {
StepDeltaData delta = stepDelta.delta().get();
if (delta instanceof ArgumentsDelta) {
System.out.println(" args: " + ((ArgumentsDelta) delta).arguments().orElse(""));
} else if (delta instanceof TextDelta) {
System.out.print(((TextDelta) delta).text().orElse(""));
}
}
} else if (event instanceof InteractionCompletedEvent) {
System.out.println("\n--- Done ---");
}
}
}
}
Go
package main
import (
"context"
"fmt"
"log"
"google.golang.org/genai"
"google.golang.org/genai/interactions/models/interactions"
"google.golang.org/genai/interactions/models/operations"
)
func main() {
ctx := context.Background()
client, err := genai.NewClient(ctx, nil)
if err != nil {
log.Fatal(err)
}
getWeatherTool := interactions.NewTool(interactions.Function{
Name: genai.Ptr("get_weather"),
Description: genai.Ptr("Gets weather"),
Parameters: map[string]any{
"type": "object",
"properties": map[string]any{
"location": map[string]any{"type": "string"},
},
"required": []string{"location"},
},
})
res, err := client.Interactions.Create(ctx, operations.CreateInteractionRequest{
Body: operations.NewCreateInteractionRequestBody(interactions.CreateModelInteraction{
Model: interactions.Model("gemini-3.8-flash"),
Input: interactions.NewInteractionsInput("What's the weather in Boston?"),
Tools: []interactions.Tool{getWeatherTool},
Stream: genai.Ptr(true),
}),
})
if err != nil {
log.Fatal(err)
}
stream := res.InteractionSSEStreamEvent
defer stream.Close()
for stream.Next() {
event := stream.Value()
if stepStart := event.GetDataStepStart(); stepStart != nil {
if fcStep := stepStart.GetStepFunctionCall(); fcStep != nil {
fmt.Println("Calling:", fcStep.Name)
}
} else if stepDelta := event.GetDataStepDelta(); stepDelta != nil {
if argsDelta := stepDelta.GetDeltaArgumentsDelta(); argsDelta != nil {
fmt.Println(" args:", argsDelta.GetArguments())
} else if textDelta := stepDelta.GetDeltaText(); textDelta != nil {
fmt.Print(textDelta.GetText())
}
} else if event.GetDataInteractionCompleted() != nil {
fmt.Println("\n--- Done ---")
}
}
if err := stream.Err(); err != nil {
log.Fatal(err)
}
}
REST
# Request
curl -X POST "https://generativelanguage.googleapis.com/v1beta/interactions" \
-H "Content-Type: application/json" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-d '{
"model": "gemini-3.8-flash",
"input": "What is the weather in Boston?",
"tools": [{"type": "function", "name": "get_weather", "parameters": {"type": "object", "properties": {"location": {"type": "string"}}}}],
"stream": true
}'
# Response stream
// Stream 1: the model calls the function
event: interaction.created
data: {"interaction": {"id": "int_1", "status": "in_progress"}, "event_type": "interaction.created"}
event: interaction.status_update
data: {"interaction_id": "int_1", "status": "in_progress", "event_type": "interaction.status_update"}
// ── Step 0: Thought ──────────────────────────────────
event: step.start
data: {"index": 0, "step": {"type": "thought"}, "event_type": "step.start"}
event: step.delta
data: {"index": 0, "delta": {"type": "thought_summary", "content": {"type": "text", "text": "The user wants weather data for Boston. I'll call the get_weather tool."}}, "event_type": "step.delta"}
event: step.stop
data: {"index": 0, "event_type": "step.stop"}
// ── Step 1: Function Call (arguments streamed) ───────
event: step.start
data: {"index": 1, "step": {"type": "function_call", "id": "fc_1", "name": "get_weather", "arguments": {}}, "event_type": "step.start"}
event: step.delta
data: {"index": 1, "delta": {"type": "arguments_delta", "arguments": "{\"location\": \"Boston, MA\"}"}, "event_type": "step.delta"}
event: step.stop
data: {"index": 1, "event_type": "step.stop"}
// The stream ends with status requires_action: the model needs the tool result.
event: interaction.completed
data: {"interaction": {"id": "int_1", "status": "requires_action", "usage": {"total_input_tokens": 34, "total_output_tokens": 15, "total_tokens": 49}}, "event_type": "interaction.completed"}
event: done
data: [DONE]
// ── (Client submits the tool result) ──────────────────
// The client calls interactions.create with the function_result as input
// and previous_interaction_id set to "int_1". This opens a new stream.
// Stream 2: the model uses the result
event: interaction.created
data: {"interaction": {"id": "int_2", "status": "in_progress"}, "event_type": "interaction.created"}
event: interaction.status_update
data: {"interaction_id": "int_2", "status": "in_progress", "event_type": "interaction.status_update"}
// ── Step 0: Thought ──────────────────────────────────
event: step.start
data: {"index": 0, "step": {"type": "thought"}, "event_type": "step.start"}
event: step.delta
data: {"index": 0, "delta": {"type": "thought_summary", "content": {"type": "text", "text": "Got weather data. Composing the final response."}}, "event_type": "step.delta"}
event: step.stop
data: {"index": 0, "event_type": "step.stop"}
// ── Step 1: Model Output (text streamed) ─────────────
event: step.start
data: {"index": 1, "step": {"type": "model_output"}, "event_type": "step.start"}
event: step.delta
data: {"index": 1, "delta": {"type": "text", "text": "It's currently 52°F and rainy in Boston."}, "event_type": "step.delta"}
event: step.stop
data: {"index": 1, "event_type": "step.stop"}
// ── Interaction complete ─────────────────────────────
event: interaction.completed
data: {"interaction": {"id": "int_2", "status": "completed", "usage": {"total_input_tokens": 256, "total_output_tokens": 128, "total_tokens": 384}}, "event_type": "interaction.completed"}
event: done
data: [DONE]