Jump to content

Connect SuperML | Leeroopedia MCP: Equip your AI agents with best practices, code verification, and debugging knowledge. Powered by Leeroo — building Organizational Superintelligence. Contact us at founders@leeroo.com.

Implementation:Arize ai Phoenix OpenAI Adapter

From Leeroopedia
Revision as of 12:04, 16 February 2026 by Admin (talk | contribs) (Auto-imported from implementations/Arize_ai_Phoenix_OpenAI_Adapter.md)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

Overview

The OpenAIAdapter is a concrete implementation of the BaseLLMAdapter abstract class that integrates the OpenAI Chat Completions API (including Azure OpenAI) into the Phoenix evaluator framework. It resides in the phoenix-evals sub-package and provides both synchronous and asynchronous methods for text generation and structured object extraction. The adapter supports structured output (via json_schema response format), tool calling, and an automatic fallback strategy. It is also aware of model-specific constraints such as varying system role semantics across GPT, o1, and o3 model families.

Description

The module defines the OpenAIAdapter class and two supporting functions: identify_openai_client() and get_openai_rate_limit_errors(). Key design characteristics:

  • Client identification: Detects OpenAI clients by checking for the OpenAIClientWrapper type, the "openai" module namespace, or the presence of chat.completions interface.
  • Dual provider registration: The adapter is registered under both openai and azure providers via separate @register_provider decorators with distinct client factories but the same rate limit error type.
  • Sync/async client detection: Inspects class names for "Async" or uses inspect.iscoroutinefunction on chat.completions.create to determine the client mode. Enforces correct method usage (sync methods on sync clients, async on async).
  • Model-aware system role mapping: The _system_role() method maps system messages to the correct role string based on the model:
    • "system" for GPT models
    • "user" for o1-mini and o1-preview (which do not support system or developer roles)
    • "developer" for o1 and o3 models
  • Capability detection: _supports_structured_output() checks if the model supports JSON schema response format (gpt-4o variants), and _supports_tool_calls() returns False for o1/o3 reasoning models.
  • Schema normalization: _ensure_additional_properties_false() recursively adds "additionalProperties": false to all object types, as required by OpenAI's structured output API.
  • Multimodal support: Handles text, image (base64 and URL), and audio content from legacy MultimodalPrompt objects.

Usage

from openai import OpenAI
from phoenix.evals.llm.adapters.openai.adapter import OpenAIAdapter

# Synchronous usage
client = OpenAI(api_key="sk-...")
adapter = OpenAIAdapter(client=client, model="gpt-4o")

# Text generation
response = adapter.generate_text("What is the capital of France?")

# Structured output (prefers json_schema response format for gpt-4o)
schema = {
    "type": "object",
    "properties": {
        "label": {"type": "string", "enum": ["relevant", "irrelevant"]},
        "explanation": {"type": "string"}
    },
    "required": ["label", "explanation"]
}
result = adapter.generate_object("Classify this text.", schema=schema)
from openai import AsyncOpenAI

# Asynchronous usage
async_client = AsyncOpenAI(api_key="sk-...")
adapter = OpenAIAdapter(client=async_client, model="gpt-4o")

response = await adapter.async_generate_text("Summarize this document.")
result = await adapter.async_generate_object(prompt, schema=schema)
# Azure OpenAI usage (registered under "azure" provider)
from openai import AzureOpenAI

azure_client = AzureOpenAI(
    api_key="...",
    api_version="2024-02-01",
    azure_endpoint="https://my-resource.openai.azure.com/"
)
adapter = OpenAIAdapter(client=azure_client, model="gpt-4o")

Code Reference

Symbol Kind Location Lines
identify_openai_client() Function packages/phoenix-evals/src/phoenix/evals/llm/adapters/openai/adapter.py 19-30
get_openai_rate_limit_errors() Function packages/phoenix-evals/src/phoenix/evals/llm/adapters/openai/adapter.py 33-36
OpenAIAdapter Class packages/phoenix-evals/src/phoenix/evals/llm/adapters/openai/adapter.py 55-594
OpenAIAdapter.generate_text() Method packages/phoenix-evals/src/phoenix/evals/llm/adapters/openai/adapter.py 86-102
OpenAIAdapter.async_generate_text() Method packages/phoenix-evals/src/phoenix/evals/llm/adapters/openai/adapter.py 104-124
OpenAIAdapter.generate_object() Method packages/phoenix-evals/src/phoenix/evals/llm/adapters/openai/adapter.py 126-169
OpenAIAdapter.async_generate_object() Method packages/phoenix-evals/src/phoenix/evals/llm/adapters/openai/adapter.py 171-213
OpenAIAdapter._system_role() Method packages/phoenix-evals/src/phoenix/evals/llm/adapters/openai/adapter.py 382-394
OpenAIAdapter._supports_structured_output() Method packages/phoenix-evals/src/phoenix/evals/llm/adapters/openai/adapter.py 346-349
OpenAIAdapter._supports_tool_calls() Method packages/phoenix-evals/src/phoenix/evals/llm/adapters/openai/adapter.py 351-355

I/O Contract

generate_text / async_generate_text

Direction Type Description
Input Union[PromptLike, MultimodalPrompt] A string prompt, list of message dicts, list of Message TypedDicts, or legacy MultimodalPrompt (with text, image, and audio parts)
Input **kwargs Additional keyword arguments forwarded to client.chat.completions.create()
Output str The choices[0].message.content from the OpenAI response
Raises ValueError If sync method is called on async client (or vice versa), or if content is None
Raises PhoenixUnsupportedAudioFormat If an audio part uses an unsupported format

generate_object / async_generate_object

Direction Type Description
Input Union[PromptLike, MultimodalPrompt] A prompt in any supported format
Input Dict[str, Any] A JSON schema defining the expected output structure
Input ObjectGenerationMethod AUTO (default: prefers structured output for gpt-4o), STRUCTURED_OUTPUT, or TOOL_CALLING
Output Dict[str, Any] Parsed JSON from structured output, or parsed function arguments from tool calls
Raises ValueError If the model does not support the requested method, or no tool calls in response

Usage Examples

Model-Specific System Role Handling

from phoenix.evals.llm.prompts import Message, MessageRole

messages = [
    Message(role=MessageRole.SYSTEM, content="You are a classifier."),
    Message(role=MessageRole.USER, content="Classify this text."),
]

# For GPT models: system message uses role="system"
adapter_gpt = OpenAIAdapter(client=client, model="gpt-4o")
# Internally: [{"role": "system", ...}, {"role": "user", ...}]

# For o1: system message uses role="developer"
adapter_o1 = OpenAIAdapter(client=client, model="o1")
# Internally: [{"role": "developer", ...}, {"role": "user", ...}]

# For o1-mini: system message uses role="user"
adapter_o1mini = OpenAIAdapter(client=client, model="o1-mini")
# Internally: [{"role": "user", ...}, {"role": "user", ...}]

Capability-Aware Object Generation

# gpt-4o supports both structured output and tool calling
# AUTO mode will prefer structured output
adapter = OpenAIAdapter(client=client, model="gpt-4o")
result = adapter.generate_object(prompt, schema=schema)  # Uses json_schema response format

# o1 models do not support tool calling
# AUTO mode will use structured output if available
adapter = OpenAIAdapter(client=client, model="o1")
result = adapter.generate_object(prompt, schema=schema)

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment