OpenInference Documentation

repository·main·Indexed 22 days ago

https://github.com/arize-ai/openinference

A specification and set of plugins for standardized tracing of AI applications, complementing OpenTelemetry. It enables capturing detailed telemetry for LLM calls, vector store retrievals, and tool usage. The repository includes Go instrumentation for the Anthropic Go SDK and OpenAI Go SDK (including Azure OpenAI), providing features for span suppression, context attribute propagation (session, user, metadata, tags), and PII masking via environment variables or programmatic TraceConfig.

Tokens
235.5K
Snippets
584
Records
760
Agent score
77%

What's inside OpenInference

  1. What is the OpenInference Specification?

    main

    OpenInference is a semantic convention specification for AI application observability, built on top of OpenTelemetry. It standardizes how AI-specific workloads—such as LLM calls, agent reasoning, tool invocations, and retrieval operations—are represented as distributed traces.

    Because OpenTelemetry's default attribute model is generic, OpenInference provides a concrete schema and span-kind taxonomy to handle AI-specific requirements like:

    • Structured inputs/outputs: Handling multi-turn messages and multimodal content.
    • Token economics: Tracking prompt, completion, and reasoning token counts.
    • Agentic control flow: Providing consistent identity for reasoning loops and tool calls.
    • Privacy: Enabling granular masking of sensitive prompt/completion fields.
    • Quality feedback: Associating scores and labels from human or LLM judges with specific operations.
  2. Overview of OpenInference

    main

    OpenInference is a set of conventions and plugins designed to complement OpenTelemetry for tracing AI applications. It provides a standardized way to capture insights into LLM (Large Language Model) invocations and the surrounding application context, such as retrieval from vector stores or the use of external tools (search engines, APIs, etc.).

    OpenInference is natively supported by:

    • Arize Phoenix
    • Arize AX

    However, because it is built on OpenTelemetry principles, it can be used with any OpenTelemetry-compatible backend.

  3. Supported Anthropic SDK features

    main

    The Anthropic instrumentation provides automatic tracing for the following features:

    • Messages API: Full support for anthropic.messages.create().
    • Streaming: Automatic handling of streaming responses.
    • Tool Use: Captures tool/function calling information.
    • Token Usage: Records input/output token counts when available.
    • Error Handling: Proper error recording and span status management.
  4. Understand the @arizeai/openinference-core source structure

    main

    The @arizeai/openinference-core package is organized into several functional modules that provide tracing capabilities, helpers, and type definitions:

    • src/index.ts: The main entry point that re-exports the public API.
    • src/helpers/: Contains utility functions for tracing, including:
      • withSpan.ts: Implementation of the withSpan pattern.
      • wrappers.ts: High-level wrappers like traceChain, traceAgent, and traceTool.
      • decorators.ts: The @observe decorator for easy instrumentation.
      • attributeHelpers.ts: Functions to extract attributes like getLLMAttributes and getEmbeddingAttributes.
      • tracerHelpers.ts: Utilities for managing tracers via getTracer and wrapTracer.
      • types.ts: Core types such as SpanTraceOptions, SpanInput/Output, Message, and TokenCount.
    • src/trace/: Contains the core tracing logic:
      • contextAttributes.ts: Functions to set context like setSession, setUser, and setMetadata.
      • types.ts: Definitions for Session, User, Metadata, PromptTemplate, and Tags.
      • trace-config/: Configuration management, including OITracer, OISpan (a masking-aware wrapper), and maskingRules.
    • src/utils/: General purpose utilities for safety and type checking.
  5. Explore OpenInference JavaScript Libraries

    main

    OpenInference provides a suite of JavaScript packages for instrumenting LLM applications according to semantic conventions. These libraries allow you to trace LLM calls, agentic workflows, and GenAI interactions.

    Key categories of libraries include:

    • Core & Conventions: @arizeai/openinference-core (utilities and configuration) and @arizeai/openinference-semantic-conventions (standardized tracing schemas).
    • SDK Instrumentation: Specific packages for instrumenting popular SDKs like openai, anthropic, bedrock, langchain, and claude-agent-sdk.
    • Framework Support: Integration with frameworks like vercel (Vercel AI SDK), tanstack-ai (middleware), and mcp (Model Context Protocol).
    • Specialized Agents: Instrumentation for beeai and bedrock-agent-runtime.
  6. Compare reasoning/thinking implementations across OpenAI, Anthropic, and Gemini

    main

    This guide provides a side-by-side comparison of how major LLM vendors (OpenAI, Anthropic, and Google Gemini) handle model reasoning (Chain-of-Thought). It compares three primary axes:

    1. Request parameters: How to opt-in and configure reasoning (e.g., setting budgets or effort levels).
    2. Response parts: The structure of the data returned when a model reasons (e.g., where the thinking text lives and how it is distinguished from the final answer).
    3. Multi-turn propagation: How to maintain the reasoning chain across multiple turns (e.g., which 'continuity tokens' or signatures must be echoed back to the server).

    For vendor-specific deep dives, refer to the individual documentation for openai_reasoning.md, anthropic_thinking.md, or gemini_thinking.md.

  7. What is instrumented in Claude Agent SDK

    main

    This package provides auto-instrumentation for two main patterns in the Claude Agent SDK:

    query()

    Each call is wrapped in a single AGENT span named ClaudeAgentSDK.query. It captures:

    • Input: Prompt text or JSON.
    • Output: Result text/JSON from the SDK result message.
    • Metadata: session.id, llm.model_name, token counts, and llm.cost.total (when available).
    • Tools: Tool calls are captured as child TOOL spans via SDK hooks.

    ClaudeSDKClient

    Used for continuous/multi-turn conversations. Each iteration of receive_response() (or receive_messages()) is wrapped in an AGENT span named ClaudeAgentSDK.ClaudeSDKClient.receive_response with the same input/output/metadata/tool spans as query().

    Note: To capture detailed LLM and tool spans inside the agent runs (the underlying Anthropic API calls), you must also install and use openinference-instrumentation-anthropic.

  8. What is traced in the LangChain4j OpenInference example

    main

    When using the OpenInference instrumentation with LangChain4j, the following telemetry data is captured and exported:

    • LLM Calls: All calls made to OpenAI.
    • Messages: Input prompts and output responses.
    • Model Parameters: Configuration such as temperature and max tokens.
    • Token Usage: Token counts (when provided by the provider).
    • Timing: Latency and timing information for the operations.
  9. Echo reasoning and tool-use items for multi-turn continuity

    main

    When implementing stateless (ZDR) multi-turn conversations involving tool use, you must echo the canonical sequence of items in the input[] array. The correct order is:

    1. reasoning item (leads the turn)
    2. function_call item
    3. function_call_output item

    Warning: Do not drop the leading reasoning item when rebuilding the next turn from tool outputs. The server will reject requests that omit the reasoning items that preceded the tool calls. On parallel tool calls, you must echo the reasoning items for every branch.

    {
      "model": "gpt-5",
      "store": false,
      "include": ["reasoning.encrypted_content"],
      "reasoning": { "effort": "medium" },
      "input": [
        { "role": "user", "content": "What's the weather in Paris?" },
        {
          "type": "reasoning",
          "id": "rs_1",
          "summary": [{ "type": "summary_text", "text": "Need to call get_weather for Paris." }],
          "encrypted_content": "gAAAAA...=="
        },
        {
          "type": "function_call",
          "id": "fc_1",
          "call_id": "call_1",
          "name": "get_weather",
          "arguments": "{\"city\":\"Paris\"}"
        },
        {
          "type": "function_call_output",
          "call_id": "call_1",
          "output": "{\"temp_c\":12,\"conditions\":\"cloudy\"}"
        }
      ],
      "tools": [{ "type": "function", "name": "get_weather", "parameters": { /* ... */ } }]
    }
  10. How Realtime audio is instrumented

    main

    The OpenAIAgentsInstrumentor().instrument(...) method automatically traces agents.realtime.RealtimeSession (the OpenAI Agents SDK's voice/audio runtime) if the realtime extras are installed. No additional configuration is required; the instrumentor applies patches whenever agents.realtime is importable.

    For each turn, the instrumentor produces a span tree structured as follows:

    • conversation.turn (Parent): Contains aggregated input/output transcripts, llm.model_name, and llm.invocation_parameters.
      • user (Child): Contains input.audio.url (WAV data URI), input.audio.transcript, or input.value for text.
      • assistant (Child): Contains output.audio.url, output.audio.transcript, token counts, and time_to_first_token_ms.
        • <tool_name> (Grandchild): One span per function call within the turn.
      • Additional user or assistant siblings may exist for split inputs or tool round-trips.
  11. Why both `tracing.tracer` and `functions.tracer` are patched in Google ADK

    main

    In ADK 1.32+, the instrumentor must patch both tracing.tracer and functions.tracer to ensure full coverage of tool execution spans.

    This is necessary because google-adk captures the tracer in a local binding at import time within flows/llm_flows/functions.py:

    from ...telemetry.tracing import tracer  # captured at IMPORT time

    Because this local tracer is captured at import, reassigning tracing.tracer is insufficient to intercept spans generated by parallel-call paths (like execute_tool (merged)). By wrapping functions.tracer independently with the same _SelectiveExecuteToolTracer proxy, the instrumentor ensures that both individual tool calls and merged tool calls are correctly processed as OpenInference spans.

    with tracer.start_as_current_span('execute_tool (merged)'):
        trace_merged_tool_calls(...)
  12. OpenInference Attribute Naming Conventions

    main

    Attributes are typed key/value pairs attached to spans. They follow a structured naming convention to ensure interoperability:

    • Namespacing: Use dot-separated namespaces (e.g., llm.input_messages, llm.token_count.prompt).
    • List Flattening: For list-valued attributes, use zero-based integer indices in a flattened format (e.g., llm.input_messages.0.message.role).

    For a complete list of attribute names, types, and meanings, refer to the Semantic Conventions document.