> ## Documentation Index
> Fetch the complete documentation index at: https://docs.scorecard.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Tracing

> Instrument and inspect every LLM request in minutes.

export const DarkLightImage = ({lightSrc, caption, alt, darkSrc = null, width = "1000"}) => {
  const getAbsoluteUrl = src => {
    if (src.startsWith('http://') || src.startsWith('https://')) {
      return src;
    }
    const currentUrl = typeof window !== 'undefined' ? window.location.origin : '';
    if (currentUrl.includes('.mintlify.app')) {
      const subdomain = currentUrl.split('.')[0].replace('https://', '');
      return `https://mintlify.s3.us-west-1.amazonaws.com/${subdomain}${src.startsWith('/') ? '' : '/'}${src}`;
    } else if (currentUrl === 'https://docs.scorecard.io') {
      return `https://mintlify.s3.us-west-1.amazonaws.com/scorecard-d65b5e8a${src.startsWith('/') ? '' : '/'}${src}`;
    } else {
      return `${currentUrl}${src.startsWith('/') ? '' : '/'}${src}`;
    }
  };
  const content = <>
      <img className="block dark:hidden" width={width} src={getAbsoluteUrl(lightSrc)} alt={alt} />
      <img className="hidden dark:block" width={width} src={getAbsoluteUrl(darkSrc || lightSrc.replace('light', 'dark'))} alt={alt} />
    </>;
  if (caption) {
    return <Frame caption={caption}>{content}</Frame>;
  } else {
    return content;
  }
};

<Info>
  New to Scorecard? Head straight to the [Tracing Quickstart](/intro/tracing-quickstart) or jump into our ready-to-run [Google Colab notebook](https://colab.research.google.com/github/scorecard-ai/scorecard-examples/blob/main/python-jupyter-openllmetry-openai/openllmetry_openai_example.ipynb) to see traces in under 5 minutes.
</Info>

LLM observability means knowing exactly what happened in every generation—latency, token usage, prompts, completions, cost, errors and more. Scorecard's **Tracing** collects this data automatically—via SDK wrappers, environment variables, [OpenLLMetry](https://github.com/traceloop/openllmetry), an LLM proxy, or direct OpenTelemetry—and displays rich visualisations in the Scorecard UI.

## Why Tracing matters

* Debug long or failing requests in seconds.
* Audit prompts & completions for compliance and safety.
* Attribute quality and cost back to specific services or users.
* Feed production traffic into evaluations.

### If you call it something else

* **Observability / AI spans / request logs**: We capture standard OpenTelemetry traces and spans for LLM calls and related operations.
* **Agent runs / tools / function calls**: These appear as nested spans in the trace tree, with inputs/outputs when available.
* **Prompt/Completion pairs**: Extracted from common keys (`openinference.*`, `ai.prompt` / `ai.response`, `gen_ai.*`) so they can be turned into testcases and scored.

***

## Instrumentation Methods

Choose the method that fits your stack. All methods send traces to Scorecard's OpenTelemetry endpoint.

<Tabs>
  <Tab title="Agent Frameworks">
    For frameworks with built-in OpenTelemetry support (Claude Agent SDK, OpenAI Agents SDK). No code changes—just set environment variables.

    ```bash highlight={1-4} theme={null}
    export OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer <your-scorecard-api-key>"
    export BETA_TRACING_ENDPOINT="https://tracing.scorecard.io/otel"
    export ENABLE_BETA_TRACING_DETAILED=1
    export OTEL_RESOURCE_ATTRIBUTES="scorecard.project_id=<your-project-id>"
    ```

    <CodeGroup>
      ```python Python theme={null}
      # No code changes required — just set the env vars above and run your app.
      import anyio
      from claude_agent_sdk import (
          AssistantMessage,
          TextBlock,
          query,
      )

      async def main():
          async for message in query(prompt="What is 2 + 2?"):
              if isinstance(message, AssistantMessage):
                  for block in message.content:
                      if isinstance(block, TextBlock):
                          print(f"Claude: {block.text}")

      anyio.run(main)
      ```

      ```ts TypeScript theme={null}
      // No code changes required — just set the env vars above and run your app.
      import {
        AssistantMessage,
        TextBlock,
        query,
      } from "@anthropic-ai/claude-agent-sdk";

      async function main() {
        const stream = query({
          prompt: "What is 2 + 2?",
        });

        for await (const message of stream) {
          if (message instanceof AssistantMessage) {
            for (const block of message.content) {
              if (block instanceof TextBlock) {
                console.log("Claude:", block.text);
              }
            }
          }
        }
      }

      main();
      ```
    </CodeGroup>

    See the [Claude Agent SDK Tracing](/intro/claude-agent-sdk-tracing) guide for details.
  </Tab>

  <Tab title="SDK Wrappers">
    One-line wrapper for OpenAI, Anthropic, or Vercel AI SDK clients. Install the `scorecard-ai` package and wrap your client—no other changes needed.

    <CodeGroup>
      ```bash Python theme={null}
      pip install scorecard-ai
      ```

      ```bash TypeScript theme={null}
      npm install scorecard-ai
      ```
    </CodeGroup>

    **OpenAI**

    <CodeGroup>
      ```python Python highlight={1,5,7} theme={null}
      from scorecard_ai import wrap
      from openai import OpenAI
      import os

      openai = wrap(
          OpenAI(api_key=os.getenv("OPENAI_API_KEY")),
      )

      response = openai.chat.completions.create(
          model="gpt-4o",
          messages=[
              {"role": "system", "content": "You are a helpful assistant."},
              {"role": "user", "content": "What is the capital of France?"},
          ],
      )

      print(response.choices[0].message.content)
      ```

      ```ts TypeScript highlight={1,4,8} theme={null}
      import { wrap } from 'scorecard-ai';
      import OpenAI from 'openai';

      const openai = wrap(
        new OpenAI({
          apiKey: process.env['OPENAI_API_KEY'],
        }),
      );

      const response = await openai.chat.completions.create({
        model: 'gpt-4o',
        messages: [
          { role: 'system', content: 'You are a helpful assistant.' },
          { role: 'user', content: 'What is the capital of France?' },
        ],
      });

      console.log(response.choices[0]?.message?.content);
      ```
    </CodeGroup>

    **Anthropic**

    <CodeGroup>
      ```python Python highlight={1,5,7} theme={null}
      from scorecard_ai import wrap
      from anthropic import Anthropic
      import os

      claude = wrap(
          Anthropic(api_key=os.getenv("ANTHROPIC_API_KEY")),
      )

      response = claude.messages.create(
          model="claude-sonnet-4-20250514",
          max_tokens=1024,
          messages=[{"role": "user", "content": "What is the capital of France?"}],
      )

      text_content = next(
          (block for block in response.content if block.type == "text"), None
      )
      print(text_content.text if text_content else "No response")
      ```

      ```ts TypeScript highlight={1,4,8} theme={null}
      import { wrap } from 'scorecard-ai';
      import Anthropic from '@anthropic-ai/sdk';

      const claude = wrap(
        new Anthropic({
          apiKey: process.env['ANTHROPIC_API_KEY'],
        }),
      );

      const response = await claude.messages.create({
        model: 'claude-sonnet-4-20250514',
        max_tokens: 1024,
        messages: [{ role: 'user', content: 'What is the capital of France?' }],
      });

      const textContent = response.content.find((block) => block.type === 'text');
      console.log(textContent?.text);
      ```
    </CodeGroup>

    **Vercel AI SDK** (TypeScript only)

    ```ts TypeScript highlight={3,5} theme={null}
    import { openai } from '@ai-sdk/openai';
    import * as ai from 'ai';
    import { wrapAISDK } from 'scorecard-ai';

    const aiSDK = wrapAISDK(ai);

    const { text } = await aiSDK.generateText({
      model: openai('gpt-4o'),
      prompt: 'What is the capital of France?',
    });

    console.log(text);
    ```

    See the [Tracing Quickstart](/intro/tracing-quickstart) and [Vercel AI SDK wrapper](/features/ai-sdk-wrapper) for full setup details.
  </Tab>

  <Tab title="Traceloop">
    Universal OpenTelemetry-based tracing via [OpenLLMetry](https://github.com/traceloop/openllmetry). Supports LangChain, LlamaIndex, CrewAI, and 20+ providers.

    <CodeGroup>
      ```bash Python theme={null}
      pip install traceloop-sdk
      ```

      ```bash TypeScript theme={null}
      npm install @traceloop/node-server-sdk
      ```
    </CodeGroup>

    Set these environment variables:

    ```bash highlight={1-2} theme={null}
    export TRACELOOP_BASE_URL="https://tracing.scorecard.io/otel"
    export TRACELOOP_HEADERS="Authorization=Bearer%20<your-scorecard-api-key>"
    ```

    <CodeGroup>
      ```python Python highlight={1-3,6,10} theme={null}
      from traceloop.sdk import Traceloop
      from traceloop.sdk.decorators import workflow
      from traceloop.sdk.instruments import Instruments
      from openai import OpenAI

      Traceloop.init(disable_batch=True, instruments={Instruments.OPENAI})

      client = OpenAI()

      @workflow(name="simple_chat")
      def chat():
          response = client.chat.completions.create(
              model="gpt-4o",
              messages=[{"role": "user", "content": "Hello!"}]
          )
          return response.choices[0].message.content

      result = chat()
      print(result)
      ```

      ```ts TypeScript highlight={1,4-7,12,18} theme={null}
      import * as traceloop from "@traceloop/node-server-sdk";
      import OpenAI from "openai";

      traceloop.initialize({
        disableBatch: true,
        instrumentModules: { openAI: OpenAI },
      });

      const openai = new OpenAI();

      async function chat() {
        return await traceloop.withWorkflow({ name: "simple_chat" }, async () => {
          const response = await openai.chat.completions.create({
            model: "gpt-4o",
            messages: [{ role: "user", content: "Hello!" }],
          });
          return response.choices[0].message.content;
        });
      }

      const result = await chat();
      console.log(result);
      ```
    </CodeGroup>

    **LangChain** — add `opentelemetry-instrumentation-langchain` and use `Instruments.LANGCHAIN`:

    ```python Python highlight={1-8} theme={null}
    from traceloop.sdk import Traceloop
    from traceloop.sdk.instruments import Instruments

    # IMPORTANT: Initialize Traceloop before importing any LangChain modules.
    Traceloop.init(
        disable_batch=True,
        instruments={Instruments.LANGCHAIN}
    )

    from langchain_openai import ChatOpenAI
    from langchain_core.prompts import ChatPromptTemplate

    prompt = ChatPromptTemplate.from_messages([
        ("system", "You are a helpful assistant."),
        ("user", "{input}")
    ])

    model = ChatOpenAI(model="gpt-4o-mini")
    chain = prompt | model

    response = chain.invoke({"input": "What is the capital of France?"})
    print(response.content)
    ```

    **LlamaIndex** — use `Instruments.LLAMA_INDEX`:

    ```python Python highlight={1-2,6-9} theme={null}
    from traceloop.sdk import Traceloop
    from traceloop.sdk.instruments import Instruments
    from llama_index.llms.openai import OpenAI
    from llama_index.core.llms import ChatMessage

    Traceloop.init(
        disable_batch=True,
        instruments={Instruments.LLAMA_INDEX, Instruments.OPENAI}
    )

    llm = OpenAI(model="gpt-4o")
    response = llm.chat([ChatMessage(role="user", content="Hello!")])

    print(response.message.content)
    ```

    **CrewAI** — use `Instruments.CREWAI`:

    ```python Python highlight={1-2,5-8} theme={null}
    from traceloop.sdk import Traceloop
    from traceloop.sdk.instruments import Instruments
    from crewai import Agent, Task, Crew

    Traceloop.init(
        disable_batch=True,
        instruments={Instruments.CREWAI, Instruments.OPENAI}
    )

    researcher = Agent(
        role="Researcher",
        goal="Research and summarize topics",
        backstory="You are an expert researcher.",
    )

    task = Task(
        description="What is the capital of France?",
        expected_output="A brief answer",
        agent=researcher,
    )

    crew = Crew(agents=[researcher], tasks=[task])
    result = crew.kickoff()

    print(result)
    ```

    See the [LangChain Quickstart](/intro/langchain-quickstart) and supported [frameworks and providers](#supported-frameworks--providers) below.
  </Tab>

  <Tab title="LLM Proxy">
    Change your `baseURL` to `https://llm.scorecard.io`. No SDK, no dependencies—just a URL change.

    <CodeGroup>
      ```python Python highlight={6-9} theme={null}
      from openai import OpenAI
      import os

      client = OpenAI(
          api_key=os.environ["OPENAI_API_KEY"],
          base_url="https://llm.scorecard.io",
          default_headers={
              "x-scorecard-api-key": os.environ["SCORECARD_API_KEY"],
          },
      )

      response = client.chat.completions.create(
          model="gpt-4o",
          messages=[{"role": "user", "content": "What is the capital of France?"}],
      )

      print(response.choices[0].message.content)
      ```

      ```ts TypeScript highlight={5-8} theme={null}
      import OpenAI from 'openai';

      const client = new OpenAI({
        apiKey: process.env.OPENAI_API_KEY,
        baseURL: 'https://llm.scorecard.io',
        defaultHeaders: {
          'x-scorecard-api-key': process.env.SCORECARD_API_KEY,
        },
      });

      const response = await client.chat.completions.create({
        model: 'gpt-4o',
        messages: [{ role: 'user', content: 'What is the capital of France?' }],
      });

      console.log(response.choices[0].message.content);
      ```
    </CodeGroup>

    See the [Tracing Quickstart](/intro/tracing-quickstart) for full setup details.
  </Tab>

  <Tab title="OpenTelemetry">
    Send traces directly using any OpenTelemetry SDK (Python, TypeScript, Java, Go, .NET, Rust).

    * **Endpoint:** `https://tracing.scorecard.io/otel/v1/traces`
    * **Auth:** `Authorization: Bearer <SCORECARD_API_KEY>`

    <CodeGroup>
      ```bash Python wrap theme={null}
      pip install opentelemetry-api opentelemetry-sdk opentelemetry-exporter-otlp-proto-grpc
      ```

      ```bash TypeScript wrap theme={null}
      npm install @opentelemetry/api @opentelemetry/sdk-trace-node @opentelemetry/sdk-trace-base @opentelemetry/exporter-trace-otlp-http @opentelemetry/resources @opentelemetry/semantic-conventions
      ```
    </CodeGroup>

    <CodeGroup>
      ```python Python highlight={2-23,27,29-33,45} theme={null}
      from anthropic import Anthropic
      from opentelemetry import trace
      from opentelemetry.sdk.trace import TracerProvider
      from opentelemetry.sdk.trace.export import BatchSpanProcessor
      from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
      from opentelemetry.sdk.resources import Resource
      from opentelemetry.semconv.resource import ResourceAttributes
      import os

      resource = Resource.create({
          ResourceAttributes.SERVICE_NAME: "my-app",
      })

      trace_provider = TracerProvider(resource=resource)
      trace_provider.add_span_processor(BatchSpanProcessor(
          OTLPSpanExporter(
              endpoint="https://tracing.scorecard.io/otel",
              headers={"Authorization": f"Bearer {os.environ['SCORECARD_API_KEY']}"}
          )
      ))
      trace.set_tracer_provider(trace_provider)

      tracer = trace.get_tracer(__name__)
      client = Anthropic()

      @tracer.start_as_current_span("chat")
      def chat(prompt: str) -> str:
          span = trace.get_current_span()
          span.set_attributes({
              "gen_ai.system": "anthropic",
              "gen_ai.request.model": "claude-sonnet-4-20250514",
          })

          message = client.messages.create(
              model="claude-sonnet-4-20250514",
              max_tokens=1024,
              messages=[{"role": "user", "content": prompt}],
          )

          return message.content[0].text

      result = chat("What is the capital of France?")
      print(result)

      trace.get_tracer_provider().force_flush()
      ```

      ```ts TypeScript highlight={1-6,9-25,29-31,38-39,47} theme={null}
      import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-http";
      import { Resource } from "@opentelemetry/resources";
      import { BatchSpanProcessor } from "@opentelemetry/sdk-trace-base";
      import { NodeTracerProvider } from "@opentelemetry/sdk-trace-node";
      import { ATTR_SERVICE_NAME } from "@opentelemetry/semantic-conventions";
      import { trace, SpanStatusCode } from "@opentelemetry/api";
      import OpenAI from "openai";

      const exporter = new OTLPTraceExporter({
        url: "https://tracing.scorecard.io/otel/v1/traces",
        headers: {
          Authorization: `Bearer ${process.env.SCORECARD_API_KEY}`,
        },
      });

      const tracerProvider = new NodeTracerProvider({
        resource: Resource.default().merge(
          new Resource({ [ATTR_SERVICE_NAME]: "my-app" })
        ),
      });

      tracerProvider.addSpanProcessor(new BatchSpanProcessor(exporter));
      tracerProvider.register();

      const tracer = trace.getTracer("my-app");
      const openai = new OpenAI();

      async function chat(prompt: string) {
        return tracer.startActiveSpan("chat", async (span) => {
          span.setAttribute("gen_ai.system", "openai");
          span.setAttribute("gen_ai.request.model", "gpt-4o");

          const completion = await openai.chat.completions.create({
            model: "gpt-4o",
            messages: [{ role: "user", content: prompt }],
          });

          span.setStatus({ code: SpanStatusCode.OK });
          span.end();
          return completion.choices[0].message.content;
        });
      }

      const result = await chat("What is the capital of France?");
      console.log(result);

      await tracerProvider.forceFlush();
      ```
    </CodeGroup>
  </Tab>
</Tabs>

***

## View Traces in the Records Page

Ingested traces appear on the **Records** page alongside records from other sources (API, Playground, Kickoff). Each row in the table shows:

<DarkLightImage lightSrc="/images/tracing-records-list-light.png" darkSrc="/images/tracing-records-list-dark.png" caption="Records page showing ingested traces." alt="Records page showing a list of traced records" />

Each row shows the record's inputs, outputs, status, source, trace ID, and metric scores. You can search by inputs, outputs, and expected values, or filter by `status`, `source`, `trace.id`, `run.id`, `testcase.id`, `metric`, `metadata`, time range, and more. Use **Quick Filters** for presets like "My Recent Records". Customise visible columns via the **Edit Table** modal.

Open a record to see more details including the **span tree**, **conversation** (for chat-based traces), **timeline**, and **scores**:

<DarkLightImage lightSrc="/images/tracing-record-spans-light.png" darkSrc="/images/tracing-record-spans-dark.png" caption="Record detail view showing the span tree" alt="Record detail view showing spans with inputs, outputs, and timing" />

***

## Trace Grouping

When running batch operations or multi-step workflows, you can group related traces into a single run using the `scorecard.tracing_group_id` span attribute. This makes it easier to track and analyze workflows that span multiple LLM calls.

### How it works

Add the `scorecard.tracing_group_id` attribute to your spans with a shared identifier. Scorecard automatically groups spans with the same group ID into a single run.

<CodeGroup>
  ```python Python highlight={1-6,8-9,12-13} theme={null}
  from opentelemetry import trace

  tracer = trace.get_tracer(__name__)

  # Use the same group_id for all related operations
  group_id = "batch-job-123"

  with tracer.start_as_current_span("process_document") as span:
      span.set_attribute("scorecard.tracing_group_id", group_id)
      # Your LLM call here

  with tracer.start_as_current_span("summarize_results") as span:
      span.set_attribute("scorecard.tracing_group_id", group_id)
      # Another LLM call in the same workflow
  ```

  ```typescript TypeScript highlight={1-10,12-14,16} theme={null}
  import { trace } from '@opentelemetry/api';

  const tracer = trace.getTracer('my-service');

  // Use the same groupId for all related operations
  const groupId = 'batch-job-123';

  const span1 = tracer.startSpan('process_document');
  span1.setAttribute('scorecard.tracing_group_id', groupId);
  // Your LLM call here
  span1.end();

  const span2 = tracer.startSpan('summarize_results');
  span2.setAttribute('scorecard.tracing_group_id', groupId);
  // Another LLM call in the same workflow
  span2.end();
  ```
</CodeGroup>

### Use cases

* **Batch processing**: Group all documents processed in a single batch job
* **Multi-step agents**: Track all LLM calls within an agent's execution
* **Workflows**: Link related operations across different services
* **A/B testing**: Group traces by experiment variant for comparison

<Tip>
  Traces with the same `scorecard.tracing_group_id` will appear together in the same run, making it easy to analyze aggregate metrics across related operations.
</Tip>

***

## AI-Specific Error Detection

Scorecard's tracing goes beyond technical failures to detect AI-specific behavioral issues that traditional observability misses. The system acts as an always-on watchdog, analyzing every AI interaction to catch both obvious technical errors and subtle behavioral problems that could impact user experience.

### Silent Failure Detection

The most dangerous errors in AI systems are "silent failures" where your AI responds but incorrectly. Scorecard automatically detects behavioral errors including off-topic responses, workflow interruptions, safety violations, hallucinations, and context loss. These silent failures often go unnoticed without specialized AI observability but can severely impact user trust and application effectiveness.

Technical errors like rate limits, timeouts, and API failures are captured automatically through standard trace error recording. However, AI applications also face unique challenges like semantic drift, safety policy violations, factual accuracy issues, and task completion failures that require intelligent analysis beyond traditional error logging.

### Custom Error Detection

Create custom metrics through Scorecard's UI to detect application-specific behavioral issues. Design AI-powered metrics that analyze trace data for off-topic responses, safety violations, or task completion failures. These custom metrics automatically evaluate your traces and surface problematic interactions that would otherwise go unnoticed in production.

***

## Supported Frameworks & Providers

Scorecard traces LLM applications built with popular open-source frameworks through [OpenLLMetry](https://github.com/traceloop/openllmetry). OpenLLMetry provides automatic instrumentation for:

### Application Frameworks

* **CrewAI** – Multi-agent collaboration
* **Haystack** – Search and question-answering pipelines
* **LangChain** – Chains, agents, and tool calls
* **Langflow** – Visual workflow builder
* **LangGraph** – Multi-step workflows and state machines
* **LiteLLM** – Unified interface for 100+ LLMs
* **LlamaIndex** – RAG pipelines and document retrieval
* [**OpenAI Agents SDK**](https://github.com/openai/openai-agents-python?tab=readme-ov-file#tracing) – Assistants API and function calling
* [**Vercel AI SDK**](https://ai-sdk.dev/providers/observability/scorecard) – Full-stack AI applications

<Tip>
  Scorecard is featured as a recommended observability provider in the official [Vercel AI SDK documentation](https://ai-sdk.dev/providers/observability/scorecard) and [OpenAI Agents Python README](https://github.com/openai/openai-agents-python?tab=readme-ov-file#tracing).
</Tip>

### LLM Providers

* Aleph Alpha
* Anthropic
* AWS Bedrock
* AWS SageMaker
* Azure OpenAI
* Cohere
* Google Gemini
* Google Vertex AI
* Groq
* HuggingFace
* IBM Watsonx AI
* Mistral AI
* Ollama
* OpenAI
* Replicate
* Together AI
* and more

### Vector Databases

* Chroma
* LanceDB
* Marqo
* Milvus
* Pinecone
* Qdrant
* Weaviate

<Info>
  For the complete list of supported integrations, see the [OpenLLMetry repository](https://github.com/traceloop/openllmetry). All integrations are built on OpenTelemetry standards and maintained by the community.
</Info>

### Custom Providers

For frameworks or providers not listed above, you can use:

* **HTTP Instrumentation**: OpenLLMetry's `instrument_http()` for HTTP-based APIs
* **Manual Spans**: Emit custom OpenTelemetry spans for proprietary systems

See the [OpenLLMetry documentation](https://www.traceloop.com/docs/openllmetry/getting-started-python) for manual instrumentation guides.

***

## Use cases

* **Production observability for LLM quality and safety**
* **Debugging slow/failed requests with full span context**
* **Auditing prompts/completions for compliance**
* **Attributing token cost and latency to services/cohorts**
* **Building evaluation datasets from real traffic (Trace to Testcase)**

***

## Next steps

1. Follow the [Tracing Quickstart](/intro/tracing-quickstart) to send your first trace.
2. Set up [Claude Agent SDK Tracing](/intro/claude-agent-sdk-tracing) with zero code changes.
3. Instrument [LangChain](/intro/langchain-quickstart) chains and agents.
4. Use the [Vercel AI SDK wrapper](/features/ai-sdk-wrapper) for full-stack AI apps.
5. Open the [Colab notebook](https://colab.research.google.com/github/scorecard-ai/scorecard-examples/blob/main/python-jupyter-openllmetry-openai/openllmetry_openai_example.ipynb) for an interactive tour.

Happy tracing! 🚀
