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.
- Click Workspaces in the sidebar and open the workspace you want to send traces to.
- Open the Service accounts tab and click Create service account.
- Give the service account a name and pick the Trace writer preset, then click Create.
- 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-httpOr with pip:
pip install opentelemetry-sdk opentelemetry-exporter-otlp-proto-httpSend 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-openaiimport 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-anthropicimport 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-genaiimport 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 logfireimport 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-genaiimport 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-langchainimport 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-agentsimport 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.