> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/Arize-ai/openinference/llms.txt
> Use this file to discover all available pages before exploring further.

# Quickstart

> Get started with OpenInference in 5 minutes. Install instrumentation, launch Phoenix, and start tracing your first LLM application.

This guide will help you instrument your first AI application with OpenInference and visualize traces in Phoenix.

## Prerequisites

Choose your language:

<Tabs>
  <Tab title="Python">
    * Python 3.9 or higher
    * An OpenAI API key (or another LLM provider)
  </Tab>

  <Tab title="JavaScript">
    * Node.js 18 or higher
    * npm or yarn
    * An OpenAI API key (or another LLM provider)
  </Tab>

  <Tab title="Java">
    * Java 11 or higher
    * Gradle or Maven
  </Tab>
</Tabs>

## Installation

<Steps>
  <Step title="Install OpenInference instrumentation">
    Install the OpenInference instrumentation library for your framework:

    <Tabs>
      <Tab title="Python">
        <CodeGroup>
          ```bash pip theme={null}
          pip install openinference-instrumentation-openai "openai>=1.26" arize-phoenix opentelemetry-sdk opentelemetry-exporter-otlp
          ```

          ```bash uv theme={null}
          uv pip install openinference-instrumentation-openai "openai>=1.26" arize-phoenix opentelemetry-sdk opentelemetry-exporter-otlp
          ```

          ```bash poetry theme={null}
          poetry add openinference-instrumentation-openai "openai>=1.26" arize-phoenix opentelemetry-sdk opentelemetry-exporter-otlp
          ```
        </CodeGroup>

        <Note>
          Replace `openinference-instrumentation-openai` with the instrumentation for your framework:

          * LangChain: `openinference-instrumentation-langchain`
          * LlamaIndex: `openinference-instrumentation-llama-index`
          * Anthropic: `openinference-instrumentation-anthropic`
          * See [all Python instrumentations](/python)
        </Note>
      </Tab>

      <Tab title="JavaScript">
        <CodeGroup>
          ```bash npm theme={null}
          npm install --save @arizeai/openinference-instrumentation-openai @opentelemetry/sdk-trace-node @opentelemetry/exporter-trace-otlp-http @opentelemetry/resources @opentelemetry/instrumentation openai
          ```

          ```bash yarn theme={null}
          yarn add @arizeai/openinference-instrumentation-openai @opentelemetry/sdk-trace-node @opentelemetry/exporter-trace-otlp-http @opentelemetry/resources @opentelemetry/instrumentation openai
          ```

          ```bash pnpm theme={null}
          pnpm add @arizeai/openinference-instrumentation-openai @opentelemetry/sdk-trace-node @opentelemetry/exporter-trace-otlp-http @opentelemetry/resources @opentelemetry/instrumentation openai
          ```
        </CodeGroup>

        <Note>
          Replace `@arizeai/openinference-instrumentation-openai` with the instrumentation for your framework:

          * LangChain: `@arizeai/openinference-instrumentation-langchain`
          * Anthropic: `@arizeai/openinference-instrumentation-anthropic`
          * Bedrock: `@arizeai/openinference-instrumentation-bedrock`
          * See [all JavaScript instrumentations](/javascript)
        </Note>
      </Tab>

      <Tab title="Java">
        **Gradle:**

        ```gradle theme={null}
        dependencies {
            implementation 'com.arize:openinference-instrumentation-langchain4j:0.1.+'
            implementation 'io.opentelemetry:opentelemetry-api:1.49.0'
            implementation 'io.opentelemetry:opentelemetry-sdk:1.49.0'
            implementation 'io.opentelemetry:opentelemetry-exporter-otlp:1.49.0'
        }
        ```

        **Maven:**

        ```xml theme={null}
        <dependencies>
            <dependency>
                <groupId>com.arize</groupId>
                <artifactId>openinference-instrumentation-langchain4j</artifactId>
                <version>0.1.+</version>
            </dependency>
            <dependency>
                <groupId>io.opentelemetry</groupId>
                <artifactId>opentelemetry-api</artifactId>
                <version>1.49.0</version>
            </dependency>
        </dependencies>
        ```
      </Tab>
    </Tabs>
  </Step>

  <Step title="Start Phoenix server">
    Phoenix is an open-source AI observability platform that runs entirely on your machine. Start the server to collect traces:

    <Tabs>
      <Tab title="Python">
        ```bash theme={null}
        python -m phoenix.server.main serve
        ```

        Phoenix will start on `http://localhost:6006`. Open this URL in your browser.
      </Tab>

      <Tab title="JavaScript">
        ```bash theme={null}
        python -m phoenix.server.main serve
        ```

        Phoenix will start on `http://localhost:6006`. Open this URL in your browser.

        <Note>
          Phoenix requires Python even when instrumenting JavaScript apps. Install it with `pip install arize-phoenix`.
        </Note>
      </Tab>

      <Tab title="Java">
        ```bash theme={null}
        python -m phoenix.server.main serve
        ```

        Phoenix will start on `http://localhost:6006`. Open this URL in your browser.

        <Note>
          Phoenix requires Python. Install it with `pip install arize-phoenix`.
        </Note>
      </Tab>
    </Tabs>

    <Tip>
      The Phoenix server does not send data over the internet — all traces stay on your machine.
    </Tip>
  </Step>

  <Step title="Set your API key">
    Set your OpenAI API key as an environment variable:

    <CodeGroup>
      ```bash macOS/Linux theme={null}
      export OPENAI_API_KEY="your-api-key-here"
      ```

      ```powershell Windows theme={null}
      $env:OPENAI_API_KEY="your-api-key-here"
      ```
    </CodeGroup>
  </Step>

  <Step title="Instrument your application">
    Create a file with the following code to instrument your first LLM call:

    <Tabs>
      <Tab title="Python">
        Create `app.py`:

        ```python app.py theme={null}
        import openai
        from openinference.instrumentation.openai import OpenAIInstrumentor
        from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
        from opentelemetry.sdk import trace as trace_sdk
        from opentelemetry.sdk.trace.export import SimpleSpanProcessor

        # Configure OpenTelemetry to send traces to Phoenix
        endpoint = "http://127.0.0.1:6006/v1/traces"
        tracer_provider = trace_sdk.TracerProvider()
        tracer_provider.add_span_processor(SimpleSpanProcessor(OTLPSpanExporter(endpoint)))

        # Instrument OpenAI
        OpenAIInstrumentor().instrument(tracer_provider=tracer_provider)

        if __name__ == "__main__":
            # Make an OpenAI call - it will be automatically traced
            client = openai.OpenAI()
            response = client.chat.completions.create(
                model="gpt-3.5-turbo",
                messages=[{"role": "user", "content": "Write a haiku about observability."}],
                max_tokens=50,
            )
            print(response.choices[0].message.content)
        ```

        Run the application:

        ```bash theme={null}
        python app.py
        ```
      </Tab>

      <Tab title="JavaScript">
        Create `instrumentation.js`:

        ```javascript instrumentation.js theme={null}
        const { NodeTracerProvider } = require('@opentelemetry/sdk-trace-node');
        const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-http');
        const { SimpleSpanProcessor } = require('@opentelemetry/sdk-trace-node');
        const { OpenAIInstrumentation } = require('@arizeai/openinference-instrumentation-openai');
        const { registerInstrumentations } = require('@opentelemetry/instrumentation');

        // Configure OpenTelemetry to send traces to Phoenix
        const provider = new NodeTracerProvider();
        provider.addSpanProcessor(
          new SimpleSpanProcessor(
            new OTLPTraceExporter({
              url: 'http://127.0.0.1:6006/v1/traces',
            })
          )
        );
        provider.register();

        // Register OpenAI instrumentation
        registerInstrumentations({
          instrumentations: [new OpenAIInstrumentation()],
        });
        ```

        Create `app.js`:

        ```javascript app.js theme={null}
        const OpenAI = require('openai');

        const client = new OpenAI({
          apiKey: process.env.OPENAI_API_KEY,
        });

        async function main() {
          const response = await client.chat.completions.create({
            model: 'gpt-3.5-turbo',
            messages: [{ role: 'user', content: 'Write a haiku about observability.' }],
            max_tokens: 50,
          });
          console.log(response.choices[0].message.content);
        }

        main();
        ```

        Run the application:

        ```bash theme={null}
        node -r ./instrumentation.js app.js
        ```

        <Warning>
          The instrumentation file must be required before your application code runs. Use the `-r` flag to ensure it loads first.
        </Warning>
      </Tab>

      <Tab title="Java">
        Create `Main.java`:

        ```java Main.java theme={null}
        import io.openinference.instrumentation.langchain4j.LangChain4jInstrumentor;
        import io.opentelemetry.api.GlobalOpenTelemetry;
        import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter;
        import io.opentelemetry.sdk.OpenTelemetrySdk;
        import io.opentelemetry.sdk.trace.SdkTracerProvider;
        import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor;
        import dev.langchain4j.model.openai.OpenAiChatModel;

        public class Main {
            public static void main(String[] args) {
                // Configure OpenTelemetry to send traces to Phoenix
                SdkTracerProvider tracerProvider = SdkTracerProvider.builder()
                    .addSpanProcessor(
                        SimpleSpanProcessor.create(
                            OtlpHttpSpanExporter.builder()
                                .setEndpoint("http://127.0.0.1:6006/v1/traces")
                                .build()
                        )
                    )
                    .build();

                OpenTelemetrySdk.builder()
                    .setTracerProvider(tracerProvider)
                    .buildAndRegisterGlobal();

                // Auto-instrument LangChain4j
                LangChain4jInstrumentor.instrument();

                // Make an LLM call - it will be automatically traced
                OpenAiChatModel model = OpenAiChatModel.builder()
                    .apiKey(System.getenv("OPENAI_API_KEY"))
                    .modelName("gpt-3.5-turbo")
                    .build();

                String response = model.generate("Write a haiku about observability.");
                System.out.println(response);
            }
        }
        ```

        Run the application:

        ```bash theme={null}
        ./gradlew run
        ```
      </Tab>
    </Tabs>
  </Step>

  <Step title="View traces in Phoenix">
    Open Phoenix in your browser at `http://localhost:6006`. You'll see:

    * **Traces view**: All LLM calls with timing, token counts, and costs
    * **Span details**: Input messages, output messages, model parameters
    * **Timeline**: Visual representation of the execution flow

    <Frame>
      <img src="https://raw.githubusercontent.com/Arize-ai/phoenix-assets/main/images/trace_details.png" alt="Phoenix trace details" />
    </Frame>
  </Step>
</Steps>

## What's captured?

OpenInference automatically captures:

<CardGroup cols={2}>
  <Card title="Messages" icon="messages">
    Full conversation history including system prompts, user messages, and assistant responses
  </Card>

  <Card title="Token counts" icon="hashtag">
    Prompt tokens, completion tokens, cached tokens, and reasoning tokens
  </Card>

  <Card title="Model parameters" icon="sliders">
    Temperature, max tokens, top-p, and other invocation parameters
  </Card>

  <Card title="Costs" icon="dollar-sign">
    Estimated costs for prompt and completion tokens in USD
  </Card>

  <Card title="Timing" icon="clock">
    Start time, end time, and duration with nanosecond precision
  </Card>

  <Card title="Errors" icon="triangle-exclamation">
    Exception messages and stack traces when calls fail
  </Card>
</CardGroup>

## Advanced example with context

Add session tracking, user IDs, and custom metadata to your traces:

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    from openinference.instrumentation import using_attributes

    with using_attributes(
        session_id="user-session-123",
        user_id="user-456",
        metadata={
            "environment": "production",
            "version": "1.0.0",
        },
        tags=["chat", "customer-support"],
    ):
        response = client.chat.completions.create(
            model="gpt-3.5-turbo",
            messages=[{"role": "user", "content": "How do I reset my password?"}],
        )
    ```
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    const { context, trace } = require('@opentelemetry/api');
    const { SemanticAttributes } = require('@arizeai/openinference-semantic-conventions');

    const span = trace.getTracer('my-app').startSpan('chat');
    span.setAttribute(SemanticAttributes.SESSION_ID, 'user-session-123');
    span.setAttribute(SemanticAttributes.USER_ID, 'user-456');
    span.setAttribute(SemanticAttributes.METADATA, JSON.stringify({
      environment: 'production',
      version: '1.0.0',
    }));
    span.setAttribute(SemanticAttributes.TAG_TAGS, JSON.stringify(['chat', 'customer-support']));

    context.with(trace.setSpan(context.active(), span), async () => {
      const response = await client.chat.completions.create({
        model: 'gpt-3.5-turbo',
        messages: [{ role: 'user', content: 'How do I reset my password?' }],
      });
      span.end();
    });
    ```
  </Tab>

  <Tab title="Java">
    ```java theme={null}
    import io.opentelemetry.api.trace.Span;
    import io.openinference.semconv.trace.SpanAttributes;

    Span span = GlobalOpenTelemetry.getTracer("my-app").spanBuilder("chat").startSpan();
    span.setAttribute(SpanAttributes.SESSION_ID, "user-session-123");
    span.setAttribute(SpanAttributes.USER_ID, "user-456");
    span.setAttribute(SpanAttributes.METADATA, "{\"environment\": \"production\", \"version\": \"1.0.0\"}");

    try {
        String response = model.generate("How do I reset my password?");
        System.out.println(response);
    } finally {
        span.end();
    }
    ```
  </Tab>
</Tabs>

## Streaming example

OpenInference supports streaming LLM responses:

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    response = client.chat.completions.create(
        model="gpt-3.5-turbo",
        messages=[{"role": "user", "content": "Write a story about AI."}],
        stream=True,
        stream_options={"include_usage": True},  # Required for token counts
    )

    for chunk in response:
        if chunk.choices and (content := chunk.choices[0].delta.content):
            print(content, end="")
    ```

    <Note>
      Set `stream_options={"include_usage": True}` to capture token counts when streaming (requires `openai>=1.26`).
    </Note>
  </Tab>

  <Tab title="JavaScript">
    ```javascript theme={null}
    const stream = await client.chat.completions.create({
      model: 'gpt-3.5-turbo',
      messages: [{ role: 'user', content: 'Write a story about AI.' }],
      stream: true,
    });

    for await (const chunk of stream) {
      const content = chunk.choices[0]?.delta?.content;
      if (content) {
        process.stdout.write(content);
      }
    }
    ```
  </Tab>
</Tabs>

## Next steps

<CardGroup cols={2}>
  <Card title="Python instrumentations" icon="python" href="/python/instrumentations">
    Explore all 30+ Python instrumentation libraries
  </Card>

  <Card title="JavaScript instrumentations" icon="js" href="/javascript/instrumentations">
    Explore JavaScript/TypeScript instrumentations
  </Card>

  <Card title="Privacy controls" icon="shield-halved" href="/configuration/privacy-controls">
    Configure data masking and PII protection
  </Card>

  <Card title="Concepts" icon="book" href="/concepts/overview">
    Learn about traces, spans, and attributes
  </Card>
</CardGroup>
