Skip to main content

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.

CloudWeGo Eino is a Go framework for building LLM-powered applications. Braintrust traces Eino to capture llm calls and tool calls.
This guide covers manual instrumentation. For quicker setup, use auto-instrumentation.

Setup

Install the Braintrust Eino integration:
go get github.com/braintrustdata/braintrust-sdk-go/trace/contrib/cloudwego/eino

Trace with CloudWeGo Eino

Register the Braintrust handler once with Eino’s callback system. All subsequent ChatModel calls are traced automatically.
package main

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

	einoopenai "github.com/cloudwego/eino-ext/components/model/openai"
	"github.com/cloudwego/eino/callbacks"
	"github.com/cloudwego/eino/schema"
	"go.opentelemetry.io/otel"
	"go.opentelemetry.io/otel/sdk/trace"

	"github.com/braintrustdata/braintrust-sdk-go"
	traceeino "github.com/braintrustdata/braintrust-sdk-go/trace/contrib/cloudwego/eino"
)

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

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

	handler := traceeino.NewHandler()
	callbacks.AppendGlobalHandlers(handler)

	ctx := context.Background()
	tracer := otel.Tracer("eino-example")
	ctx, span := tracer.Start(ctx, "eino-chat")
	defer span.End()

	chatModel, err := einoopenai.NewChatModel(ctx, &einoopenai.ChatModelConfig{
		Model:  "gpt-4o-mini",
		APIKey: os.Getenv("OPENAI_API_KEY"),
	})
	if err != nil {
		log.Fatal(err)
	}

	messages := []*schema.Message{{
		Role:    schema.User,
		Content: "What is the capital of France?",
	}}
	resp, err := chatModel.Generate(ctx, messages)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Printf("Response: %s\n", resp.Content)
	fmt.Printf("View trace: %s\n", bt.Permalink(span))
}

Streaming

For streaming, call handler.Wait() after closing the reader so asynchronously finalized span attributes are flushed before exit.
#skip-compile
reader, err := chatModel.Stream(ctx, messages)
if err != nil {
	log.Fatal(err)
}
// ... consume the stream ...
reader.Close()
handler.Wait()

Tracing embeddings

Eino’s callback handler captures EmbedStrings calls automatically. No additional setup is needed beyond registering the handler. Embedding calls appear as LLM spans in Braintrust, with input texts, embedding count, and model metadata captured.

Resources