This is the official Ruby SDK for Braintrust, for tracing and evaluating your AI applications.
NOTE: This SDK is currently in BETA status and APIs may change between minor versions.
Add to your Gemfile:
gem "braintrust", require: "braintrust/setup"Set your API key and install:
export BRAINTRUST_API_KEY="your-api-key"
bundle installYour LLM calls are now automatically traced. View them at braintrust.dev.
The SDK also offers additional setup options for a variety of applications.
| What it looks like | When to Use | |
|---|---|---|
| Setup script | require 'braintrust/setup' |
You'd like to automatically setup the SDK at load time. |
| CLI command | braintrust exec -- ruby app.rb |
You prefer not to modify the application source code. |
| Braintrust.init | Call Braintrust.init in your code |
You need to control when setup occurs, or require customized configuration. |
See our examples for more detail.
For most applications, we recommend adding require: "braintrust/setup" to your Gemfile or an initializer file in your Ruby application to automatically setup the SDK. This will automatically apply instrumentation to all available LLM libraries.
You can use environment variables to configure behavior.
You can use this CLI command to instrument any Ruby application without modifying the source code.
First, make sure the gem is installed on the system:
gem install braintrustThen wrap the start up command of any Ruby application to apply:
braintrust exec -- ruby app.rb
braintrust exec -- bundle exec rails server
braintrust exec --only openai -- ruby app.rbYou can use environment variables to configure behavior.
NOTE: Installing a package at the system-level does not guarantee compatibility with all Ruby applications on that system; conflicts with dependencies can arise.
For stronger assurance of compatibility, we recommend either:
- Installing via the application's
Gemfileandbundle installwhen possible. - OR for OCI/Docker deployments,
gem install braintrustwhen building images in your CI/CD pipeline (and verifying their safe function.)
For more control over when auto-instrumentation is applied:
require "braintrust"
Braintrust.initOptions:
| Option | Default | Description |
|---|---|---|
api_key |
ENV['BRAINTRUST_API_KEY'] |
API key |
auto_instrument |
true |
true, false, or Hash with :only/:except keys to filter integrations |
blocking_login |
false |
Block until login completes (async login when false) |
default_project |
ENV['BRAINTRUST_DEFAULT_PROJECT'] |
Default project for spans |
enable_tracing |
true |
Enable OpenTelemetry tracing |
filter_ai_spans |
ENV['BRAINTRUST_OTEL_FILTER_AI_SPANS'] |
Only export AI-related spans |
org_name |
ENV['BRAINTRUST_ORG_NAME'] |
Organization name |
set_global |
true |
Set as global state. Set to false for isolated instances |
Example with options:
Braintrust.init(
default_project: "my-project",
auto_instrument: { only: [:openai] }
)| Variable | Description |
|---|---|
BRAINTRUST_API_KEY |
Required. Your Braintrust API key |
BRAINTRUST_API_URL |
Braintrust API URL (default: https://api.braintrust.dev) |
BRAINTRUST_APP_URL |
Braintrust app URL (default: https://www.braintrust.dev) |
BRAINTRUST_AUTO_INSTRUMENT |
Set to false to disable auto-instrumentation |
BRAINTRUST_DEBUG |
Set to true to enable debug logging |
BRAINTRUST_DEFAULT_PROJECT |
Default project for spans |
BRAINTRUST_INSTRUMENT_EXCEPT |
Comma-separated list of integrations to skip |
BRAINTRUST_INSTRUMENT_ONLY |
Comma-separated list of integrations to enable (e.g., openai,anthropic) |
BRAINTRUST_ORG_NAME |
Organization name |
BRAINTRUST_OTEL_FILTER_AI_SPANS |
Set to true to only export AI-related spans |
The SDK automatically instruments these LLM libraries:
| Provider | Gem | Versions | Integration Name | Examples |
|---|---|---|---|---|
| Anthropic | anthropic |
>= 0.3.0 | :anthropic |
Link |
| OpenAI | openai |
>= 0.1.0 | :openai |
Link |
ruby-openai |
>= 7.0.0 | :ruby_openai |
Link | |
| Multiple | ruby_llm |
>= 1.8.0 | :ruby_llm |
Link |
For fine-grained control, disable auto-instrumentation and instrument specific clients:
require "braintrust"
require "openai"
Braintrust.init(auto_instrument: false) # Or BRAINTRUST_AUTO_INSTRUMENT=false
# Instrument all OpenAI clients
Braintrust.instrument!(:openai)
# OR instrument a single client
client = OpenAI::Client.new
Braintrust.instrument!(:openai, target: client)Wrap business logic in spans to see it in your traces:
tracer = OpenTelemetry.tracer_provider.tracer("my-app")
tracer.in_span("process-request") do |span|
span.set_attribute("user.id", user_id)
# LLM calls inside here are automatically nested under this span
response = client.chat.completions.create(...)
endLog binary data (images, PDFs, audio) in your traces:
require "braintrust/trace/attachment"
att = Braintrust::Trace::Attachment.from_file("image/png", "./photo.png")
# Use in messages (OpenAI/Anthropic format)
messages = [
{
role: "user",
content: [
{type: "text", text: "What's in this image?"},
att.to_h
]
}
]
# Log to span
span.set_attribute("braintrust.input_json", JSON.generate(messages))Create attachments from various sources:
Braintrust::Trace::Attachment.from_bytes("image/jpeg", image_data)
Braintrust::Trace::Attachment.from_file("application/pdf", "./doc.pdf")
Braintrust::Trace::Attachment.from_url("https://example.com/image.png")See example: trace_attachments.rb
Get a permalink to any span:
tracer = OpenTelemetry.tracer_provider.tracer("my-app")
tracer.in_span("my-operation") do |span|
# your code here
puts "View trace at: #{Braintrust::Trace.permalink(span)}"
endRun evaluations against your AI systems:
require "braintrust"
Braintrust.init
Braintrust::Eval.run(
project: "my-project",
experiment: "classifier-v1",
cases: [
{input: "apple", expected: "fruit"},
{input: "carrot", expected: "vegetable"}
],
task: ->(input) { classify(input) },
scorers: [
->(input, expected, output) { output == expected ? 1.0 : 0.0 }
]
)Load test cases from a Braintrust dataset:
Braintrust::Eval.run(
project: "my-project",
dataset: "my-dataset",
task: ->(input) { classify(input) },
scorers: [...]
)Use scoring functions defined in Braintrust:
Braintrust::Eval.run(
project: "my-project",
cases: [...],
task: ->(input) { ... },
scorers: [
Braintrust::Scorer.remote("my-project", "accuracy-scorer")
]
)See examples: eval.rb, dataset.rb, remote_functions.rb
First verify there are no errors in your logs after running with BRAINTRUST_DEBUG=true set.
Your application needs the following for this to work:
require 'bundler/setup'
Bundler.requireIt is present by default in Rails applications, but may not be in Sinatra, Rack, or other applications.
Alternatively, you can add require 'braintrust/setup' to your application initialization files.
See CONTRIBUTING.md for development setup and guidelines.
Apache License 2.0 - see LICENSE.