Blue Guardrails
Getting started

Getting started

Set up Blue Guardrails to monitor issues in your AI application

Blue Guardrails detects issues in LLM-powered applications or workflows. It analyzes the model's responses and identifies when it fabricates information or contradicts provided context.

To connect your AI application to Blue Guardrails, follow this guide. It walks through sending model inputs and outputs from your application to your Blue Guardrails workspace.

Prerequisites

  • A Blue Guardrails account
  • Membership in a workspace with a role of Contributor or higher (see Roles and permissions)

Create an API key

To send data to Blue Guardrails, you need an API key for your workspace.

  1. Click Workspaces in the sidebar and open the workspace you want to send traces to.
  2. Open the Service accounts tab and click Create service account.
  3. Give the service account a name and pick the Trace writer preset, then click Create.
  4. In the new row, click Create key, name the key, choose an expiration, and click Create.

Copy the key now. Blue Guardrails only displays it once.

For more options, including read access, evaluations, and experiments, see Create an API key for your workspace.

Install OpenTelemetry

Blue Guardrails receives data from your AI application via OpenTelemetry traces. Use the OpenTelemetry GenAI instrumentation packages to trace supported libraries.

Install the OpenTelemetry SDK and HTTP trace exporter:

uv add opentelemetry-sdk opentelemetry-exporter-otlp-proto-http

Or with pip:

pip install opentelemetry-sdk opentelemetry-exporter-otlp-proto-http

Send your first traces

Choose your library below. Each example installs tracing support and sends message content to Blue Guardrails.

Replace <YOUR_API_KEY> before running the example. If you use pip, replace uv add with pip install.

uv add openai opentelemetry-instrumentation-genai-openai
import os

os.environ['OTEL_EXPORTER_OTLP_TRACES_ENDPOINT'] = 'https://api.blueguardrails.com/v1/traces'
os.environ['OTEL_EXPORTER_OTLP_TRACES_HEADERS'] = 'Authorization=Bearer <YOUR_API_KEY>'
os.environ['OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT'] = 'SPAN_ONLY'

from openai import OpenAI
from opentelemetry import trace
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from opentelemetry.instrumentation.genai.openai import OpenAIInstrumentor
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor

tracer_provider = TracerProvider()
tracer_provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter()))
trace.set_tracer_provider(tracer_provider)
OpenAIInstrumentor().instrument(tracer_provider=tracer_provider)

client = OpenAI()
response = client.chat.completions.create(
    model='gpt-4o-mini',
    messages=[
        {'role': 'system', 'content': 'Answer the question based on the context.'},
        {'role': 'user', 'content': 'Context: Revenue in Q1 was $85 Billion.'},
        {'role': 'user', 'content': 'What was the revenue in Q1?'},
    ],
)
print(response.choices[0].message.content)
tracer_provider.shutdown()
uv add anthropic opentelemetry-instrumentation-genai-anthropic
import os

os.environ['OTEL_EXPORTER_OTLP_TRACES_ENDPOINT'] = 'https://api.blueguardrails.com/v1/traces'
os.environ['OTEL_EXPORTER_OTLP_TRACES_HEADERS'] = 'Authorization=Bearer <YOUR_API_KEY>'
os.environ['OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT'] = 'SPAN_ONLY'

from anthropic import Anthropic
from opentelemetry import trace
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from opentelemetry.instrumentation.genai.anthropic import AnthropicInstrumentor
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor

tracer_provider = TracerProvider()
tracer_provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter()))
trace.set_tracer_provider(tracer_provider)
AnthropicInstrumentor().instrument(tracer_provider=tracer_provider)

client = Anthropic()
response = client.messages.create(
    max_tokens=1000,
    model='claude-haiku-4-5',
    system='Answer the question based on the context.',
    messages=[
        {'role': 'user', 'content': 'Context: Revenue in Q1 was $85 Billion.'},
        {'role': 'user', 'content': 'What was the revenue in Q1?'},
    ],
)
print(response.content[0].text)
tracer_provider.shutdown()
uv add google-genai opentelemetry-instrumentation-google-genai
import os

os.environ['OTEL_EXPORTER_OTLP_TRACES_ENDPOINT'] = 'https://api.blueguardrails.com/v1/traces'
os.environ['OTEL_EXPORTER_OTLP_TRACES_HEADERS'] = 'Authorization=Bearer <YOUR_API_KEY>'
os.environ['OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT'] = 'SPAN_ONLY'

from google.genai import Client
from opentelemetry import trace
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from opentelemetry.instrumentation.google_genai import GoogleGenAiSdkInstrumentor
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor

tracer_provider = TracerProvider()
tracer_provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter()))
trace.set_tracer_provider(tracer_provider)
GoogleGenAiSdkInstrumentor().instrument(tracer_provider=tracer_provider)

client = Client()
message = '''Answer the question based on the context.
Context: Revenue in Q1 was $85 Billion.
What was the revenue in Q1?'''
response = client.models.generate_content(model='gemini-2.5-flash', contents=message)
print(response.text)
tracer_provider.shutdown()
uv add pydantic-ai logfire
import os

os.environ['OTEL_EXPORTER_OTLP_TRACES_ENDPOINT'] = 'https://api.blueguardrails.com/v1/traces'
os.environ['OTEL_EXPORTER_OTLP_TRACES_HEADERS'] = 'Authorization=Bearer <YOUR_API_KEY>'

import logfire
from pydantic_ai import Agent

logfire.configure(send_to_logfire=False)
logfire.instrument_pydantic_ai()

agent = Agent(
    'openai:gpt-4o-mini',
    instructions='Answer the question based on the context.',
)
result = agent.run_sync(
    'Context: Revenue in Q1 was $85 Billion.\nWhat was the revenue in Q1?'
)
print(result.output)
uv add haystack-ai anthropic-haystack google-genai-haystack opentelemetry-instrumentation-genai-openai opentelemetry-instrumentation-genai-anthropic opentelemetry-instrumentation-google-genai
import os

os.environ['OTEL_EXPORTER_OTLP_TRACES_ENDPOINT'] = 'https://api.blueguardrails.com/v1/traces'
os.environ['OTEL_EXPORTER_OTLP_TRACES_HEADERS'] = 'Authorization=Bearer <YOUR_API_KEY>'
os.environ['OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT'] = 'SPAN_ONLY'

from haystack.components.generators.chat import OpenAIChatGenerator
from haystack.dataclasses import ChatMessage
from haystack_integrations.components.generators.anthropic import AnthropicChatGenerator
from haystack_integrations.components.generators.google_genai import GoogleGenAIChatGenerator
from opentelemetry import trace
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from opentelemetry.instrumentation.genai.anthropic import AnthropicInstrumentor
from opentelemetry.instrumentation.genai.openai import OpenAIInstrumentor
from opentelemetry.instrumentation.google_genai import GoogleGenAiSdkInstrumentor
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor

tracer_provider = TracerProvider()
tracer_provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter()))
trace.set_tracer_provider(tracer_provider)
OpenAIInstrumentor().instrument(tracer_provider=tracer_provider)
AnthropicInstrumentor().instrument(tracer_provider=tracer_provider)
GoogleGenAiSdkInstrumentor().instrument(tracer_provider=tracer_provider)

messages = [
    ChatMessage.from_system('Answer the question based on the context.'),
    ChatMessage.from_user(
        'Context: Revenue in Q1 was $85 Billion.\nWhat was the revenue in Q1?'
    ),
]

openai_response = OpenAIChatGenerator(model='gpt-4o-mini').run(messages)
anthropic_response = AnthropicChatGenerator(model='claude-haiku-4-5').run(messages)
google_response = GoogleGenAIChatGenerator(model='gemini-2.5-flash').run(
    messages=messages
)

print(openai_response)
print(anthropic_response)
print(google_response)
tracer_provider.shutdown()
uv add langgraph langchain-openai opentelemetry-instrumentation-genai-langchain
import os

os.environ['OTEL_EXPORTER_OTLP_TRACES_ENDPOINT'] = 'https://api.blueguardrails.com/v1/traces'
os.environ['OTEL_EXPORTER_OTLP_TRACES_HEADERS'] = 'Authorization=Bearer <YOUR_API_KEY>'
os.environ['OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT'] = 'SPAN_ONLY'

from langchain_openai import ChatOpenAI
from langgraph.prebuilt import create_react_agent
from opentelemetry import trace
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from opentelemetry.instrumentation.genai.langchain import LangChainInstrumentor
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor

tracer_provider = TracerProvider()
tracer_provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter()))
trace.set_tracer_provider(tracer_provider)
LangChainInstrumentor().instrument(tracer_provider=tracer_provider)

agent = create_react_agent(
    ChatOpenAI(model='gpt-4o-mini'),
    tools=[],
    prompt='Answer the question based on the context.',
    name='agent',
)
result = agent.invoke({
    'messages': [{
        'role': 'user',
        'content': 'Context: Revenue in Q1 was $85 Billion.\nWhat was the revenue in Q1?',
    }]
})
print(result['messages'][-1].content)
tracer_provider.shutdown()
uv add openai-agents opentelemetry-instrumentation-genai-openai opentelemetry-instrumentation-genai-openai-agents
import os

os.environ['OTEL_EXPORTER_OTLP_TRACES_ENDPOINT'] = 'https://api.blueguardrails.com/v1/traces'
os.environ['OTEL_EXPORTER_OTLP_TRACES_HEADERS'] = 'Authorization=Bearer <YOUR_API_KEY>'
os.environ['OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT'] = 'SPAN_ONLY'

from agents import Agent, Runner
from opentelemetry import trace
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from opentelemetry.instrumentation.genai.openai import OpenAIInstrumentor
from opentelemetry.instrumentation.genai.openai_agents import OpenAIAgentsInstrumentor
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor

tracer_provider = TracerProvider()
tracer_provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter()))
trace.set_tracer_provider(tracer_provider)
OpenAIInstrumentor().instrument(tracer_provider=tracer_provider)
OpenAIAgentsInstrumentor().instrument(
    tracer_provider=tracer_provider,
    disable_openai_trace_export=True,
)

agent = Agent(
    name='Revenue analyst',
    instructions='Answer the question based on the context.',
    model='gpt-4o-mini',
)
result = Runner.run_sync(
    agent,
    'Context: Revenue in Q1 was $85 Billion.\nWhat was the revenue in Q1?',
)
print(result.final_output)
tracer_provider.shutdown()
uv add claude-agent-sdk "langsmith[otel]"
import asyncio
import os

# Set these before importing langsmith or claude_agent_sdk.
os.environ['LANGSMITH_OTEL_ENABLED'] = 'true'
os.environ['LANGSMITH_OTEL_ONLY'] = 'true'
os.environ['LANGSMITH_TRACING'] = 'true'
os.environ['OTEL_EXPORTER_OTLP_TRACES_ENDPOINT'] = 'https://api.blueguardrails.com/v1/traces'
os.environ['OTEL_EXPORTER_OTLP_TRACES_HEADERS'] = 'Authorization=Bearer <YOUR_API_KEY>'

from claude_agent_sdk import ClaudeAgentOptions, ClaudeSDKClient
from langsmith.integrations.claude_agent_sdk import configure_claude_agent_sdk
from opentelemetry import trace
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor

tracer_provider = TracerProvider()
tracer_provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter()))
trace.set_tracer_provider(tracer_provider)
configure_claude_agent_sdk()

async def main() -> None:
    options = ClaudeAgentOptions(
        allowed_tools=['Read', 'Edit', 'Glob'],
        permission_mode='acceptEdits',
    )

    async with ClaudeSDKClient(options=options) as client:
        await client.query(
            'Read sample_code.py and convert all numpy-style docstrings '
            'to Google-style docstrings. Edit the file in place.'
        )

        async for message in client.receive_response():
            if hasattr(message, 'content'):
                for block in message.content:
                    if hasattr(block, 'text'):
                        print(block.text)
                    elif hasattr(block, 'name'):
                        print(f'Tool: {block.name}')

try:
    asyncio.run(main())
finally:
    tracer_provider.shutdown()

After running your code, traces appear in Blue Guardrails within a few seconds. Open your workspace and click Dashboard to see incoming messages and issue metrics.

Next steps

On this page