> ## Documentation Index
> Fetch the complete documentation index at: https://braintrust.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Firebase Genkit

> Trace Firebase Genkit calls in Braintrust to debug prompts, evaluate models, and monitor production usage

If you are a coding agent, prefer the Braintrust [`bt` CLI](/docs/reference/cli/quickstart) for repeatable, scriptable work: running evals, instrumenting code, querying logs, syncing data, managing functions, and configuring coding agents. Use the MCP server for reasoning over Braintrust data in conversation, and for capabilities the CLI doesn't cover, such as monitor views, alerts, and authoring evaluators, preprocessors, and facets.

[Firebase Genkit](https://firebase.google.com/docs/genkit) is Google's open-source framework for building AI-powered applications. Braintrust traces Genkit calls from your application.

<View title="TypeScript" icon="https://img.logo.dev/typescriptlang.org?token=pk_BdcHD9e5SCW3j1rnJkNyMQ">
  <h2 id="setup-typescript">
    Setup
  </h2>

  Install Braintrust alongside Genkit and a model plugin.

  <CodeGroup>
    ```bash pnpm theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
    pnpm add braintrust genkit @genkit-ai/googleai
    ```

    ```bash npm theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
    npm install braintrust genkit @genkit-ai/googleai
    ```
  </CodeGroup>

  <h2 id="auto-instrumentation-typescript">
    Auto-instrumentation
  </h2>

  To trace Genkit calls without modifying your application code, initialize Braintrust normally, then run your app with Braintrust's import hook to patch Genkit at runtime. Requires `genkit` v1.0.0 or later.

  <Steps>
    <Step title="Initialize Braintrust and call Genkit">
      <CodeGroup>
        ```javascript title="trace-genkit-auto.js" theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
        import { initLogger } from "braintrust";
        import { genkit } from "genkit";
        import { googleAI } from "@genkit-ai/googleai";

        initLogger({
          projectName: "my-genkit-project",
          apiKey: process.env.BRAINTRUST_API_KEY,
        });

        const ai = genkit({
          plugins: [googleAI()],
        });

        const { text } = await ai.generate({
          model: googleAI.model("gemini-2.5-flash"),
          prompt: "What is the capital of France?",
        });

        console.log(text);
        ```
      </CodeGroup>
    </Step>

    <Step title="Run with the import hook">
      ```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
      node --import braintrust/hook.mjs trace-genkit-auto.js
      ```

      The auto-instrumentation example uses plain JavaScript so `node --import` can run the file directly. The Braintrust APIs work the same in TypeScript projects — compile your TypeScript to JavaScript, then run the compiled file with the import hook.

      <Note>
        If you're using a bundler, see [Trace LLM calls](/docs/instrument/trace-llm-calls#auto-instrumentation) for plugin and loader setup.
      </Note>
    </Step>
  </Steps>

  <h2 id="manual-instrumentation-typescript">
    Manual instrumentation
  </h2>

  To trace Genkit manually, wrap your Genkit instance yourself with `wrapGenkit()`. Use this when you want to instrument a specific instance rather than patching Genkit globally.

  <CodeGroup>
    ```javascript JavaScript theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
    import { initLogger, wrapGenkit } from "braintrust";
    import { genkit } from "genkit";
    import { googleAI } from "@genkit-ai/googleai";

    initLogger({
      projectName: "my-genkit-project",
      apiKey: process.env.BRAINTRUST_API_KEY,
    });

    const ai = wrapGenkit(
      genkit({
        plugins: [googleAI()],
      }),
    );

    const { text } = await ai.generate({
      model: googleAI.model("gemini-2.5-flash"),
      prompt: "What is the capital of France?",
    });

    console.log(text);
    ```
  </CodeGroup>

  <h2 id="what-traced-typescript">
    What Braintrust traces
  </h2>

  Braintrust patches the Genkit SDK and captures:

  * Generate spans (`genkit.generate`), with the prompt and messages as input, model and request parameters in metadata, and the response as output.
  * Streaming generate spans (`genkit.generateStream`), with streamed text output and `time_to_first_token`.
  * Embedding spans (`genkit.embed` and `genkit.embedMany`), with input as input and a summarized result (embedding count and dimensions).
  * Action spans (`genkit.<action_type>: <name>`) for flows, tools, and other Genkit actions, with input, output, and duration, plus action type, name, and key in metadata.
  * Token usage metrics (prompt, completion, total, plus cached and reasoning tokens when reported).
  * Errors captured on every call.

  <h2 id="tracing-resources-typescript">
    Tracing resources
  </h2>

  * [Firebase Genkit documentation](https://firebase.google.com/docs/genkit)
  * [Genkit JS on GitHub](https://github.com/firebase/genkit)
</View>

<View title="Go" icon="https://img.logo.dev/go.dev?token=pk_BdcHD9e5SCW3j1rnJkNyMQ">
  <h2 id="setup-go">
    Setup
  </h2>

  Install the Braintrust Genkit integration:

  ```bash theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
  go get github.com/braintrustdata/braintrust-sdk-go/trace/contrib/genkit
  ```

  <h2 id="manual-instrumentation-go">
    Manual instrumentation
  </h2>

  To trace Firebase Genkit calls, attach Braintrust's middleware by passing `tracegenkit.NewMiddleware()` to `ai.WithMiddleware(...)` on each Genkit call you want to trace. The middleware infers provider and model metadata from the request configuration and response metadata when Genkit exposes them. Pass `tracegenkit.WithProvider` and `tracegenkit.WithModel` to override those values or fill them in for custom model implementations and proxies.

  <CodeGroup>
    ```go Go theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
    package main

    import (
    	"context"
    	"fmt"
    	"log"
    	"os"

    	"github.com/firebase/genkit/go/ai"
    	"github.com/firebase/genkit/go/genkit"
    	"github.com/firebase/genkit/go/plugins/googlegenai"
    	"go.opentelemetry.io/otel"
    	"go.opentelemetry.io/otel/sdk/trace"

    	"github.com/braintrustdata/braintrust-sdk-go"
    	tracegenkit "github.com/braintrustdata/braintrust-sdk-go/trace/contrib/genkit"
    )

    func main() {
    	tp := trace.NewTracerProvider()
    	defer tp.Shutdown(context.Background())
    	otel.SetTracerProvider(tp)

    	bt, err := braintrust.New(tp,
    		braintrust.WithProject("my-genkit-project"),
    		braintrust.WithAPIKey(os.Getenv("BRAINTRUST_API_KEY")),
    	)
    	if err != nil {
    		log.Fatal(err)
    	}

    	ctx := context.Background()
    	g := genkit.Init(ctx,
    		genkit.WithPlugins(&googlegenai.GoogleAI{
    			APIKey: os.Getenv("GOOGLE_API_KEY"),
    		}),
    		genkit.WithDefaultModel("googleai/gemini-2.5-flash"),
    	)

    	tracer := otel.Tracer("genkit-example")
    	ctx, span := tracer.Start(ctx, "genkit-call")
    	defer span.End()

    	mw := tracegenkit.NewMiddleware()
    	resp, err := genkit.Generate(ctx, g,
    		ai.WithPrompt("What is the capital of France?"),
    		ai.WithMiddleware(mw),
    	)
    	if err != nil {
    		log.Fatal(err)
    	}

    	fmt.Printf("Response: %s\n", resp.Text())
    	fmt.Printf("View trace: %s\n", bt.Permalink(span))
    }
    ```
  </CodeGroup>

  <h3 id="tracing-tools-go">
    Tracing tools
  </h3>

  To trace Genkit tool calls, define your tools with the `tracegenkit` drop-in replacements instead of the standard `genkit` functions. Each traced tool emits a `tool` span for its full execution, including failures.

  ```go #skip-compile theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
  import (
  	tracegenkit "github.com/braintrustdata/braintrust-sdk-go/trace/contrib/genkit"
  )

  // Drop-in for genkit.DefineTool
  weatherTool := tracegenkit.DefineTool(g, "get_weather",
  	"Get the current weather for a city",
  	func(ctx *ai.ToolContext, input WeatherInput) (string, error) {
  		// tool implementation
  	},
  )

  // Drop-in for genkit.DefineToolWithInputSchema (custom input schema)
  // tracegenkit.DefineToolWithInputSchema(g, "name", "desc", schema, fn)

  // Drop-in for genkit.DefineMultipartTool (multipart output)
  // tracegenkit.DefineMultipartTool(g, "name", "desc", fn)
  ```

  With auto-instrumentation (Orchestrion), `genkit.DefineTool`, `genkit.DefineToolWithInputSchema`, and `genkit.DefineMultipartTool` calls are replaced with their traced equivalents automatically.

  <h3 id="streaming-go">
    Streaming
  </h3>

  To trace streaming responses from `genkit.GenerateStream`, pass the same middleware to that call:

  ```go #skip-compile theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
  stream, err := genkit.GenerateStream(ctx, g,
  	ai.WithPrompt("Tell me a story"),
  	ai.WithMiddleware(mw),
  )
  if err != nil {
  	log.Fatal(err)
  }
  _ = stream
  ```

  <h3 id="tracing-embeddings-go">
    Tracing embeddings
  </h3>

  Genkit does not route embedding calls through its model middleware, so `tracegenkit.NewMiddleware()` does not capture them. To trace embeddings, wrap each embedder with `tracegenkit.WrapEmbedder`. The wrapped value implements `ai.Embedder` and can be used as a drop-in replacement with `ai.WithEmbedder(...)`.

  ```go #skip-compile theme={"theme":{"light":"github-light","dark":"github-dark-dimmed"}}
  import (
  	"github.com/firebase/genkit/go/ai"
  	"github.com/firebase/genkit/go/genkit"

  	tracegenkit "github.com/braintrustdata/braintrust-sdk-go/trace/contrib/genkit"
  )

  embedder := tracegenkit.WrapEmbedder(
  	genkit.LookupEmbedder(g, "googleai/gemini-embedding-001"),
  	tracegenkit.WithEmbedderModel("gemini-embedding-001"),
  	tracegenkit.WithEmbedderProvider("google"),
  )

  resp, err := genkit.Embed(ctx, g,
  	ai.WithEmbedder(embedder),
  	ai.WithTextDocs("text 1", "text 2"),
  )
  ```

  <h2 id="what-traced-go">
    What Braintrust traces
  </h2>

  Braintrust captures:

  * `genkit.Generate`, `genkit.GenerateText`, and `genkit.GenerateStream` inputs, outputs, and finish reasons.
  * Streaming responses, with `time_to_first_token` captured on the first chunk.
  * Token usage, including cached input tokens and reasoning (thoughts) tokens.
  * Tool calls and tool results.
  * Tool execution spans, emitted when tools are defined with `tracegenkit.DefineTool`, `tracegenkit.DefineToolWithInputSchema`, or `tracegenkit.DefineMultipartTool` (or via auto-instrumentation).
  * Model configuration (model, temperature, top\_p, max output tokens, etc.) and response metadata (latency, provider, request id).
  * `genkit.Embed` inputs, embedding count, and dimensions when wrapped with `WrapEmbedder`.

  <h2 id="tracing-resources-go">
    Tracing resources
  </h2>

  * [Firebase Genkit documentation](https://firebase.google.com/docs/genkit)
  * [Go SDK example](https://github.com/braintrustdata/braintrust-sdk-go/tree/main/examples/genkit)
</View>
