Module 3 of 7 · 56 min

Build Reliable Gemini API Workflows

Use the Google Gen AI SDK with environment-based credentials, configurable models, explicit conversation state, typed candidate handling, validation, bounded recovery, and privacy-safe evidence.

Google

By the end

You will be able to

  • Explain Gemini API request, candidate, content-part, finish, safety, and usage contracts.
  • Use the Google Gen AI SDK with environment-based credentials and model configuration.
  • Own conversation state and validate candidate content before downstream use.
  • Classify API failures, retry safely, and preserve privacy-reviewed operational evidence.
01

Treat responses as structured candidates

A Gemini content-generation request identifies a model, contents, and optional system instruction, generation, safety, tool, or output controls. A response can contain candidates, content parts, finish information, safety signals, citations or grounding metadata, and usage. Do not assume every success is one plain string.

Convenience text access is useful only after the workflow has checked the response contract. Inspect whether a candidate exists, which parts are present, why generation stopped, and whether safety or other conditions require a refusal, recovery, or escalation path.

02

Configure credentials and models

Load GEMINI_API_KEY from the runtime environment or a managed secret store and fail closed when it is absent. Keep keys out of source, prompts, logs, client-side bundles, learner evidence, and screenshots; restrict, rotate, and revoke them according to current Google guidance.

Keep model identifiers, API version, output limits, timeout, retry budget, safety configuration, and storage decisions in reviewed configuration. Verify currently supported values and credentials for the actual Gemini API or Google Cloud deployment rather than assuming one setup fits every environment.

Secret-safe Gemini SDK boundary
typescript
import { GoogleGenAI } from "@google/genai";

const model = process.env.GEMINI_MODEL;
if (!process.env.GEMINI_API_KEY || !model) {
  throw new Error("Gemini API configuration is incomplete");
}

const client = new GoogleGenAI({ apiKey: process.env.GEMINI_API_KEY });
const response = await client.models.generateContent({
  model,
  contents: approvedInput,
  config: { systemInstruction: "Return an evidence-linked risk summary." },
});

const candidate = response.candidates?.[0];
if (!candidate) {
  await handleBlockedOrEmptyResponse(response.promptFeedback);
  throw new Error("Gemini returned no candidate");
}
switch (candidate.finishReason) {
  case "STOP": break;
  case "SAFETY": await handleSafetyStop(candidate.safetyRatings); throw new Error("Safety stop");
  case "MAX_TOKENS": await handleTruncatedOutput(candidate.content); throw new Error("Output limit");
  case "RECITATION": await handleRecitationStop(); throw new Error("Recitation stop");
  default: throw new Error(`Unhandled finish outcome: ${candidate.finishReason ?? "none"}`);
}
for (const part of candidate.content?.parts ?? []) {
  if (typeof part.text === "string") await handleValidatedText(part.text);
  else throw new Error("Unhandled Gemini content part");
}
03

Own conversation state explicitly

Multi-turn chat helpers preserve or resend conversation history according to their SDK contract; they do not remove application responsibility. Define which user and model turns, files, tool results, summaries, and identifiers are retained and supplied on later requests.

Set truncation, summarization, branching, privacy, deletion, and recovery policy deliberately. A transcript shown in a UI, state held by a client object, and durable application records are different things and must not be conflated.

04

Validate finish, parts, and output

Route normal completion, output limits, safety blocks, recitation, malformed function calls, cancellation, and unknown finish outcomes separately using the current documented enums. Handle text, function requests, executable code, media, and other supported parts only when the workflow contract permits them.

Validate schemas, required evidence, citations, lengths, allowed values, and business rules before downstream use. Provider transport success, model completion, application validation, and external postcondition success are separate states.

05

Recover and observe with bounds

Classify failures before retrying. Rate limits and transient service failures may use provider guidance, exponential backoff with jitter, maximum attempts, and an end-to-end deadline. Invalid arguments, permissions, blocked keys, unsupported models, and application validation failures require correction.

Record correlation, application and prompt versions, configured model reference, latency, usage, finish outcome, part types, validation, retry count, and terminal state under an allowlist. Exclude keys, authorization headers, sensitive raw content, and unnecessary provider identifiers.

Practice activity

Design and test a Gemini API client

  1. Define a request contract with environment credentials, configurable model, system instruction, contents, output contract, timeout, retry budget, and trace identifier.
  2. Document conversation-state ownership, retention, summarization, deletion, privacy, branching, and recovery behavior.
  3. Implement or diagram handlers for normal text, safety block, output limit, unknown part, invalid output, authentication, permission, rate limit, timeout, cancellation, and service failure.
  4. Use synthetic request/response fixtures so no paid call is required; prove every terminal path and a telemetry allowlist without exposing credentials or sensitive content.

What to produce

  • A secret-free client implementation or design with typed candidate and part handling, state ownership, validation, bounded retries, and deterministic fixtures.
  • A state and telemetry record showing configuration versions, finish outcome, part types, usage, validation, retries, privacy controls, and terminal result.

Reflect before continuing

Which outcome in your client must be corrected or escalated instead of retried, and what evidence proves that decision?

Evidence

Sources and verification

Knowledge check

Make it stick.

Pass at 80%

Choose the strongest answer for each question. Your attempts become part of your device-local transcript.

01Why inspect candidates and parts before using response text?
02Where should a reusable application obtain its model identifier?
03Who owns retention when an SDK chat helper tracks turns?
04What should happen for an unsupported or unknown finish outcome?
05Which failure should not be retried unchanged?