go

module
v1.4.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 14, 2026 License: Apache-2.0

README

Genkit logo
Genkit Go
AI SDK for Go • LLM Framework • AI Agent Toolkit

Go Reference Go Report Card

Build production-ready AI-powered applications in Go with a unified interface for text generation, structured output, tool calling, and agentic workflows.

DocumentationAPI ReferenceDiscord


Installation

go get github.com/firebase/genkit/go

Quick Start

Get up and running in under a minute:

package main

import (
    "context"
    "fmt"

    "github.com/firebase/genkit/go/ai"
    "github.com/firebase/genkit/go/genkit"
    "github.com/firebase/genkit/go/plugins/googlegenai"
)

func main() {
    ctx := context.Background()
    g := genkit.Init(ctx, genkit.WithPlugins(&googlegenai.GoogleAI{}))

    answer, err := genkit.GenerateText(ctx, g,
        ai.WithModelName("googleai/gemini-2.5-flash"),
        ai.WithPrompt("Why is Go a great language for AI applications?"),
    )
    if err != nil {
        fmt.Println("could not generate: %s", err)
    }
    fmt.Println(answer)
}
export GEMINI_API_KEY="your-api-key"
go run main.go

Features

Genkit Go gives you everything you need to build AI applications with confidence.

Generate Text

Call any model with a simple, unified API:

text, _ := genkit.GenerateText(ctx, g,
    ai.WithModelName("googleai/gemini-2.5-flash"),
    ai.WithPrompt("Explain quantum computing in simple terms."),
)
fmt.Println(text)

Generate Structured Data

Get type-safe JSON output that maps directly to your Go structs:

type Recipe struct {
    Title       string   `json:"title"`
    Ingredients []string `json:"ingredients"`
    Steps       []string `json:"steps"`
}

recipe, _ := genkit.GenerateData[Recipe](ctx, g,
    ai.WithModelName("googleai/gemini-2.5-flash"),
    ai.WithPrompt("Create a recipe for chocolate chip cookies."),
)
fmt.Printf("Recipe: %s\n", recipe.Title)

See full example

Stream Responses

Stream text as it's generated for responsive user experiences:

stream := genkit.GenerateStream(ctx, g,
    ai.WithModelName("googleai/gemini-2.5-flash"),
    ai.WithPrompt("Write a short story about a robot learning to paint."),
)

for result, err := range stream {
    if err != nil {
        log.Fatal(err)
    }
    if result.Done {
        break
    }
    fmt.Print(result.Chunk.Text())
}

See full example

Stream Structured Data

Stream typed JSON objects as they're being generated:

type Ingredient struct {
    Name   string `json:"name"`
    Amount string `json:"amount"`
}

type Recipe struct {
    Title       string        `json:"title"`
    Ingredients []*Ingredient `json:"ingredients"`
}

stream := genkit.GenerateDataStream[*Recipe](ctx, g,
    ai.WithModelName("googleai/gemini-2.5-flash"),
    ai.WithPrompt("Create a recipe for spaghetti carbonara."),
)

for result, err := range stream {
    if err != nil {
        log.Fatal(err)
    }
    if result.Done {
        fmt.Printf("\nComplete recipe: %s\n", result.Output.Title)
        break
    }
    // Access partial data as it streams in
    if result.Chunk != nil && len(result.Chunk.Ingredients) > 0 {
        fmt.Printf("Found ingredient: %s\n", result.Chunk.Ingredients[0].Name)
    }
}

See full example

Define Tools

Give models the ability to take actions and access external data:

type WeatherInput struct {
    Location string `json:"location"`
}

weatherTool := genkit.DefineTool(g, "getWeather",
    "Gets the current weather for a location",
    func(ctx *ai.ToolContext, input WeatherInput) (string, error) {
        // Call your weather API here
        return fmt.Sprintf("Weather in %s: 72°F and sunny", input.Location), nil
    },
)

response, _ := genkit.Generate(ctx, g,
    ai.WithModelName("googleai/gemini-2.5-flash"),
    ai.WithPrompt("What's the weather like in San Francisco?"),
    ai.WithTools(weatherTool),
)
fmt.Println(response.Text())

See full example

Tool Interrupts

Pause execution for human approval, then resume with modified inputs or direct responses:

type TransferInput struct {
    ToAccount string  `json:"toAccount"`
    Amount    float64 `json:"amount"`
}

type TransferInterrupt struct {
    Reason  string  `json:"reason"`
    Amount  float64 `json:"amount"`
    Balance float64 `json:"balance"`
}

transferTool := genkit.DefineTool(g, "transfer",
    "Transfer money to an account",
    func(ctx *ai.ToolContext, input TransferInput) (string, error) {
        // Confirm large transfers
        if !ctx.IsResumed() && input.Amount > 1000 {
            return "", ai.InterruptWith(ctx, TransferInterrupt{
                Reason:  "confirm_large",
                Amount:  input.Amount,
                Balance: currentBalance,
            })
        }
        return "Transfer completed", nil
    },
)

// Handle interrupts in your flow
resp, _ := genkit.Generate(ctx, g,
    ai.WithModelName("googleai/gemini-2.5-flash"),
    ai.WithPrompt("Transfer $5000 to account ABC123"),
    ai.WithTools(transferTool),
)

if resp.FinishReason == ai.FinishReasonInterrupted {
    for _, interrupt := range resp.Interrupts() {
        meta, _ := ai.InterruptAs[TransferInterrupt](interrupt)

        // Get user confirmation, then resume
        part, _ := transferTool.RestartWith(interrupt)
        resp, _ = genkit.Generate(ctx, g,
            ai.WithMessages(resp.History()...),
            ai.WithTools(transferTool),
            ai.WithToolRestarts(part),
        )
    }
}

See full example

Define Flows

Wrap your AI logic in flows for better observability, testing, and deployment:

jokeFlow := genkit.DefineFlow(g, "tellJoke",
    func(ctx context.Context, topic string) (string, error) {
        return genkit.GenerateText(ctx, g,
            ai.WithModelName("googleai/gemini-2.5-flash"),
            ai.WithPrompt("Tell me a joke about %s", topic),
        )
    },
)

joke, _ := jokeFlow.Run(ctx, "programming")
fmt.Println(joke)

See full example

Streaming Flows

Stream data from your flows using Server-Sent Events (SSE):

genkit.DefineStreamingFlow(g, "streamStory",
    func(ctx context.Context, topic string, send core.StreamCallback[string]) (string, error) {
        stream := genkit.GenerateStream(ctx, g,
            ai.WithModelName("googleai/gemini-2.5-flash"),
            ai.WithPrompt("Write a story about %s", topic),
        )

        for result, err := range stream {
            if err != nil {
                return "", err
            }
            if result.Done {
                return result.Response.Text(), nil
            }
            send(ctx, result.Chunk.Text())
        }
        return "", nil
    },
)

See full example

Traced Sub-steps

Add observability to complex flows by breaking them into traced operations:

genkit.DefineFlow(g, "processDocument",
    func(ctx context.Context, doc string) (string, error) {
        // Each Run call creates a traced step visible in the Dev UI
        summary, _ := genkit.Run(ctx, "summarize", func() (string, error) {
            return genkit.GenerateText(ctx, g,
                ai.WithModelName("googleai/gemini-2.5-flash"),
                ai.WithPrompt("Summarize: %s", doc),
            )
        })

        keywords, _ := genkit.Run(ctx, "extractKeywords", func() ([]string, error) {
            return genkit.GenerateData[[]string](ctx, g,
                ai.WithModelName("googleai/gemini-2.5-flash"),
                ai.WithPrompt("Extract keywords from: %s", summary),
            )
        })

        return fmt.Sprintf("Summary: %s\nKeywords: %v", summary, keywords), nil
    },
)

See full example

Define Prompts

Create reusable prompts with Handlebars templating:

greetingPrompt := genkit.DefinePrompt(g, "greeting",
    ai.WithModelName("googleai/gemini-2.5-flash"),
    ai.WithPrompt("Write a {{style}} greeting for {{name}}."),
)

response, _ := greetingPrompt.Execute(ctx, ai.WithInput(map[string]any{
    "name":  "Alice",
    "style": "formal",
}))
fmt.Println(response.Text())

See full example

Type-Safe Data Prompts

Get compile-time type safety for your prompt inputs and outputs:

type JokeRequest struct {
    Topic string `json:"topic"`
}

type Joke struct {
    Setup     string `json:"setup"`
    Punchline string `json:"punchline"`
}

jokePrompt := genkit.DefineDataPrompt[JokeRequest, *Joke](g, "joke",
    ai.WithModelName("googleai/gemini-2.5-flash"),
    ai.WithPrompt("Tell a joke about {{topic}}."),
)

for result, err := range jokePrompt.ExecuteStream(ctx, JokeRequest{Topic: "cats"}) {
    if err != nil {
        log.Fatal(err)
    }
    if result.Done {
        fmt.Printf("Punchline: %s\n", result.Output.Punchline)
        break
    }
    // Access typed partial data as it streams
    if result.Chunk != nil && result.Chunk.Setup != "" {
        fmt.Printf("Got setup: %s\n", result.Chunk.Setup)
    }
}

See full example

Load Prompts from Files

Keep prompts separate from code using .prompt files with YAML frontmatter:

# prompts/recipe.prompt
---
model: googleai/gemini-2.5-flash
input:
  schema: RecipeRequest
output:
  format: json
  schema: Recipe
---
{{role "system"}}
You are an experienced chef.

{{role "user"}}
Create a {{cuisine}} {{dish}} recipe for {{servingSize}} people.
{{#if dietaryRestrictions}}
Dietary restrictions: {{#each dietaryRestrictions}}{{this}}{{#unless @last}}, {{/unless}}{{/each}}.
{{/if}}
// Register schemas so .prompt files can reference them by name
genkit.DefineSchemaFor[RecipeRequest](g)
genkit.DefineSchemaFor[Recipe](g)

// Look up and execute the prompt
recipePrompt := genkit.LookupDataPrompt[RecipeRequest, *Recipe](g, "recipe")
recipe, _ := recipePrompt.Execute(ctx, RecipeRequest{
    Dish:        "tacos",
    Cuisine:     "Mexican",
    ServingSize: 4,
})
fmt.Printf("%s (%s)\n", recipe.Title, recipe.PrepTime)

See full example

Embed Prompts in Your Binary

Ship a single binary with prompts compiled in using Go's embed package:

//go:embed prompts/*
var promptsFS embed.FS

func main() {
    ctx := context.Background()
    g := genkit.Init(ctx,
        genkit.WithPlugins(&googlegenai.GoogleAI{}),
        genkit.WithPromptFS(promptsFS),
    )

    prompt := genkit.LookupPrompt(g, "greeting")
    response, _ := prompt.Execute(ctx)
    fmt.Println(response.Text())
}

See full example

Expose Flows as HTTP Endpoints

Serve your flows over HTTP with automatic JSON serialization:

mux := http.NewServeMux()
for _, flow := range genkit.ListFlows(g) {
    mux.HandleFunc("POST /"+flow.Name(), genkit.Handler(flow))
}
log.Fatal(http.ListenAndServe(":8080", mux))
curl -X POST http://localhost:8080/tellJoke \
  -H "Content-Type: application/json" \
  -d '{"data": "programming"}'

Model Providers

Genkit provides a unified interface across all major AI providers. Use whichever model fits your needs:

Provider Plugin Models
Google AI googlegenai.GoogleAI Gemini 2.5 Flash, Gemini 2.5 Pro, and more
Vertex AI vertexai.VertexAI Gemini models via Google Cloud
Anthropic anthropic.Anthropic Claude 3.5, Claude 3 Opus, and more
Ollama ollama.Ollama Llama, Mistral, and other open models
OpenAI Compatible compat_oai Any OpenAI-compatible API
// Google AI
g := genkit.Init(ctx, genkit.WithPlugins(&googlegenai.GoogleAI{}))

// Anthropic
g := genkit.Init(ctx, genkit.WithPlugins(&anthropic.Anthropic{}))

// Ollama (local models)
g := genkit.Init(ctx, genkit.WithPlugins(&ollama.Ollama{
    ServerAddress: "http://localhost:11434",
}))

// Multiple providers at once
g := genkit.Init(ctx, genkit.WithPlugins(
    &googlegenai.GoogleAI{},
    &anthropic.Anthropic{},
))

Use ai.WithModelName for simple cases, or pair a model with provider-specific config using ModelRef:

import "google.golang.org/genai"

// Simple: just the model name
response, _ := genkit.Generate(ctx, g,
    ai.WithModelName("googleai/gemini-2.5-flash"),
    ai.WithPrompt("Hello!"),
)

// Advanced: model name + provider-specific configuration
response, _ := genkit.Generate(ctx, g,
    ai.WithModel(googlegenai.ModelRef("googleai/gemini-2.5-flash", &genai.GenerateContentConfig{
        Temperature:     genai.Ptr(float32(0.7)),
        MaxOutputTokens: genai.Ptr(int32(1000)),
        TopP:            genai.Ptr(float32(0.9)),
    })),
    ai.WithPrompt("Hello!"),
)

Development Tools

Genkit CLI

Use the Genkit CLI to run your app with tracing and a local development UI:

curl -sL cli.genkit.dev | bash
genkit start -- go run main.go

Developer UI

The local developer UI lets you:

  • Test flows with different inputs interactively
  • Inspect traces to debug complex multi-step operations
  • Compare models by switching providers in real-time
  • Evaluate prompts against datasets

Experimental

These features are available in core/x and may change in future releases.

Durable Streaming

Allow clients to reconnect to in-progress or completed streams using a stream ID:

import "github.com/firebase/genkit/go/core/x/streaming"

mux.HandleFunc("POST /myFlow", genkit.Handler(myStreamingFlow,
    genkit.WithStreamManager(streaming.NewInMemoryStreamManager(
        streaming.WithTTL(10*time.Minute),
    )),
))

Clients receive a stream ID in the X-Genkit-Stream-Id header and can reconnect to replay buffered chunks.

See full example

Sessions

Maintain typed state across multiple requests and throughout generation including tools:

import "github.com/firebase/genkit/go/core/x/session"

type CartState struct {
    Items []string `json:"items"`
}

store := session.NewInMemoryStore[CartState]()

genkit.DefineFlow(g, "manageCart", func(ctx context.Context, input string) (string, error) {
    sess, err := session.Load(ctx, store, "session-id")
    if err != nil {
        sess, _ = session.New(ctx,
            session.WithID[CartState]("session-id"),
            session.WithStore(store),
            session.WithInitialState(CartState{}),
        )
    }
    ctx = session.NewContext(ctx, sess)

    // Tools can now access session state via session.FromContext[CartState](ctx)
    return genkit.GenerateText(ctx, g, ai.WithPrompt(input), ai.WithTools(myTools...))
})

See full example


Samples

Explore working examples to see Genkit in action:

Sample Description
basic Simple text generation with streaming
basic-structured Typed JSON output with GenerateData and GenerateDataStream
basic-prompts Prompt templates with Handlebars and .prompt files
intermediate-interrupts Human-in-the-loop with tool interrupts
prompts-embed Embed prompts in your binary
durable-streaming Reconnectable streams with replay
session Stateful flows with typed session data

Built by Google with contributions from the Open Source Community

Directories

Path Synopsis
Package core implements Genkit actions and other essential machinery.
Package core implements Genkit actions and other essential machinery.
api
logger
Package logger provides context-scoped structured logging for Genkit.
Package logger provides context-scoped structured logging for Genkit.
tracing
Package tracing provides execution trace support for Genkit operations.
Package tracing provides execution trace support for Genkit operations.
x/session
Package session provides experimental session management APIs for Genkit.
Package session provides experimental session management APIs for Genkit.
x/streaming
Package streaming provides experimental durable streaming APIs for Genkit.
Package streaming provides experimental durable streaming APIs for Genkit.
Package genkit provides a framework for building AI-powered applications in Go.
Package genkit provides a framework for building AI-powered applications in Go.
cmd/copy command
copy is a tool for copying parts of files.
copy is a tool for copying parts of files.
cmd/jsonschemagen command
A simple, self-contained code generator for JSON Schema.
A simple, self-contained code generator for JSON Schema.
cmd/weave command
The weave command is a simple preprocessor for markdown files.
The weave command is a simple preprocessor for markdown files.
fakeembedder
Package fakeembedder provides a fake implementation of genkit.Embedder for testing purposes.
Package fakeembedder provides a fake implementation of genkit.Embedder for testing purposes.
plugins
evaluators
Package evaluators defines a set of Genkit Evaluators for popular use-cases
Package evaluators defines a set of Genkit Evaluators for popular use-cases
firebase/x
Package x contains experimental Firebase features.
Package x contains experimental Firebase features.
googlecloud
The googlecloud package supports telemetry (tracing, metrics and logging) using Google Cloud services.
The googlecloud package supports telemetry (tracing, metrics and logging) using Google Cloud services.
internal
Package internal contains code that is common to all models
Package internal contains code that is common to all models
internal/uri
Package uri extracts the content-type and data from a media part.
Package uri extracts the content-type and data from a media part.
localvec
Package localvec is a local vector database for development and testing.
Package localvec is a local vector database for development and testing.
mcp
Package mcp provides a client for integration with the Model Context Protocol.
Package mcp provides a client for integration with the Model Context Protocol.
pinecone
Package pinecone implements a genkit plugin for the Pinecone vector database.
Package pinecone implements a genkit plugin for the Pinecone vector database.
samples
anthropic command
basic command
This sample demonstrates basic Genkit flows: a non-streaming flow and a streaming flow that generate jokes about a given topic.
This sample demonstrates basic Genkit flows: a non-streaming flow and a streaming flow that generate jokes about a given topic.
basic-prompts command
This sample demonstrates prompts using both inline code definitions and .prompt files (Dotprompt).
This sample demonstrates prompts using both inline code definitions and .prompt files (Dotprompt).
basic-structured command
This sample demonstrates structured input/output with strongly-typed Go structs.
This sample demonstrates structured input/output with strongly-typed Go structs.
cache-gemini command
coffee-shop command
durable-streaming command
This sample demonstrates durable streaming, which allows clients to reconnect to in-progress or completed streams using a stream ID.
This sample demonstrates durable streaming, which allows clients to reconnect to in-progress or completed streams using a stream ID.
durable-streaming-firestore command
This sample demonstrates durable streaming with Firestore backend.
This sample demonstrates durable streaming with Firestore backend.
flow-sample1 command
formats command
imagen command
imagen-gemini command
intermediate-interrupts command
Tool-interrupts demonstrates the tool interrupts feature in Genkit.
Tool-interrupts demonstrates the tool interrupts feature in Genkit.
mcp-ception command
mcp-client command
mcp-server command
menu command
modelgarden command
multipart-tools command
ollama-tools command
ollama-vision command
pgvector command
This program can be manually tested like so:
This program can be manually tested like so:
prompts command
prompts-embed command
rag command
session command
This sample demonstrates how to use sessions to maintain state across multiple requests.
This sample demonstrates how to use sessions to maintain state across multiple requests.
text-to-speech command
veo command
tests
test_app command
This program doesn't do anything interesting.
This program doesn't do anything interesting.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL