Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/genkit-ai/genkit/llms.txt

Use this file to discover all available pages before exploring further.

A flow is a Genkit-managed function with typed inputs and outputs that wraps your AI logic. Every invocation is automatically traced end-to-end, appears in the Dev UI, and can be exposed as an HTTP endpoint for production use. Flows are the unit you deploy. Whether you’re building a simple Q&A endpoint or an agent with many steps, you define it as a flow.

Defining a flow

import { genkit, z } from 'genkit';
import { googleAI } from '@genkit-ai/google-genai';

const ai = genkit({
  plugins: [googleAI()],
  model: 'googleai/gemini-2.5-flash',
});

const summarizeFlow = ai.defineFlow(
  {
    name: 'summarize',
    inputSchema: z.object({ text: z.string() }),
    outputSchema: z.object({ summary: z.string() }),
  },
  async (input) => {
    const response = await ai.generate({
      prompt: `Summarize the following in one sentence:\n\n${input.text}`,
    });
    return { summary: response.text };
  }
);
inputSchema and outputSchema are Zod schemas. Genkit validates inputs and outputs against them automatically.

Calling a flow

Flows are callable like regular functions. They return the output value defined by the output schema.
const result = await summarizeFlow({ text: 'Genkit is an open-source framework...' });
console.log(result.summary);

Named steps with run

Use ai.run() (TypeScript) or genkit.Run() (Go) to give individual steps within a flow their own trace spans. This makes it easy to pinpoint exactly where time is spent in the Dev UI.
const ragFlow = ai.defineFlow('rag', async (query: string) => {
  const docs = await ai.run('retrieve', async () => {
    return myRetriever.retrieve(query);
  });

  const response = await ai.run('generate', async () => {
    return ai.generate({
      prompt: `Answer using these docs:\n${docs.join('\n')}\n\nQuestion: ${query}`,
    });
  });

  return response.text;
});

Flows as HTTP endpoints

Flows can be exposed as HTTP endpoints so that any HTTP client can invoke them. The request body is the flow’s input and the response body is its output.
Use onFlow from @genkit-ai/firebase or wrap the flow in an Express/Cloud Functions handler:
import { onFlow } from '@genkit-ai/firebase/functions';

export const summarize = onFlow(
  ai,
  {
    name: 'summarize',
    inputSchema: z.object({ text: z.string() }),
    outputSchema: z.object({ summary: z.string() }),
    authPolicy: ...,
  },
  async (input) => { /* ... */ }
);
Or serve all registered flows with Genkit’s built-in flow server:
import express from 'express';
import { expressHandler } from '@genkit-ai/express';

const app = express();
app.post('/summarize', expressHandler(summarizeFlow));
app.listen(3000);

Observability

Every flow run creates a trace that records:
  • Flow input and output
  • Every named run() step
  • Model calls, including prompts and responses
  • Tool calls and their outputs
  • Latency at each level
Traces are visible in the Genkit Dev UI during development and can be exported to Cloud Trace, Jaeger, or any OpenTelemetry-compatible backend in production.
The Dev UI starts automatically when you run genkit start (TypeScript/Python) or set GENKIT_ENV=dev (Go). Flows and their traces appear in the Flows and Traces panels.

Background flows

Some operations—like video generation or long-running batch jobs—take too long to return synchronously. Genkit supports background flows (also called operations) that return immediately with an operation handle. The caller can then poll the handle to check on progress.
// TypeScript — start a long-running background generation
let operation = await ai.generate({
  model: googleAI.model('veo-2.0-generate-001'),
  prompt: 'A banana riding a bicycle.',
});

// Poll until done
while (!operation.done) {
  operation = await ai.checkOperation(operation);
  await new Promise((resolve) => setTimeout(resolve, 5000));
}

const result = operation.result;
For most use cases, regular (synchronous) flows are the right choice. Use background flows only when the underlying model or task genuinely cannot complete within a standard HTTP request timeout.

Next steps

Models

Learn how to call AI models from within flows.

Tools

Give models the ability to call your functions.

Streaming

Stream responses token-by-token from flows.

Dev Tools

Inspect flow traces and replay runs in the Dev UI.

Build docs developers (and LLMs) love