Interactions API 開發人員指南

Interactions API 提供統一的有狀態介面,可在 Gemini Enterprise Agent Platform 上,使用 Gemini 模型和自主代理建構生成式 AI 應用程式。使用 Interactions API 管理工作階段儲存空間和多輪對話、串流即時回覆、強制執行結構化輸出內容、叫用內建工具和建立基準、執行函式呼叫,以及協調長時間執行的背景工作。

本指南說明如何安裝 Google Gen AI SDK、驗證用戶端,以及實作常見的互動工作流程。如要進一步瞭解互動生命週期的概念,請參閱「Interactions API 總覽」。

事前準備

向 Interactions API 傳送要求前,請先設定 Google Cloud專案和開發環境:

  1. In the Google Cloud console, on the project selector page, select or create a Google Cloud project.

    Roles required to select or create a project

    • Select a project: Selecting a project doesn't require a specific IAM role—you can select any project that you've been granted a role on.
    • Create a project: To create a project, you need the Project Creator role (roles/resourcemanager.projectCreator), which contains the resourcemanager.projects.create permission. Learn how to grant roles.

    Go to project selector

  2. Verify that billing is enabled for your Google Cloud project.

  3. Enable the Agent Platform API, if it is not already enabled.

    Roles required to enable APIs

    To enable APIs, you need the serviceusage.services.enable permission. If you created the project, then you likely already have this permission through the Owner role (roles/owner). Otherwise, you can get this permission through the Service Usage Admin role (roles/serviceusage.serviceUsageAdmin). Learn how to grant roles.

    Enable the API

  4. Make sure that you have the following role or roles on the project: Agent Platform User (roles/aiplatform.user)

    Check for the roles

    1. In the Google Cloud console, go to the IAM page.

      Go to IAM
    2. Select the project.
    3. In the Principal column, find all rows that identify you or a group that you're included in. To learn which groups you're included in, contact your administrator.

    4. For all rows that specify or include you, check the Role column to see whether the list of roles includes the required roles.

    Grant the roles

    1. In the Google Cloud console, go to the IAM page.

      Go to IAM
    2. Select the project.
    3. Click Grant access.
    4. In the New principals field, enter your user identifier. This is typically the identifier for a user in a workforce identity pool. For details, see Represent workforce pool users in IAM policies, or contact your administrator.

    5. Click Select a role, then search for the role.
    6. To grant additional roles, click Add another role and add each additional role.
    7. Click Save.

基本概念

請參閱下列概念,瞭解 Interactions API 如何管理狀態和回覆:

  • Interaction:Interactions API 的核心資源是 Interaction。Interaction 代表對話或工作中的完整回合,會追蹤模型思考、工具呼叫和最終輸出的時間順序。為提示/回覆互動和複雜的多步驟 Agentic Workflows,提供統一的封裝。

  • 有狀態保留:互動預設會儲存在伺服器端 (Python 為 store=True,TypeScript/JavaScript 為 store: true)。儲存的互動記錄會保留 7 天,之後就會自動刪除。設定 store=False 會啟用無狀態模式,停用伺服器端保留功能,並符合零資料保留 (ZDR) 規定。無狀態模式也會停用 previous_interaction_id 鏈結和非同步執行 (background=True)。

  • 回應輔助函式:Google Gen AI SDK 2.3.0 以上版本提供互動回應的便利屬性,包括 interaction.output_text、interaction.output_image 和 interaction.output_audio。請使用 interaction.output_text 讀取文字回覆,不要手動索引至步驟陣列 (例如 interaction.steps[-1].content[0].text)。

需求條件

整合 Interactions API 前,請確認環境和要求符合下列規定:

  • SDK 版本支援:使用支援的 Google Gen AI SDK 程式庫。

  • 支援的模型:使用支援的 Gemini 3 以上版本模型。舊版模型系列不支援這個 API。如需支援模型的完整清單,請參閱「支援的模型」和「遷移至最新模型版本」。

  • 回合範圍參數:tools、system_instruction 和 generation_config 等設定參數僅適用於目前的回合。如果工作流程需要在多輪對話中持續使用這些參數,請在後續的每輪互動中傳遞這些參數。

  • Gemini 4 Argon 的長解碼:如要在 gemini-4-argon 或 gemini-4-argon-cyber-permissive 上生成超過 65,536 個詞元的單輪輸出內容 (最多 1,048,576 個詞元減去輸入詞元),請在 v1beta1 端點使用 Google Gen AI SDK 自動接續功能 (Python 的 google-genai >= 2.34.0、TypeScript/JavaScript 的 @google/genai >= 2.32.0、Go 的 >= 1.77.0、Java 的 >= 1.80.0)、background=True 或 continuation_token。如需程式碼範例和接續規則,請參閱 Gemini 4 Argon 開發人員指南中的「Long decodes」(長解碼)。

安裝 Google Gen AI SDK

安裝或升級您偏好語言的 Google Gen AI SDK:

Python

pip install --upgrade "google-genai>=2.3.0"

TypeScript / JavaScript

npm install "@google/genai>=2.3.0"

Go

go get google.golang.org/genai

Java

<dependencies>
  <dependency>
    <groupId>com.google.genai</groupId>
    <artifactId>google-genai</artifactId>
    <version>1.78.0</version>
  </dependency>
</dependencies>

驗證用戶端

您可以使用下列任一驗證方式,連線至 Agent Platform 上的 Interactions API:

使用 Google Cloud 專案和應用程式預設憑證 (ADC) 建立連線

如要在 Google Cloud上部署企業工作負載和正式環境,請使用這個驗證方式。如要使用應用程式預設憑證 (ADC) 進行驗證,請使用下列屬性初始化用戶端:

  • enterprise=True
  • project="PROJECT_ID"
  • location="global"

如果尚未設定本機憑證,請執行 gcloud auth application-default login。

在下列程式碼範例中,將 PROJECT_ID 替換為您的Google Cloud 專案 ID。

Python

from google import genai

client = genai.Client(
    enterprise=True,
    project="PROJECT_ID",
    location="global",
)

interaction = client.interactions.create(
    model="gemini-3.8-flash",
    input="Explain serverless computing in one sentence.",
)

print(interaction.output_text)

TypeScript / JavaScript

import { GoogleGenAI } from "@google/genai";

const ai = new GoogleGenAI({
    enterprise: true,
    project: "PROJECT_ID",
    location: "global",
});

const interaction = await ai.interactions.create({
    model: "gemini-3.8-flash",
    input: "Explain serverless computing in one sentence.",
});

console.log(interaction.output_text);

REST

curl -X POST "https://aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/global/interactions" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gemini-3.8-flash",
    "input": [{
      "type": "user_input",
      "content": [{
        "type": "text",
        "text": "Explain serverless computing in one sentence."
      }]
    }]
  }'

使用快捷模式 (API 金鑰) 連結

如要快速建立原型、使用輕量指令碼,或以 API 金鑰驗證環境,請採用這種驗證方式。在初始化用戶端時或在 x-goog-api-key HTTP 標頭中傳遞 API 金鑰。

在下列程式碼範例中,將 API_KEY 替換為您的 API 金鑰,並將 PROJECT_ID 替換為您的 Google Cloud 專案 ID。

Python

from google import genai

client = genai.Client(
    enterprise=True,
    api_key="API_KEY",
)

interaction = client.interactions.create(
    model="gemini-3.8-flash",
    input="Explain serverless computing in one sentence.",
)

print(interaction.output_text)

TypeScript / JavaScript

import { GoogleGenAI } from "@google/genai";

const ai = new GoogleGenAI({
    enterprise: true,
    apiKey: "API_KEY",
});

const interaction = await ai.interactions.create({
    model: "gemini-3.8-flash",
    input: "Explain serverless computing in one sentence.",
});

console.log(interaction.output_text);

REST

curl -X POST "https://aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/global/interactions" \
  -H "x-goog-api-key: API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gemini-3.8-flash",
    "input": [{
      "type": "user_input",
      "content": [{
        "type": "text",
        "text": "Explain serverless computing in one sentence."
      }]
    }]
  }'

常見的互動工作流程

設定用戶端後,您可以使用 interactions.create 方法管理工作階段儲存空間和多輪對話、即時串流輸出權杖、生成經過結構定義驗證的 JSON、叫用內建工具和基準建立、呼叫外部函式,以及執行自主代理。

管理工作階段儲存空間和對話狀態

Interactions API 支援伺服器端有狀態儲存空間 (store=True,預設) 和用戶端管理的無狀態執行 (store=False)。下表比較有狀態和無狀態互動模式:

功能 有狀態模式 (store=true,預設) 無狀態模式 (store=false)
伺服器端資料保留設定 在伺服器上儲存輸入內容、中繼步驟和輸出內容 7 天。 停用伺服器端互動儲存空間,以支援零資料保留 (ZDR) 工作流程。
多輪對話情境 在 previous_interaction_id 中傳遞先前的互動 id,藉此鏈結對話。 每次對話時,都必須在 input 的 steps 中傳遞先前的完整對話陣列。傳遞 previous_interaction_id 會傳回 400 Bad Request 錯誤。
背景執行 (background=true) 支援長時間執行的模型和代理互動。 不支援。非同步背景執行作業需要伺服器端狀態持續性。
工作階段生命週期方法 支援擷取 (get)、列出 (list)、取消 (cancel) 和刪除 (delete) 互動。 同步或串流回覆完成後,就無法擷取。
靜態資料加密 預設會使用 Google-owned and Google-managed encryption key加密,或在us和eu多區域使用客戶自行管理的加密金鑰 (CMEK)。 系統不會儲存靜態互動狀態。

執行有狀態的多輪對話

根據預設,Interactions API 會將對話狀態儲存在伺服器上 (Python 為 store=True,TypeScript/JavaScript 為 store: true)。如要繼續現有對話,請將前一個互動的 id 傳遞至 previous_interaction_id 參數。Agent Platform 會擷取儲存的對話內容、附加新的對話,並重複使用快取的前置詞權杖。

在端點之間鏈結互動時,請遵守下列位置規則:

  • 相同位置:您可以在相同位置鏈結互動 (例如 global 到 global、us 到 us 或 eu 到 eu)。

  • 跨不同位置:不支援跨不同端點位置鏈結 (global 和 us 或 eu 之間,或 us 和 eu 之間)。每個端點都會將互動狀態儲存在獨立儲存空間,因此參照在其他位置建立的互動 ID 會傳回 404 Not Found 錯誤。

在下列範例中,請將 PROJECT_ID 替換為您的 Google Cloud專案 ID:

Python

from google import genai

client = genai.Client(
    enterprise=True,
    project="PROJECT_ID",
    location="global",
)

# Turn 1: Start a stateful conversation (store=True by default)
turn1 = client.interactions.create(
    model="gemini-3.8-flash",
    input="Hi! My name is John. I am working on AI agents.",
    store=True,
)
print(f"Turn 1: {turn1.output_text}")

# Turn 2: Reference the stored conversation state using previous_interaction_id
turn2 = client.interactions.create(
    model="gemini-3.8-flash",
    input="What is my name?",
    previous_interaction_id=turn1.id,
)
print(f"Turn 2: {turn2.output_text}")

TypeScript / JavaScript

import { GoogleGenAI } from "@google/genai";

const ai = new GoogleGenAI({
    enterprise: true,
    project: "PROJECT_ID",
    location: "global",
});

// Turn 1: Start a stateful conversation (store: true by default)
const turn1 = await ai.interactions.create({
    model: "gemini-3.8-flash",
    input: "Hi! My name is John. I am working on AI agents.",
    store: true,
});
console.log(`Turn 1: ${turn1.output_text}`);

// Turn 2: Reference the stored conversation state using previous_interaction_id
const turn2 = await ai.interactions.create({
    model: "gemini-3.8-flash",
    input: "What is my name?",
    previous_interaction_id: turn1.id,
});
console.log(`Turn 2: ${turn2.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 =
    Client.builder()
        .enterprise(true)
        .project("PROJECT_ID")
        .location("global")
        .build();

// Turn 1: Start a stateful conversation (store is true by default)
CreateModelInteraction req1 =
    CreateModelInteraction.builder()
        .model(Model.of("gemini-3.8-flash"))
        .input(InteractionsInput.of("Hi! My name is John. I am working on AI agents."))
        .store(true)
        .build();

Interaction turn1 =
    client.interactions.create(CreateInteractionRequestBody.of(req1)).interaction().orElseThrow();
System.out.println("Turn 1: " + turn1.outputText().orElse(""));

// Turn 2: Reference the stored conversation state using previousInteractionId
CreateModelInteraction req2 =
    CreateModelInteraction.builder()
        .model(Model.of("gemini-3.8-flash"))
        .previousInteractionId(turn1.id().orElseThrow())
        .input(InteractionsInput.of("What is my name?"))
        .build();

Interaction turn2 =
    client.interactions.create(CreateInteractionRequestBody.of(req2)).interaction().orElseThrow();
System.out.println("Turn 2: " + turn2.outputText().orElse(""));

REST

# Turn 1: Start a stateful conversation
curl -X POST "https://aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/global/interactions" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gemini-3.8-flash",
    "store": true,
    "input": "Hi! My name is John. I am working on AI agents."
  }'

# Turn 2: Pass the interaction ID from Turn 1 in previous_interaction_id
curl -X POST "https://aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/global/interactions" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gemini-3.8-flash",
    "previous_interaction_id": "PREVIOUS_INTERACTION_ID",
    "input": "What is my name?"
  }'

執行無狀態多輪對話

如果工作負載需要零資料保留 (ZDR),請在每項要求中明確設定 store=False (TypeScript/JavaScript 為 store: false,REST 為 "store": false)。

在無狀態模式下,您可以在用戶端管理對話記錄,方法是維護 Step 物件 (user_input、thought、function_call、function_result 和 model_output) 的清單,並在每次對話時傳送 input 中累積的 steps 陣列:

Python

from google import genai

client = genai.Client(
    enterprise=True,
    project="PROJECT_ID",
    location="global",
)

history = [
    {
        "type": "user_input",
        "content": [{"type": "text", "text": "Hi! My name is John."}],
    }
]

# Turn 1: Stateless request (store=False)
turn1 = client.interactions.create(
    model="gemini-3.8-flash",
    input=history,
    store=False,
)
print(f"Turn 1: {turn1.output_text}")

# Append the model's generated steps and the next user turn to local history
history.extend(turn1.steps)
history.append(
    {
        "type": "user_input",
        "content": [{"type": "text", "text": "What is my name?"}],
    }
)

# Turn 2: Send the full step history with store=False
turn2 = client.interactions.create(
    model="gemini-3.8-flash",
    input=history,
    store=False,
)
print(f"Turn 2: {turn2.output_text}")

TypeScript / JavaScript

import { GoogleGenAI, Step } from "@google/genai";

const ai = new GoogleGenAI({
    enterprise: true,
    project: "PROJECT_ID",
    location: "global",
});

const history: Step[] = [
    {
        type: "user_input",
        content: [{ type: "text", text: "Hi! My name is John." }],
    },
];

// Turn 1: Stateless request (store: false)
const turn1 = await ai.interactions.create({
    model: "gemini-3.8-flash",
    input: history,
    store: false,
});
console.log(`Turn 1: ${turn1.output_text}`);

// Append the model's generated steps and the next user turn to local history
if (turn1.steps) {
    history.push(...turn1.steps);
}
history.push({
    type: "user_input",
    content: [{ type: "text", text: "What is my name?" }],
});

// Turn 2: Send the full step history with store: false
const turn2 = await ai.interactions.create({
    model: "gemini-3.8-flash",
    input: history,
    store: false,
});
console.log(`Turn 2: ${turn2.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.interactions.Step;
import com.google.genai.gaos.models.interactions.TextContent;
import com.google.genai.gaos.models.interactions.UserInputContent;
import com.google.genai.gaos.models.interactions.UserInputStep;
import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;
import java.util.ArrayList;
import java.util.List;

Client client =
    Client.builder()
        .enterprise(true)
        .project("PROJECT_ID")
        .location("global")
        .build();

List<Step> history = new ArrayList<>();
history.add(
    Step.of(
        UserInputStep.builder()
            .content(
                List.of(
                    UserInputContent.of(
                        TextContent.builder().text("Hi! My name is John.").build())))
            .build()));

// Turn 1: Stateless request (store(false))
CreateModelInteraction req1 =
    CreateModelInteraction.builder()
        .model(Model.of("gemini-3.8-flash"))
        .input(InteractionsInput.ofSteps(history))
        .store(false)
        .build();

Interaction turn1 =
    client.interactions.create(CreateInteractionRequestBody.of(req1)).interaction().orElseThrow();
System.out.println("Turn 1: " + turn1.outputText().orElse(""));

// Append the model's generated steps and the next user turn to local history
turn1.steps().ifPresent(history::addAll);
history.add(
    Step.of(
        UserInputStep.builder()
            .content(
                List.of(
                    UserInputContent.of(
                        TextContent.builder().text("What is my name?").build())))
            .build()));

// Turn 2: Send the full step history with store(false)
CreateModelInteraction req2 =
    CreateModelInteraction.builder()
        .model(Model.of("gemini-3.8-flash"))
        .input(InteractionsInput.ofSteps(history))
        .store(false)
        .build();

Interaction turn2 =
    client.interactions.create(CreateInteractionRequestBody.of(req2)).interaction().orElseThrow();
System.out.println("Turn 2: " + turn2.outputText().orElse(""));

REST

curl -X POST "https://aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/global/interactions" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gemini-3.8-flash",
    "store": false,
    "input": [
      {
        "type": "user_input",
        "content": [{"type": "text", "text": "Hi! My name is John."}]
      },
      {
        "type": "model_output",
        "content": [{"type": "text", "text": "Hello John! How can I help you today?"}]
      },
      {
        "type": "user_input",
        "content": [{"type": "text", "text": "What is my name?"}]
      }
    ]
  }'

保留和工作階段生命週期

儲存的互動 (store=True) 遵循下列保留和分支規則:

  • 7 天存留時間 (TTL):每筆儲存的互動資料都會從 created 時間戳記起保留 7 天,並在 7 天 TTL 到期時自動刪除。

  • 獨立的上層和下層儲存空間:使用 previous_interaction_id 鏈結新一輪對話時,Agent Platform 會將祖系對話記錄複製到新的互動記錄。由於每個回合都會儲存自己的對話記錄副本,因此過期或刪除較早的回合會產生下列影響:

    • 從後續回合繼續操作成功:如果回合 1 (interaction_1) 在回合 2 (interaction_2) 建立後到期或刪除,您仍可使用 previous_interaction_id=interaction_2.id 建立回合 3,直到 interaction_2 本身到期或刪除為止。

    • 無法從過期或刪除的回合分支:嘗試建立新互動,並直接參照 previous_interaction_id 中過期或刪除的互動 ID,會傳回 400 Bad Request (Previous Interaction ID not found) 錯誤。

擷取、列出、取消及刪除儲存的互動

您可以使用下列方法,檢查及管理儲存互動記錄的整個生命週期:

  • 擷取互動 (interactions.get):依 id 擷取完整的 Interaction 資源,包括 user_input 步驟、中繼 thought 和工具步驟,以及 model_output 步驟。設定 stream=True (和選用的 last_event_id),串流或繼續進行中的互動。

  • 列出互動 (interactions.list):使用 page_size (預設為 10,上限為 500) 和 page_token,透過 REST 查詢專案中儲存的互動 ID。傳回 InteractionMetadata 資源清單。

  • 取消進行中的互動 (interactions.cancel):停止處於 in_progress 或 requires_action 狀態的非同步背景互動 (background=True),並將其狀態轉換為 cancelled。我們會向您收取取消訂閱前產生的權杖費用。

  • 刪除儲存的互動 (interactions.delete):在 7 天存留時間到期前,永久移除儲存的互動。只有處於終端狀態 (completed、failed 或 cancelled) 的互動才能刪除;如果互動仍在背景執行,請先取消再刪除。

在下列範例中,請將 PROJECT_ID 替換為您的 Google Cloud專案 ID,並將 INTERACTION_ID 替換為目標互動 ID:

Python

from google import genai

client = genai.Client(
    enterprise=True,
    project="PROJECT_ID",
    location="global",
)

# Retrieve a stored interaction by ID
interaction = client.interactions.get(id="INTERACTION_ID")
print(f"Status: {interaction.status}")

# Cancel an in-progress background interaction
cancelled = client.interactions.cancel(id="INTERACTION_ID")
print(f"After cancel: {cancelled.status}")

# Delete a completed, failed, or cancelled interaction before its 7-day TTL
client.interactions.delete(id="INTERACTION_ID")
print("Interaction deleted.")

TypeScript / JavaScript

import { GoogleGenAI } from "@google/genai";

const ai = new GoogleGenAI({
    enterprise: true,
    project: "PROJECT_ID",
    location: "global",
});

// Retrieve a stored interaction by ID
const interaction = await ai.interactions.get("INTERACTION_ID");
console.log(`Status: ${interaction.status}`);

// Cancel an in-progress background interaction
const cancelled = await ai.interactions.cancel("INTERACTION_ID");
console.log(`After cancel: ${cancelled.status}`);

// Delete a completed, failed, or cancelled interaction before its 7-day TTL
await ai.interactions.delete("INTERACTION_ID");
console.log("Interaction deleted.");

Java

import com.google.genai.Client;
import com.google.genai.gaos.models.interactions.Interaction;
import com.google.genai.gaos.models.interactions.InteractionStatus;
import com.google.genai.gaos.models.operations.CancelInteractionByIdResponse;
import com.google.genai.gaos.models.operations.GetInteractionByIdRequest;
import com.google.genai.gaos.models.operations.GetInteractionByIdResponse;

Client client =
    Client.builder()
        .enterprise(true)
        .project("PROJECT_ID")
        .location("global")
        .build();

String interactionId = "INTERACTION_ID";

// Retrieve a stored interaction by ID
GetInteractionByIdResponse getResponse =
    client.interactions.get(new GetInteractionByIdRequest(interactionId));
Interaction interaction = getResponse.interaction().orElseThrow();
System.out.println("Status: " + interaction.status().map(InteractionStatus::value).orElse(""));

// Cancel an in-progress background interaction
CancelInteractionByIdResponse cancelResponse = client.interactions.cancel(interactionId);
Interaction cancelled = cancelResponse.interaction().orElseThrow();
System.out.println("After cancel: " + cancelled.status().map(InteractionStatus::value).orElse(""));

// Delete a completed, failed, or cancelled interaction before its 7-day TTL
client.interactions.delete(interactionId);
System.out.println("Interaction deleted.");

REST

# Retrieve a stored interaction by ID
curl -X GET "https://aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/global/interactions/INTERACTION_ID" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)"

# List stored interactions (up to 500 per page)
curl -X GET "https://aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/global/interactions?page_size=10" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)"

# Cancel an in-progress background interaction
curl -X POST "https://aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/global/interactions/INTERACTION_ID/cancel" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)"

# Delete a completed, failed, or cancelled interaction
curl -X DELETE "https://aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/global/interactions/INTERACTION_ID" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)"

有狀態儲存空間配額和限制

除了模型權杖和要求比率限制外,有狀態互動 (store=True) 也受限於下列專案層級的儲存空間和並行限制:

配額或系統限制 預設限制 (每項專案) 說明
每日有狀態互動建立處理量 每天 240 GiB 班 在 interactions.create 個要求中,每天寫入伺服器端儲存空間的互動資料總量上限 (store=true)。
每日有狀態互動擷取處理量 每天 480 GiB 班 每天透過 interactions.get 要求和使用 previous_interaction_id 載入先前對話的多輪要求,讀取的互動資料儲存總量上限。
並行有狀態互動 500 項並行互動 專案中同時執行的有狀態互動數量上限。

如要進一步瞭解如何在 Agent Platform 查看及管理配額,請參閱「配額和系統限制」。

即時串流回覆

如要縮短互動式應用程式的感知延遲時間,可以在生成模型回覆時,以串流方式輸出。呼叫 interactions.create 時,請設定 stream=True (TypeScript/JavaScript 為 stream: true),接收伺服器傳送事件的可疊代串流。篩選 step.delta 事件,在收到遞增文字區塊時算繪:

Python

response = client.interactions.create(
    model="gemini-3.8-flash",
    input="Write a short poem about debugging.",
    stream=True,
)

for event in response:
    if event.event_type == "step.delta" and hasattr(event.delta, "text"):
        print(event.delta.text, end="", flush=True)
print()

TypeScript / JavaScript

const responseStream = await ai.interactions.create({
    model: "gemini-3.8-flash",
    input: "Write a short poem about debugging.",
    stream: true,
});

for await (const event of responseStream) {
    if (event.event_type === "step.delta" && event.delta && "text" in event.delta) {
        process.stdout.write(event.delta.text);
    }
}
console.log();

生成結構化輸出內容

如果應用程式需要可預測、機器可讀的回覆格式,您可以限制模型輸出內容,使其符合特定 JSON 結構定義。直接將目標結構定義 (例如 Python 中的 Pydantic 模型 JSON 結構定義,或 TypeScript/JavaScript 中的 Type 結構定義物件) 傳遞至多型 response_format 參數:

Python

from pydantic import BaseModel, Field

class Book(BaseModel):
    title: str = Field(description="The title of the book")
    author: str = Field(description="The book's author")
    year_published: int

interaction = client.interactions.create(
    model="gemini-3.8-flash",
    input="Recommend one famous sci-fi book.",
    response_format=Book.model_json_schema(),
)

# The output text is valid JSON matching the Book schema
print(interaction.output_text)

TypeScript / JavaScript

import { Type } from "@google/genai";

const BookSchema = {
    type: Type.OBJECT,
    properties: {
        title: { type: Type.STRING, description: "The title of the book" },
        author: { type: Type.STRING, description: "The book's author" },
        yearPublished: { type: Type.INTEGER },
    },
    required: ["title", "author", "yearPublished"],
};

const interaction = await ai.interactions.create({
    model: "gemini-3.8-flash",
    input: "Recommend one famous sci-fi book.",
    response_format: BookSchema,
});

console.log(interaction.output_text);

使用函式呼叫 (工具使用)

模型可透過呼叫函式,要求執行自訂函式或外部 API,以便在生成最終回覆前收集資訊。在有狀態的互動工作流程中,呼叫函式會遵循雙輪模式:

  1. 宣告並傳遞工具:在初始要求的 tools 參數中提供函式宣告。

  2. 執行並傳回結果:檢查回應步驟 (interaction.steps) 是否有 function_call 步驟,使用模型提供的 arguments 執行本機函式,並傳送後續互動,其中包含由 call_id 和 previous_interaction_id 連結的 function_result 項目。

Python

# Define a declarative function tool schema
stock_tool = {
    "type": "function",
    "name": "get_stock_price",
    "description": "Gets the stock price for a given ticker symbol.",
    "parameters": {
        "type": "object",
        "properties": {
            "ticker": {"type": "string", "description": "The stock ticker symbol"}
        },
        "required": ["ticker"],
    },
}

def get_stock_price(ticker: str) -> float:
    """Executes the local tool function."""
    if ticker.upper() == "GOOG":
        return 175.50
    return 100.0

# Turn 1: Pass the tool declaration to the model
interaction = client.interactions.create(
    model="gemini-3.8-flash",
    input="What is the stock price of GOOG?",
    tools=[stock_tool],
)

# Inspect the interaction steps for function call requests
for step in interaction.steps:
    if step.type == "function_call" and step.name == "get_stock_price":
        ticker_arg = step.arguments.get("ticker")
        price = get_stock_price(ticker_arg)

        # Turn 2: Submit the function execution result to the conversation
        final_turn = client.interactions.create(
            model="gemini-3.8-flash",
            input=[{
                "type": "function_result",
                "call_id": step.id,
                "result": {"price": price},
            }],
            previous_interaction_id=interaction.id,
        )
        print(final_turn.output_text)

TypeScript / JavaScript

// Define a declarative function tool schema
const stockTool = {
    type: "function",
    name: "getStockPrice",
    description: "Gets the stock price for a given ticker symbol.",
    parameters: {
        type: "object",
        properties: {
            ticker: { type: "string", description: "The stock ticker symbol" },
        },
        required: ["ticker"],
    },
};

function getStockPrice({ ticker }: { ticker: string }): number {
    if (ticker.toUpperCase() === "GOOG") return 175.50;
    return 100.00;
}

// Turn 1: Pass the tool declaration to the model
const interaction = await ai.interactions.create({
    model: "gemini-3.8-flash",
    input: "What is the stock price of GOOG?",
    tools: [stockTool],
});

// Inspect the interaction steps for function call requests
for (const step of interaction.steps ?? []) {
    if (step.type === "function_call" && step.name === "getStockPrice") {
        const tickerArg = step.arguments.ticker as string;
        const price = getStockPrice({ ticker: tickerArg });

        // Turn 2: Submit the function execution result to the conversation
        const finalTurn = await ai.interactions.create({
            model: "gemini-3.8-flash",
            input: [{
                type: "function_result",
                call_id: step.id,
                result: { price },
            }],
            previous_interaction_id: interaction.id,
        });
        console.log(finalTurn.output_text);
    }
}

使用內建工具

除了用戶端呼叫函式,Interactions API 也支援 Gemini 3 模型的內建伺服器端工具。在 tools 參數中啟用內建工具時,Agent Platform 會在單一 interactions.create 呼叫期間,於伺服器上執行該工具,並在 interaction.steps 中記錄工具叫用 (*_call) 和輸出 (*_result) 步驟。

Interactions API 支援下列內建工具:

  • 執行程式碼 ({"type": "code_execution"}):在沙箱環境中生成及執行 Python 程式碼,進行計算、資料分析和程式碼推理。如要瞭解支援的程式庫、計費方式和限制,請參閱「執行程式碼」。

  • 網址脈絡 ({"type": "url_context"}):擷取並分析提示中公開網址的內容。如要進一步瞭解索引快取、即時擷取,以及結合網址背景資訊和搜尋功能,請參閱「網址背景資訊」。

  • 以 Google 搜尋強化事實基礎 ({"type": "google_search"}):以即時網路資訊強化模型回覆的事實基礎,並傳回內嵌引用。請參閱「利用 Google 搜尋建立回覆基準」。

  • 電腦使用 ({"type": "computer_use"}):啟用瀏覽器和使用者介面自動化工作流程。如需設定和安全控制項,請參閱「電腦使用」。

執行 Python 程式碼

如要啟用執行程式碼功能,請在 tools 清單中加入 {"type": "code_execution"}。傳回的 interaction.steps 陣列包含 code_execution_call 步驟 (含 arguments.code 和 arguments.language)、code_execution_result 步驟 (含 result 和 is_error),以及最終的 model_output 步驟。

在下列範例中,請將 PROJECT_ID 替換為您的 Google Cloud專案 ID:

Python

from google import genai

client = genai.Client(
    enterprise=True,
    project="PROJECT_ID",
    location="global",
)

interaction = client.interactions.create(
    model="gemini-3.8-flash",
    input="Calculate the 50th Fibonacci number and find its closest prime.",
    tools=[{"type": "code_execution"}],
)

for step in interaction.steps:
    if step.type == "code_execution_call":
        print(f"Generated code:\n{step.arguments.code}")
    elif step.type == "code_execution_result":
        print(f"Execution result:\n{step.result}")
    elif step.type == "model_output":
        for content in step.content:
            if content.type == "text":
                print(content.text)

TypeScript / JavaScript

import { GoogleGenAI } from "@google/genai";

const ai = new GoogleGenAI({
    enterprise: true,
    project: "PROJECT_ID",
    location: "global",
});

const interaction = await ai.interactions.create({
    model: "gemini-3.8-flash",
    input: "Calculate the 50th Fibonacci number and find its closest prime.",
    tools: [{ type: "code_execution" }],
});

for (const step of interaction.steps ?? []) {
    if (step.type === "code_execution_call") {
        console.log(`Generated code:\n${step.arguments?.code}`);
    } else if (step.type === "code_execution_result") {
        console.log(`Execution result:\n${step.result}`);
    } else if (step.type === "model_output") {
        for (const content of step.content ?? []) {
            if (content.type === "text") {
                console.log(content.text);
            }
        }
    }
}

Java

import com.google.genai.Client;
import com.google.genai.gaos.models.interactions.CodeExecution;
import com.google.genai.gaos.models.interactions.CodeExecutionCallStep;
import com.google.genai.gaos.models.interactions.CodeExecutionResultStep;
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.interactions.Step;
import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;
import java.util.List;

Client client =
    Client.builder()
        .enterprise(true)
        .project("PROJECT_ID")
        .location("global")
        .build();

CreateModelInteraction request =
    CreateModelInteraction.builder()
        .model(Model.of("gemini-3.8-flash"))
        .input(
            InteractionsInput.of(
                "Calculate the 50th Fibonacci number and find its closest prime."))
        .tools(List.of(CodeExecution.builder().build()))
        .build();

Interaction interaction =
    client.interactions.create(CreateInteractionRequestBody.of(request)).interaction().orElseThrow();

for (Step step : interaction.steps().orElse(List.of())) {
    if (step instanceof CodeExecutionCallStep callStep) {
        callStep
            .arguments()
            .flatMap(args -> args.code())
            .ifPresent(code -> System.out.println("Generated code:\n" + code));
    } else if (step instanceof CodeExecutionResultStep resultStep) {
        resultStep
            .result()
            .ifPresent(res -> System.out.println("Execution result:\n" + res));
    }
}
System.out.println(interaction.outputText().orElse(""));

REST

curl -X POST "https://aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/global/interactions" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gemini-3.8-flash",
    "input": "Calculate the 50th Fibonacci number and find its closest prime.",
    "tools": [{"type": "code_execution"}]
  }'

使用網址背景資訊擷取網頁內容

如要讓模型擷取及分析提示中參照的網頁,請在 tools 清單中加入 {"type": "url_context"}。API 會在 url_context_call 和 url_context_result 步驟中記錄擷取的網址,並在 model_output 中將 url_citation 註解附加至生成的文字。

在下列範例中,請將 PROJECT_ID 替換為您的 Google Cloud專案 ID,並將 YOUR_URL_1 和 YOUR_URL_2 替換為要比較的公開網址:

Python

from google import genai

client = genai.Client(
    enterprise=True,
    project="PROJECT_ID",
    location="global",
)

interaction = client.interactions.create(
    model="gemini-3.8-flash",
    input="Compare the key findings from YOUR_URL_1 and YOUR_URL_2.",
    tools=[{"type": "url_context"}],
)

print(interaction.output_text)

TypeScript / JavaScript

import { GoogleGenAI } from "@google/genai";

const ai = new GoogleGenAI({
    enterprise: true,
    project: "PROJECT_ID",
    location: "global",
});

const interaction = await ai.interactions.create({
    model: "gemini-3.8-flash",
    input: "Compare the key findings from YOUR_URL_1 and YOUR_URL_2.",
    tools: [{ type: "url_context" }],
});

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.interactions.URLContext;
import com.google.genai.gaos.models.operations.CreateInteractionRequestBody;
import java.util.List;

Client client =
    Client.builder()
        .enterprise(true)
        .project("PROJECT_ID")
        .location("global")
        .build();

CreateModelInteraction request =
    CreateModelInteraction.builder()
        .model(Model.of("gemini-3.8-flash"))
        .input(
            InteractionsInput.of(
                "Compare the key findings from YOUR_URL_1 and YOUR_URL_2."))
        .tools(List.of(URLContext.builder().build()))
        .build();

Interaction interaction =
    client.interactions.create(CreateInteractionRequestBody.of(request)).interaction().orElseThrow();

System.out.println(interaction.outputText().orElse(""));

REST

curl -X POST "https://aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/global/interactions" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gemini-3.8-flash",
    "input": "Compare the key findings from YOUR_URL_1 and YOUR_URL_2.",
    "tools": [{"type": "url_context"}]
  }'

利用 Google 搜尋建立回覆基準

建立基準可將 Gemini 模型連結至可驗證的外部來源,減少幻覺,並提供附有引用來源的最新答案。如要概略瞭解 Agent Platform 的建立基準選項,請參閱「建立基準總覽」、「以 Google 搜尋強化事實基礎」和「企業版網路建立基準」。

在 tools 清單中傳遞 {"type": "google_search"},啟用「以 Google 搜尋強化事實基礎」功能後,Interactions API 會直接在 interaction.steps 時間軸中傳回搜尋和出處資料:

  • google_search_call:包含模型 (step.arguments.queries) 發出的搜尋查詢。

  • google_search_result:包含搜尋建議 (result[].search_suggestions),這是一段 HTML/CSS 程式碼片段,用於在使用者介面中顯示搜尋建議。含有來源網址和標題的網路資源,會以內嵌 url_citation 註解的形式,顯示在 model_output 文字區塊上。

  • 內嵌 url_citation 註解:model_output 步驟中的每個 text 內容區塊 (TextContent) 都可以包含 annotations 陣列。每個 url_citation 註解都會識別回覆文字中的字元或位元組範圍 (start_index 和 end_index),以及來源 title 和 url。

在下列範例中,請將 PROJECT_ID 替換為您的 Google Cloud專案 ID:

Python

from google import genai

client = genai.Client(
    enterprise=True,
    project="PROJECT_ID",
    location="global",
)

interaction = client.interactions.create(
    model="gemini-3.8-flash",
    input="Who won the 2026 Super Bowl?",
    tools=[{"type": "google_search"}],
)

print(interaction.output_text)

# Parse inline url_citation annotations from model_output steps
print("\nSources:")
for step in interaction.steps:
    if step.type == "model_output" and step.content:
        for content in step.content:
            if content.type == "text" and getattr(content, "annotations", None):
                for annotation in content.annotations:
                    if annotation.type == "url_citation":
                        span = content.text[annotation.start_index:annotation.end_index]
                        print(f"- [{annotation.title}]({annotation.url}) (cited text: {span!r})")

TypeScript / JavaScript

import { GoogleGenAI } from "@google/genai";

const ai = new GoogleGenAI({
    enterprise: true,
    project: "PROJECT_ID",
    location: "global",
});

const interaction = await ai.interactions.create({
    model: "gemini-3.8-flash",
    input: "Who won the 2026 Super Bowl?",
    tools: [{ type: "google_search" }],
});

console.log(interaction.output_text);

// Parse inline url_citation annotations from model_output steps
console.log("\nSources:");
for (const step of interaction.steps ?? []) {
    if (step.type === "model_output") {
        for (const content of step.content ?? []) {
            if (content.type === "text" && content.annotations) {
                for (const annotation of content.annotations) {
                    if (annotation.type === "url_citation") {
                        const span = content.text.slice(
                            annotation.start_index,
                            annotation.end_index,
                        );
                        console.log(
                            `- [${annotation.title}](${annotation.url}) (cited text: "${span}")`,
                        );
                    }
                }
            }
        }
    }
}

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.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.List;

Client client =
    Client.builder()
        .enterprise(true)
        .project("PROJECT_ID")
        .location("global")
        .build();

CreateModelInteraction request =
    CreateModelInteraction.builder()
        .model(Model.of("gemini-3.8-flash"))
        .input(InteractionsInput.of("Who won the 2026 Super Bowl?"))
        .tools(List.of(GoogleSearch.builder().build()))
        .build();

Interaction interaction =
    client.interactions.create(CreateInteractionRequestBody.of(request)).interaction().orElseThrow();

System.out.println(interaction.outputText().orElse(""));

// Parse inline URLCitation annotations from ModelOutputStep blocks
System.out.println("\nSources:");
for (Step step : interaction.steps().orElse(List.of())) {
    if (step instanceof ModelOutputStep outputStep) {
        for (Content content : outputStep.content().orElse(List.of())) {
            if (content instanceof TextContent textContent) {
                for (Annotation annotation : textContent.annotations().orElse(List.of())) {
                    if (annotation instanceof URLCitation citation) {
                        System.out.printf(
                            "- %s: %s (span: %d..%d)%n",
                            citation.title().orElse(""),
                            citation.url().orElse(""),
                            citation.startIndex().orElse(0L),
                            citation.endIndex().orElse(0L));
                    }
                }
            }
        }
    }
}

REST

# Request
curl -X POST "https://aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/global/interactions" \
  -H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gemini-3.8-flash",
    "input": "Who won the 2026 Super Bowl?",
    "tools": [{"type": "google_search"}]
  }'

回應包含 google_search_call、google_search_result 和 model_output 步驟,並附有內嵌 url_citation 註解:

{
  "id": "v1_ChdPU0F4YWFtNkFwS2kxZThQZ05lbXdROA",
  "model": "gemini-3.8-flash",
  "status": "completed",
  "steps": [
    {
      "type": "google_search_call",
      "id": "search_call_1",
      "arguments": {
        "queries": ["2026 Super Bowl winner"]
      }
    },
    {
      "type": "google_search_result",
      "call_id": "search_call_1",
      "result": [
        {
          "search_suggestions": "<!-- HTML and CSS for search suggestions -->"
        }
      ]
    },
    {
      "type": "model_output",
      "content": [
        {
          "type": "text",
          "text": "The Seattle Seahawks won Super Bowl LX on February 8, 2026.",
          "annotations": [
            {
              "type": "url_citation",
              "start_index": 0,
              "end_index": 59,
              "title": "Super Bowl LX",
              "url": "https://example.com/super-bowl-lx"
            }
          ]
        }
      ]
    }
  ]
}

執行代理和長期執行的背景工作

除了基礎模型,Interactions API 還可讓您使用 agent 參數叫用專門的自主代理:

  • antigravity-preview-05-2026:一般用途的代管代理,可在安全的沙箱 Linux 環境中執行程式碼、管理檔案及瀏覽網頁。詳情請參閱「與代理互動」。
  • deep-research-preview-04-2026:Gemini Deep Research 代理,可規劃及執行多步驟網路研究工作,並將多個來源的結果彙整成詳盡報告。詳情請參閱「使用 Gemini Deep Research 代理」。
  • 自訂代理:使用 client.agents.create() 設定及佈建的自訂代理資源。

代理工作流程通常需要幾分鐘才能完成,因此請設定 background=True,在背景以非同步方式執行。API 會立即傳回 Interaction 物件,其中包含 id,您可以使用 client.interactions.get() 輪詢,直到 interaction.status 轉換為 completed:

嘗試這個範例前,請將 PROJECT_ID 替換為您的Google Cloud 專案 ID。

import time
from google import genai

client = genai.Client(
    enterprise=True,
    project="PROJECT_ID",
    location="global",
)

interaction = client.interactions.create(
    input="Analyze competitive positioning for solar energy providers.",
    agent="deep-research-preview-04-2026",
    background=True,
)

print(f"Research started: {interaction.id}")

while True:
    interaction = client.interactions.get(interaction.id)
    if interaction.status == "completed":
        print(interaction.output_text)
        break
    elif interaction.status in ("failed", "cancelled"):
        print(f"Research ended with status: {interaction.status}")
        break
    time.sleep(10)

存取上傳的 Cloud Storage 檔案

您可以使用 Interactions API 存取上傳的 Cloud Storage 檔案。在下列範例中,請將 PROJECT_ID 替換為您的Google Cloud 專案 ID:

from google import genai

# Credentials must belong to an identity with storage.objects.get permissions
client = genai.Client(
    enterprise=True,
    project="PROJECT_ID",
    location="global",
)

interaction = client.interactions.create(
    model="gemini-3.8-flash",
    input=[
        {
            "type": "user_input",
            "content": [
                {"type": "text", "text": "Summarize the attached document:"},
                {
                    "type": "document",
                    "uri": "gs://my-secure-bucket/quarterly_report.pdf",
                    "mime_type": "application/pdf",
                },
            ],
        }
    ],
)

print(interaction.output_text)

將 Cloud Storage URI (例如 gs://bucket-name/path/to/file) 傳遞至 Interactions API 時,要求會先使用呼叫者的憑證驗證讀取權限,然後呼叫專案的 Agent Platform 服務代理 (service-PROJECT_NUMBER@gcp-sa-aiplatform.) 才會從 Cloud Storage 擷取物件。

如要在互動要求中傳遞 Cloud Storage 檔案,呼叫主體 (使用者帳戶、服務帳戶或聯合身分) 必須具備所有參照物件的 storage.objects.get 權限。如果是跨專案 Cloud Storage bucket 或具有自訂 IAM 政策的 Cloud Storage bucket,請將讀取權限授予呼叫主體和呼叫專案的服務代理。

每項標準 Gemini 模型互動要求最多支援 100 個不同的 Cloud Storage (gs://) URI (每個檔案最多 2 GiB 減 500 KiB)。使用 previous_interaction_id 鏈結有狀態的回合時,Agent Platform 會累計對話記錄和目前回合中的不重複 gs:// URI。代管代理互動 (設定 agent 而非 model 的要求)、Gemini Omni 模型和 Lyria 3 模型不受這項 100 個 URI 的限制。

設定存取 Cloud Storage 檔案的 IAM 角色

授予包含 storage.objects.get 權限的其中一個標準預先定義角色:

  • Storage 物件檢視者 (roles/storage.objectViewer):物件的讀取權限 (建議)。

  • Storage 物件使用者 (roles/storage.objectUser):具備物件的讀取和寫入權限。

如要使用 Google Cloud CLI 授予使用者帳戶存取權,請使用下列指令:

gcloud storage buckets add-iam-policy-binding gs://BUCKET_NAME \
    --member="user:user-email@example.com" \
    --role="roles/storage.objectViewer"

如要將存取權授予特定呼叫服務帳戶,請使用下列指令:

gcloud storage buckets add-iam-policy-binding gs://BUCKET_NAME \
    --member="serviceAccount:sa-name@PROJECT_ID." \
    --role="roles/storage.objectViewer"

排解 Cloud Storage 檔案存取問題

如果呼叫主體的權限不足,Interactions API 會傳回類似下列的 403 Forbidden 錯誤:

Access error:
PERMISSION_DENIED - 403 Forbidden: Calling principal lacks
storage.objects.get on one or more Cloud Storage URIs.

如要解決這個問題,請將 Cloud Storage bucket 或物件的 Storage 物件檢視者角色 (roles/storage.objectViewer) 授予已驗證的呼叫端 (以及呼叫專案的代理平台服務代理,用於跨專案或自訂 IAM Cloud Storage bucket)。

如果指定的物件不存在,或 bucket 權限導致呼叫端無法查看物件是否存在,Interactions API 會傳回類似下方的 404 Not Found 錯誤:

Access error:
NOT_FOUND - 404 Not Found: The object does not exist, or bucket
permissions prevent revealing object existence.

如要解決這個問題,請確認 Cloud Storage URI 正確無誤,並確認已驗證的呼叫端具備 bucket 的讀取權限。

如果模型互動要求在目前對話和任何連結的 previous_interaction_id 歷史記錄中,參照超過 100 個不同的 Cloud Storage URI,Interactions API 會傳回類似下列的 400 Bad Request 錯誤:

INVALID_ARGUMENT - 400 Bad Request: Request references 101 distinct gs:// URIs, which exceeds the maximum of 100.

如要解決這個問題,請按照下列其中一種做法進行:

  • 如果不再需要先前對話中的檔案,請在不使用 previous_interaction_id 的情況下展開新互動。
  • 合併較小的文件,或在要求酬載限制內傳遞其他內嵌檔案 (同步或串流要求壓縮後為 256 MiB,或 service_tier 設為 deferred,且 background 和 store 設為 true 時,未壓縮為 9.75 MiB)。
  • 如果要求參照 gs:// URI,請使用 generateContent,但不得超過各模態的模型項目限制 (圖片和 PDF 合計 3,000 個、音訊檔案 1,000 個、影片 10 部,或包含純文字檔案時最多 6,500 個檔案)。

使用 CMEK 加密互動資料

有狀態互動 (Python 中的 store=True 或 TypeScript/JavaScript 中的 store: true) 會將互動資料儲存最多 7 天。如要使用自己的加密金鑰 (而非Google-owned and Google-managed encryption key) 保護資料,請使用服務設定檔。服務設定檔會將 Cloud Key Management Service 金鑰連結至專案、位置和 API 範圍。只要有服務設定檔,Agent Platform 就會自動加密儲存的互動資料,互動要求格式不會改變。

Interactions API 的供應設定檔 CMEK 支援 us 和 eu 多區域。不支援「global」區域。

如要為 Interactions API 設定 CMEK,請按照下列步驟操作:

  1. 在專案中啟用 Cloud KMS API 和 Agent Platform API。請參閱事前準備一節。
  2. 在 us 或 eu 多區域中建立 Cloud KMS 金鑰。請參閱「建立金鑰環和金鑰」。
  3. 將金鑰的 roles/cloudkms.cryptoKeyEncrypterDecrypter 角色授予 Gemini Enterprise Agent Platform 服務代理。請參閱「授予 Agent Platform 權限」。
  4. 在同一個多區域 (us 或 eu) 建立服務設定檔,將 scope 設為 INTERACTIONS_API,並將 cmekConfig.encryptionSpec.kmsKeyName 設為您的金鑰:

    curl -X POST \
      -H "Authorization: Bearer $(gcloud auth print-access-token)" \
      -H "Content-Type: application/json" \
      "https://aiplatform.LOCATION.rep.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/servingProfiles?servingProfileId=SERVING_PROFILE_ID" \
      -d '{
        "displayName": "Interactions API CMEK profile",
        "description": "CMEK for Interactions API",
        "scope": "INTERACTIONS_API",
        "cmekConfig": {
          "encryptionSpec": {
            "kmsKeyName": "projects/KMS_PROJECT_ID/locations/LOCATION/keyRings/KEY_RING_NAME/cryptoKeys/KEY_NAME"
          }
        }
      }'
    

    等待長時間執行的建立作業完成 ("done": true)。如要進一步瞭解如何管理、更新或刪除供應設定檔,請參閱「建立供應設定檔」。

  5. 將互動要求傳送至與供應設定檔相同的 us 或 eu 多區域。global 端點不支援供應設定檔 CMEK。

    • Google Gen AI SDK:使用 location="us" 或 location="eu" (TypeScript/JavaScript 為 location: "us" 或 location: "eu") 初始化用戶端。
    • REST:將要求傳送至多區域端點 https://aiplatform.LOCATION.rep.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/interactions,其中 LOCATION 為 us 或 eu。

    如果停用金鑰或撤銷服務代理的存取權,建立或讀取儲存互動的要求會失敗,並傳回 FAILED_PRECONDITION 錯誤。

進階 REST 工作流程

如果是以殼層為基礎的自動化作業、CI/CD 管道,或沒有 Python 或 TypeScript/JavaScript 執行階段的環境,您可以使用 curl,直接透過 HTTP 呼叫 Interactions API。

REST 端點

將 POST 要求傳送至下列 Interactions API 端點:

POST https://aiplatform.googleapis.com/v1/projects/PROJECT_ID/locations/LOCATION/interactions

請替換要求中的下列變數:

  • PROJECT_ID: Google Cloud 專案 ID。
  • LOCATION:設為 global (或 us 或 eu,並搭配資料落地或 CMEK 的多區域主機 https://aiplatform.LOCATION.rep.googleapis.com)。

設定環境變數和驗證

執行下列各節中的 curl 範例之前,請先匯出專案 ID、目標模型或代理 ID,以及從應用程式預設憑證產生的 OAuth 2.0 存取權杖:

PROJECT_ID="PROJECT_ID"
MODEL_ID="gemini-3.8-flash"
AGENT_ID="deep-research-preview-04-2026"
ACCESS_TOKEN=$(gcloud auth print-access-token)

同步回應格式

同步 POST 要求會傳回 JSON interaction 物件,其中包含不重複的互動 id、執行 status、對話 steps 和權杖 usage 中繼資料:

{
  "id": "your-interaction-id",
  "status": "completed",
  "steps": [
    {
      "type": "model_output",
      "content": [
        {
          "type": "text",
          "text": "Serverless computing is a cloud execution model where the cloud provider dynamically manages the allocation and provisioning of servers, charging customers based on actual usage rather than pre-purchased capacity."
        }
      ]
    }
  ],
  "usage": {
    "total_tokens": 24751,
    "total_input_tokens": 23894,
    "total_output_tokens": 857
  },
  "created": "2026-05-08T10:44:43Z",
  "updated": "2026-05-08T10:44:43Z",
  "environment_id": "your-environment-id",
  "object": "interaction"
}

繼續多輪有狀態互動

如要透過 REST 繼續儲存的對話,請將先前回應中的 id 傳遞至 JSON 要求主體的 previous_interaction_id 欄位。

嘗試這個範例前,請先將 PREVIOUS_INTERACTION_ID 替換為先前互動傳回的 id。

curl -X POST "https://aiplatform.googleapis.com/v1/projects/${PROJECT_ID}/locations/global/interactions" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "'"${MODEL_ID}"'",
    "store": true,
    "previous_interaction_id": "PREVIOUS_INTERACTION_ID",
    "input": [{
      "type": "user_input",
      "content": [{
        "type": "text",
        "text": "Can you elaborate on that?"
      }]
    }]
  }'

使用伺服器傳送事件串流輸出內容

如要透過 REST 串流傳輸增量更新,請在 JSON 要求主體中加入 "stream": true:

curl -X POST "https://aiplatform.googleapis.com/v1/projects/${PROJECT_ID}/locations/global/interactions" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "'"${MODEL_ID}"'",
    "stream": true,
    "input": [{
      "type": "user_input",
      "content": [{
        "type": "text",
        "text": "Write a long story about space travel."
      }]
    }]
  }'

設定 "stream": true 時,伺服器會回應 Transfer-Encoding: chunked 和 Content-Type: text/event-stream (伺服器傳送事件)。串流中的每個事件都包含 data: 前置字元,其中含有 JSON 酬載,內含 event_type 和步驟差異內容。curl 會自動保持 HTTP 連線開啟,並即時將傳入的區塊寫入 stdout,直到互動完成。

在背景執行代管代理

如要透過 REST 非同步啟動長時間執行的代管代理程式工作,請指定目標 agent、設定 "background": true,並設定 "environment": "remote":

curl -X POST "https://aiplatform.googleapis.com/v1/projects/${PROJECT_ID}/locations/global/interactions" \
  -H "Authorization: Bearer ${ACCESS_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "agent": "'"${AGENT_ID}"'",
    "environment": "remote",
    "background": true,
    "input": [{
      "type": "user_input",
      "content": [{
        "type": "text",
        "text": "Analyze competitive positioning for commercial solar energy providers."
      }]
    }]
  }'

後續步驟

請參閱下列資源,進一步瞭解 Interactions API、內建工具和建立基準: