Глава 25

Google: Gemini Interactions API и function_result

С июня 2026 года Interactions API у Google имеет статус GA и рекомендуется для новых Gemini-проектов. Model steps содержат function_call, а приложение продолжает разговор через previous_interaction_id и function_result. Это ближе к Responses, чем к stateless Messages, но со своими полями.

Минимальная версия SDK. Interactions API доступен в JavaScript-пакете @google/genai начиная с версии 2.3.0. Устанавливайте актуальную версию и фиксируйте реально проверенную сборку в lockfile.

Адаптер начинается с клиента и перевода определения tool.

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

const client = new GoogleGenAI({});
const model = process.env.GOOGLE_MODEL ?? "gemini-3.6-flash";

type GoogleState = {
  previousInteractionId: string;
  instructions: string;
  tools: ToolDefinition[];
};

function toGoogleTool(tool: ToolDefinition) {
  return {
    type: "function" as const,
    name: tool.name,
    description: tool.description,
    parameters: tool.parameters
  };
}

Первый interaction отправляет сообщение и tools, а состояние - это interaction.id.

TypeScript
async function start(input: AgentInput): Promise<ProviderTurn> {
  const interaction = await client.interactions.create({
    model,
    input: input.message,
    system_instruction: input.instructions,
    tools: input.tools.map(toGoogleTool),
    store: true
  });

  return fromGoogleInteraction(interaction, {
    previousInteractionId: interaction.id,
    instructions: input.instructions,
    tools: input.tools
  });
}

Продолжение возвращает результаты как function_result по previous_interaction_id.

TypeScript
async function resume(rawState: unknown, results: ToolResult[]) {
  const state = googleStateSchema.parse(rawState);
  const interaction = await client.interactions.create({
    model,
    previous_interaction_id: state.previousInteractionId,
    system_instruction: state.instructions,
    tools: state.tools.map(toGoogleTool),
    input: results.map(function toFunctionResult(result) {
      return {
        type: "function_result" as const,
        name: result.name,
        call_id: result.callId,
        result: [{
          type: "text" as const,
          text: JSON.stringify({ ok: !result.isError, value: result.output })
        }]
      };
    })
  });

  return fromGoogleInteraction(interaction, {
    ...state,
    previousInteractionId: interaction.id
  });
}

Нормализация steps сводит их к общему ProviderTurn.

TypeScript
function fromGoogleInteraction(interaction: any, state: GoogleState): ProviderTurn {
  const calls = interaction.steps
    .filter(function isCall(step: any) { return step.type === "function_call"; })
    .map(function normalize(step: any): ToolCall {
      return { id: step.id, name: step.name, arguments: step.arguments };
    });

  if (calls.length > 0) return { kind: "tool_calls", calls, state };
  return { kind: "text", text: interaction.output_text ?? "", state };
}

Две оговорки завершают адаптер. Первая - про то, что previous_interaction_id НЕ переносит.

Повторяйте interaction-scoped поля. previous_interaction_id сохраняет историю, но не переносит tools, system_instruction и generation_config. Адаптер обязан передавать их снова на каждом ходе.

Вторая - про то, когда всё же нужен старый generateContent.

Когда нужен legacy generateContent. Google сохраняет его поддержку. В актуальной документации explicit caching, Batch и некоторые специальные возможности пока остаются причиной использовать generateContent. Для нового обычного agent loop начинайте с Interactions.

У Google, как и у OpenAI, есть и полноценный фреймворк - ADK. Разберём, когда он оправдан.

Ссылки