Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.orq.ai/llms.txt

Use this file to discover all available pages before exploring further.

AI Router

Route your LLM calls through the AI Router with a single base URL change. Zero vendor lock-in: always run on the best model at the lowest cost for your use case.

Observability

Instrument your code with OpenTelemetry to capture traces, logs, and metrics for every LLM call, agent step, and tool use.

AI Router

Overview

OpenAI Agents SDK enables powerful AI-driven automation through structured conversations and tool calling. By connecting the Agents SDK to Orq.ai’s AI Router, you transform experimental agents into production-ready systems with enterprise-grade capabilities.

Key Benefits

Orq.ai’s AI Router enhances your OpenAI Agents with:

Complete Observability

Track every agent step, tool use, and interaction with detailed traces and analytics

Built-in Reliability

Automatic fallbacks, retries, and load balancing for production resilience

Cost Optimization

Real-time cost tracking and spend management across all your AI operations

Multi-Provider Access

Access 300+ LLMs and 20+ providers through a single, unified integration

Prerequisites

Before integrating OpenAI Agents SDK with Orq.ai, ensure you have:
  • An Orq.ai account and API Key
  • Python 3.8 or higher
  • OpenAI Agents SDK installed
To setup your API key, see API keys & Endpoints.

Installation

Install the OpenAI Agents SDK:
pip install openai-agents openai

Configuration

Configure OpenAI Agents SDK to use Orq.ai’s AI Router by setting a custom AsyncOpenAI client:
Python
from openai import AsyncOpenAI
from agents import set_default_openai_client
import os

# Configure OpenAI client with Orq.ai AI Router
client = AsyncOpenAI(
    api_key=os.getenv("ORQ_API_KEY"),
    base_url="https://api.orq.ai/v3/router"
)

# Set as default client for all agents
set_default_openai_client(client)
base_url: https://api.orq.ai/v3/router

Basic Agent Example

Here’s a complete example of creating and running an OpenAI agent through Orq.ai:
Python
from openai import AsyncOpenAI
from agents import Agent, Runner, set_default_openai_client
import os

# Configure client with Orq.ai AI Router
client = AsyncOpenAI(
    api_key=os.getenv("ORQ_API_KEY"),
    base_url="https://api.orq.ai/v3/router"
)
set_default_openai_client(client)

# Create agent
agent = Agent(
    name="Assistant",
    instructions="You are a helpful assistant that explains complex concepts simply."
)

# Run the agent
result = Runner.run_sync(agent, "Explain quantum computing in simple terms")
print(result.final_output)

Agent with Tools

OpenAI Agents can use tools while routing through Orq.ai:
Python
from openai import AsyncOpenAI
from agents import Agent, Runner, set_default_openai_client, function_tool
import os

# Configure client
client = AsyncOpenAI(
    api_key=os.getenv("ORQ_API_KEY"),
    base_url="https://api.orq.ai/v3/router"
)
set_default_openai_client(client)

# Define a tool using the @function_tool decorator
@function_tool
def get_weather(location: str) -> str:
    """Get the current weather for a location."""
    return f"The weather in {location} is sunny and 72°F"

# Create agent with tools
agent = Agent(
    name="Weather Assistant",
    instructions="You are a weather assistant. Use the get_weather function to provide weather information.",
    tools=[get_weather]
)

# Run agent with tool access
result = Runner.run_sync(agent, "What's the weather in San Francisco?")
print(result.final_output)

Model Selection

With Orq.ai, you can use any supported model from 20+ providers:
Python
from openai import AsyncOpenAI
from agents import Agent, Runner, set_default_openai_client
import os

# Configure client
client = AsyncOpenAI(
    api_key=os.getenv("ORQ_API_KEY"),
    base_url="https://api.orq.ai/v3/router"
)
set_default_openai_client(client)

# Use Claude
claude_agent = Agent(
    name="Claude Assistant",
    model="claude-sonnet-4-5-20250929",
    instructions="You are a helpful assistant."
)

# Use Gemini
gemini_agent = Agent(
    name="Gemini Assistant",
    model="gemini-2.5-flash",
    instructions="You are a helpful assistant."
)

# Use any other model
groq_agent = Agent(
    name="Groq Assistant",
    model="llama-3.3-70b-versatile",
    instructions="You are a helpful assistant."
)

# Run with different models
result = Runner.run_sync(claude_agent, "Explain machine learning")
print(result.final_output)

Observability

Getting Started

Integrate OpenAI Agents with Orq.ai’s observability to gain complete insights into agent performance, token usage, tool utilization, and conversation flows using OpenTelemetry.

Prerequisites

Before you begin, ensure you have:
  • An Orq.ai account and API Key
  • OpenAI API key and access to the Assistants API
  • Python 3.8+

Install Dependencies

pip install openai-agents orq-ai-sdk opentelemetry-sdk opentelemetry-instrumentation opentelemetry-exporter-otlp-proto-http

Configure Orq.ai

Set up your environment variables to connect to Orq.ai’s OpenTelemetry collector: Unix/Linux/macOS:
export OTEL_EXPORTER_OTLP_ENDPOINT="https://api.orq.ai/v2/otel"
export OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer $ORQ_API_KEY"
export OTEL_RESOURCE_ATTRIBUTES="service.name=openai-agents-app,service.version=1.0.0"
export OPENAI_API_KEY="<YOUR_OPENAI_API_KEY>"
Windows (PowerShell):
$env:OTEL_EXPORTER_OTLP_ENDPOINT = "https://api.orq.ai/v2/otel"
$env:OTEL_EXPORTER_OTLP_HEADERS = "Authorization=Bearer <ORQ_API_KEY>"
$env:OTEL_RESOURCE_ATTRIBUTES = "service.name=openai-agents-app,service.version=1.0.0"
$env:OPENAI_API_KEY = "<YOUR_OPENAI_API_KEY>"
Using .env file:
OTEL_EXPORTER_OTLP_ENDPOINT=https://api.orq.ai/v2/otel
OTEL_EXPORTER_OTLP_HEADERS=Authorization=Bearer <ORQ_API_KEY>
OTEL_RESOURCE_ATTRIBUTES=service.name=openai-agents-app,service.version=1.0.0
OPENAI_API_KEY=<YOUR_OPENAI_API_KEY>

Common Pitfalls

  • Do not set a custom base_url when using OTEL. Pointing the OpenAI client at the AI Router while also exporting spans results in duplicate traces: one from the router, one from the OTEL exporter. Use the router when you need multi-provider routing or fallbacks. Use your OPENAI_API_KEY directly when you only need observability.
  • Do not call set_tracing_disabled(True). The SDK has its own built-in tracing layer. Disabling it flattens the hierarchy and leaves only bare router-level spans with no agent structure.
  • Wrap runs in agent_trace(workflow_name=...). Without it the root span is named "Agent workflow" for every run, making traces impossible to distinguish.
  • Call provider.shutdown() before exit in short scripts. BatchSpanProcessor buffers on a timer and may not flush before the process exits.

Basic Example

Python
import os
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from orq_ai_sdk.openai_agents_instrumentation import OpenAIAgentsInstrumentor
from agents import Agent, Runner
from agents import trace as agent_trace

os.environ["OTEL_EXPORTER_OTLP_ENDPOINT"] = "https://api.orq.ai/v2/otel"
os.environ["OTEL_EXPORTER_OTLP_HEADERS"] = f"Authorization=Bearer {os.environ['ORQ_API_KEY']}"

provider = TracerProvider()
provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter()))
OpenAIAgentsInstrumentor().instrument(tracer_provider=provider)

agent = Agent(name="Assistant", instructions="You are a helpful assistant")

with agent_trace(workflow_name="Haiku-Workflow"):
    result = Runner.run_sync(agent, "Write a haiku about recursion in programming.")
    print(result.final_output)

provider.shutdown()  # flush BatchSpanProcessor before exit

Advanced Example with Function Calling

Python
import os
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from orq_ai_sdk.openai_agents_instrumentation import OpenAIAgentsInstrumentor
from agents import Agent, Runner, function_tool
from agents import trace as agent_trace

os.environ["OTEL_EXPORTER_OTLP_ENDPOINT"] = "https://api.orq.ai/v2/otel"
os.environ["OTEL_EXPORTER_OTLP_HEADERS"] = f"Authorization=Bearer {os.environ['ORQ_API_KEY']}"

provider = TracerProvider()
provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter()))
OpenAIAgentsInstrumentor().instrument(tracer_provider=provider)

@function_tool
def get_weather(location: str) -> str:
    """Mock weather function"""
    return f"The weather in {location} is sunny, 72°F"

agent = Agent(
    name="Weather Assistant",
    instructions="You are a weather assistant. Use the get_weather function to provide weather information.",
    tools=[get_weather]
)

with agent_trace(workflow_name="Weather-Workflow"):
    result = Runner.run_sync(agent, "What's the weather like in Boston?")
    print(result.final_output)

provider.shutdown()

Custom Spans for Agent Operations

Python
import os
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from orq_ai_sdk.openai_agents_instrumentation import OpenAIAgentsInstrumentor
from agents import Agent, Runner
from agents import trace as agent_trace

os.environ["OTEL_EXPORTER_OTLP_ENDPOINT"] = "https://api.orq.ai/v2/otel"
os.environ["OTEL_EXPORTER_OTLP_HEADERS"] = f"Authorization=Bearer {os.environ['ORQ_API_KEY']}"

provider = TracerProvider()
provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter()))
OpenAIAgentsInstrumentor().instrument(tracer_provider=provider)

tracer = provider.get_tracer(__name__)

agent = Agent(
    name="Research Assistant",
    instructions="You are a research assistant specialized in data analysis.",
)

with agent_trace(workflow_name="Research-Workflow"):
    with tracer.start_as_current_span("agent-execution") as exec_span:
        result = Runner.run_sync(agent, "Analyze the trends in the uploaded dataset")
        exec_span.set_attribute("execution.status", "completed")
    print("Final output:", result.final_output)

provider.shutdown()

View Traces

View your traces in the AI Studio in the Traces tab.
Visit your AI Studio to view real-time analytics and traces.

Asset Capture in the Control Tower

When you instrument OpenAI Agents with OpenTelemetry and send traces to Orq.ai, agents, tools, and models are automatically extracted from the spans and registered in Control Tower.

Installation

pip install orq-ai-sdk openai-agents opentelemetry-sdk opentelemetry-instrumentation opentelemetry-exporter-otlp-proto-http

Configuration

Set the OTLP environment variables and initialise the tracer provider with the OpenAIAgentsInstrumentor before running any agents:
Python
import os
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from orq_ai_sdk.openai_agents_instrumentation import OpenAIAgentsInstrumentor

os.environ["OTEL_EXPORTER_OTLP_ENDPOINT"] = "https://api.orq.ai/v2/otel"
os.environ["OTEL_EXPORTER_OTLP_HEADERS"]  = "Authorization=Bearer <your-orq-api-key>"

tracer_provider = TracerProvider()
tracer_provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter()))

OpenAIAgentsInstrumentor().instrument(tracer_provider=tracer_provider)

Examples

Agent with no tools: captures agent/Assistant, model/gpt-4o
Python
from agents import Agent, Runner

agent = Agent(
    name="Assistant",
    instructions="Be extremely concise.",
    model="gpt-4o",
)

result = Runner.run_sync(agent, "What is the capital of France?")
print(result.final_output)
Agent with a single tool: captures agent/Weather Assistant, tool/get_weather, model/gpt-4o
Python
from agents import Agent, Runner, function_tool

@function_tool
def get_weather(location: str) -> str:
    """Get weather for a location."""
    data = {"tokyo": "Sunny, 22°C", "paris": "Cloudy, 15°C", "new york": "Rainy, 18°C"}
    return data.get(location.lower(), f"No data for {location}")

agent = Agent(
    name="Weather Assistant",
    instructions="Use get_weather to answer weather questions.",
    tools=[get_weather],
    model="gpt-4o",
)

result = Runner.run_sync(agent, "What's the weather in Tokyo?")
print(result.final_output)
Multi-agent workflow with handoff: captures agent/Assistant, agent/Spanish Assistant, tool/random_number_tool, model/gpt-4o
Python
import random
from agents import Agent, Runner, function_tool, handoff, trace as agent_trace
from agents.extensions import handoff_filters
from agents import HandoffInputData

@function_tool
def random_number_tool(max: int) -> int:
    """Return a random integer between 0 and the given maximum."""
    return random.randint(0, max)

def spanish_handoff_message_filter(handoff_message_data: HandoffInputData) -> HandoffInputData:
    handoff_message_data = handoff_filters.remove_all_tools(handoff_message_data)
    history = (
        tuple(handoff_message_data.input_history[2:])
        if isinstance(handoff_message_data.input_history, tuple)
        else handoff_message_data.input_history
    )
    return HandoffInputData(
        input_history=history,
        pre_handoff_items=tuple(handoff_message_data.pre_handoff_items),
        new_items=tuple(handoff_message_data.new_items),
    )

spanish_agent = Agent(
    name="Spanish Assistant",
    instructions="You only speak Spanish and are extremely concise.",
    handoff_description="A Spanish-speaking assistant.",
    model="gpt-4o",
)

first_agent = Agent(
    name="Assistant",
    instructions="Be extremely concise.",
    tools=[random_number_tool],
    model="gpt-4o",
)

second_agent = Agent(
    name="Assistant",
    instructions="Be helpful. If the user speaks Spanish, handoff to the Spanish assistant.",
    handoffs=[handoff(spanish_agent, input_filter=spanish_handoff_message_filter)],
    model="gpt-4o",
)

async def run_workflow():
    with agent_trace(workflow_name="Multi-Agent Workflow"):
        result = await Runner.run(first_agent, input="Hi, my name is Sora.")
        result = await Runner.run(
            first_agent,
            input=result.to_input_list() + [
                {"content": "Generate a random number between 0 and 100.", "role": "user"}
            ],
        )
        result = await Runner.run(
            second_agent,
            input=result.to_input_list() + [
                {"content": "Por favor habla en español. ¿Cuál es mi nombre?", "role": "user"}
            ],
        )
    print(result.final_output)

# In Jupyter notebooks (async supported natively)
await run_workflow()

# In regular Python scripts
import asyncio
asyncio.run(run_workflow())
After running your code, open the Assets page in Control Tower. Agents, tools, and models from your runs will appear automatically under their respective tabs.

Evaluations & Experiments

Once your agents are running, use Evaluatorq to score outputs across a dataset and Experiments to compare configurations side-by-side.

Run Evaluations with Evaluatorq

Run parallel evaluations across your agents and compare results.

Run Experiments via the API

Compare agent configurations and view results in the AI Studio.