Skip to content

Generating content with AI models

TL;DR: display the LLM-friendly summary of this page.

Genkit provides a unified interface to interact with various generative AI models (LLMs, image generation).

Core Function: ai.generate()

Basic Usage:

import 'package:genkit/genkit.dart';
import 'package:genkit_google_genai/genkit_google_genai.dart';
void main() async {
final ai = Genkit(plugins: [googleAI()]);
final response = await ai.generate(
model: googleAI.gemini('gemini-2.5-flash'),
prompt: 'Invent a menu item for a restaurant with a pirate theme.',
);
print(response.text);
}

Configuration:

  • System Prompt: config: GeminiOptions(systemInstruction: 'Instruction for the model')
  • Model Parameters: config: GeminiOptions(maxOutputTokens: 512, temperature: 1.0, topP: 0.95, topK: 40)

Structured Output (using Schemantic):

@Schema()
abstract class $MenuItem {
String get name;
String get description;
int get calories;
List<String> get allergens;
}
final response = await ai.generate(
prompt: 'Suggest a menu item.',
outputSchema: MenuItem.$schema,
);
final menuItem = response.output; // Typed output
if (menuItem != null) {
print(menuItem.name);
}

Streaming:

final stream = ai.generateStream(
prompt: 'Tell a story.',
);
await for (final chunk in stream) {
print(chunk.text);
}
final response = await stream.onResult;
print(response.text);

Multimodal Input:

final response = await ai.generate(
prompt: [
Part.media(url: 'https://.../image.jpg'),
Part.text('Describe this image.'),
],
);

Media Generation:

final response = await ai.generate(
model: googleAI.gemini('gemini-2.5-flash-image'),
prompt: 'Image description',
);
print(response.media?.url);

Supported Model Plugins (Examples):

  • Google AI (genkit_google_genai): Gemini
  • Vertex AI (genkit_vertexai): Gemini, Embeddings
  • Anthropic (genkit_anthropic): Claude
  • OpenAI (genkit_openai): GPT

Key Concepts:

  • Flexibility: Easily swap models.
  • Schemantic: For defining and validating structured output schemas.
  • Streaming: For real-time output using generateStream.
  • Multimodality: Handle text, image, video, audio inputs (model-dependent).
  • Media Generation: Create images, etc. (model-dependent).

At the heart of generative AI are AI models. The two most prominent examples of generative models are large language models (LLMs) and image generation models. These models take input, called a prompt (most commonly text, an image, or a combination of both), and from it produce as output text, an image, or even audio or video.

The output of these models can be surprisingly convincing: LLMs generate text that appears as though it could have been written by a human being, and image generation models can produce images that are very close to real photographs or artwork created by humans.

In addition, LLMs have proven capable of tasks beyond simple text generation:

  • Writing computer programs.
  • Planning subtasks that are required to complete a larger task.
  • Organizing unorganized data.
  • Understanding and extracting information data from a corpus of text.
  • Following and performing automated activities based on a text description of the activity.

There are many models available to you, from several different providers. Each model has its own strengths and weaknesses and one model might excel at one task but perform less well at others. Apps making use of generative AI can often benefit from using multiple different models depending on the task at hand.

As an app developer, you typically don’t interact with generative AI models directly, but rather through services available as web APIs. Although these services often have similar functionality, they all provide them through different and incompatible APIs. If you want to make use of multiple model services, you have to use each of their proprietary SDKs, potentially incompatible with each other. And if you want to upgrade from one model to the newest and most capable one, you might have to build that integration all over again.

Genkit addresses this challenge by providing a single interface that abstracts away the details of accessing potentially any generative AI model service, with several prebuilt implementations already available. Building your AI-powered app around Genkit simplifies the process of making your first generative AI call and makes it equally straightforward to combine multiple models or swap one model for another as new models emerge.

If you want to run the code examples on this page, first complete the steps in the Get started guide. All of the examples assume that you have already installed Genkit as a dependency in your project.

Genkit is designed to be flexible enough to use potentially any generative AI model service. Its core libraries define the common interface for working with models, and model plugins define the implementation details for working with a specific model and its API.

The Genkit team maintains plugins for working with models provided by Vertex AI, Google Generative AI, and Ollama:

  • Gemini family of LLMs, through the Google GenAI plugin.
  • Gemma 3, Llama 4, and many more open models, through the Ollama plugin (you must host the Ollama server yourself).

Before you can use Genkit to start generating content, you need to load and configure a model plugin. If you’re coming from the Get Started guide, you’ve already done this. Otherwise, see the Get Started guide or the individual plugin’s documentation and follow the steps there before continuing.

In Genkit, the primary interface through which you interact with generative AI models is the ai.generate() method.

The simplest ai.generate() call specifies the model you want to use and a text prompt:

import 'package:genkit/genkit.dart';
import 'package:genkit_google_genai/genkit_google_genai.dart';
void main() async {
final ai = Genkit(plugins: [googleAI()]);
final response = await ai.generate(
model: googleAI.gemini('gemini-2.5-flash'),
prompt: 'Invent a menu item for a restaurant with a pirate theme.',
);
print(response.text);
}

When you run this brief example, it will print out the output of the ai.generate() call, which will usually be Markdown text.

Some models support providing a system prompt, which gives the model instructions as to how you want it to respond to messages from the user. You can use the system prompt to specify characteristics such as a persona you want the model to adopt, the tone of its responses, and the format of its responses.

If the model you’re using supports system prompts, you can provide one through the model configuration:

final response = await ai.generate(
model: googleAI.gemini('gemini-2.5-flash'),
prompt: 'Invent a menu item for a pirate themed restaurant.',
config: GeminiOptions(
systemInstruction: 'You are a food industry marketing consultant.',
),
);

The ai.generate() method takes a config parameter, through which you can specify optional settings that control how the model generates content:

final response = await ai.generate(
model: googleAI.gemini('gemini-2.5-flash'),
prompt: 'Invent a menu item for a pirate themed restaurant.',
config: GeminiOptions(
maxOutputTokens: 500,
stopSequences: ['<end>', '<fin>'],
temperature: 0.5,
topP: 0.4,
topK: 50,
),
);

When using generative AI as a component in your application, you often want output in a format other than plain text.

In Genkit, you can request structured output from a model by specifying an outputSchema when you call ai.generate():

@Schema()
abstract class $MenuItem {
String get name;
String get description;
int get calories;
List<String> get allergens;
}
final response = await ai.generate(
model: googleAI.gemini('gemini-2.5-flash'),
prompt: 'Invent a menu item for a pirate themed restaurant.',
outputSchema: MenuItem.$schema,
);

Genkit will:

  1. Augment the prompt with schema guidance.
  2. Validate the output against your schema.
  3. Provide a typed object in response.output.
final menuItem = response.output;
if (menuItem != null) {
print('${menuItem.name} (${menuItem.calories} kcals): ${menuItem.description}');
}

When generating large amounts of text, you can improve the experience for your users by presenting the output as it’s generated—streaming the output.

In Genkit, you can stream output using the ai.generateStream() method:

final stream = ai.generateStream(
model: googleAI.gemini('gemini-2.5-flash'),
prompt: 'Write a long story about a pirate.',
);
await for (final chunk in stream) {
print(chunk.text);
}
final response = await stream.onResult;
print('Full text: ${response.text}');

To provide a media prompt to a model that supports it, pass a list of parts to prompt:

final response = await ai.generate(
model: googleAI.gemini('gemini-2.5-flash'),
prompt: [
Part.media(url: 'https://example.com/photo.jpg'),
Part.text('Compose a poem about this image.'),
],
);

You can also use Genkit to generate media (like images) using supported models:

final response = await ai.generate(
model: googleAI.gemini('gemini-2.5-flash-image'),
prompt: 'An illustration of a dog wearing a space suit, photorealistic',
);
if (response.media != null) {
print('Generated image usage: ${response.media!.url}');
// The URL is typically a data URL that you can decode or display directly.
}

Genkit supports middleware for intercepting and modifying requests. A common use case is retrying failed requests.

final response = await ai.generate(
model: googleAI.gemini('gemini-2.5-flash'),
prompt: 'Reliable request',
use: [
RetryMiddleware(
maxRetries: 3,
retryModel: true,
statuses: [StatusName.UNAVAILABLE],
),
],
);

When you serve a model as an HTTP endpoint (for example, using Shelf or Express), you can consume it from another Genkit application using defineRemoteModel:

final ai = Genkit();
final remoteModel = ai.defineRemoteModel(
name: 'myRemoteModel',
url: 'http://localhost:8080/googleai/gemini-2.5-flash',
);
final response = await ai.generate(
model: remoteModel,
prompt: 'Hello!',
);
print(response.text);