Implementation:Arize ai Phoenix Anthropic Adapter
Overview
The AnthropicAdapter is a concrete implementation of the BaseLLMAdapter abstract class that integrates the Anthropic Claude API 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 via Anthropic's Messages API. The adapter is auto-registered using the @register_adapter and @register_provider decorators, enabling automatic detection when an Anthropic client is passed to the evaluation pipeline.
Description
The module defines the AnthropicAdapter class along with two supporting functions: identify_anthropic_client() and get_anthropic_rate_limit_errors(). Together they enable the Phoenix evaluator framework to:
- Identify whether a given client object is an Anthropic client (by checking for the
AnthropicClientWrappertype, theanthropicmodule namespace, or the presence ofmessages.create). - Retrieve Anthropic-specific rate limit exception types for integration with the rate limiting subsystem.
- Adapt Anthropic's Messages API to the four core adapter methods:
generate_text(),async_generate_text(),generate_object(), andasync_generate_object().
The adapter handles several Anthropic-specific concerns:
- System message extraction: Anthropic requires system messages to be passed as a separate
systemparameter rather than within the messages array. The adapter extracts system messages automatically. - max_tokens requirement: Anthropic mandates the
max_tokensparameter. The adapter injects a default of 4096 if not provided. - Tool calling for structured output: Since Anthropic does not support native structured output, the adapter uses tool calling (via
tool_choicewith forced tool use) for all object generation methods. TheSTRUCTURED_OUTPUTmethod raises aValueError. - Sync/async client detection: The adapter inspects the client class name (looking for
"Async") or usesinspect.iscoroutinefunctionto determine whether the underlying client is synchronous or asynchronous, and enforces correct method usage.
Usage
The adapter is typically instantiated automatically by the Phoenix evaluator framework when a user provides an Anthropic client. Direct instantiation is also possible:
from anthropic import Anthropic
from phoenix.evals.llm.adapters.anthropic.adapter import AnthropicAdapter
# Synchronous usage
client = Anthropic(api_key="sk-...")
adapter = AnthropicAdapter(client=client, model="claude-sonnet-4-20250514")
# Text generation
response = adapter.generate_text("What is the capital of France?")
# Structured output via tool calling
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 anthropic import AsyncAnthropic
from phoenix.evals.llm.adapters.anthropic.adapter import AnthropicAdapter
# Asynchronous usage
async_client = AsyncAnthropic(api_key="sk-...")
adapter = AnthropicAdapter(client=async_client, model="claude-sonnet-4-20250514")
response = await adapter.async_generate_text("Summarize this document.")
result = await adapter.async_generate_object(prompt, schema=schema)
Code Reference
I/O Contract
generate_text / async_generate_text
| Direction | Type | Description |
|---|---|---|
| Input | Union[PromptLike, MultimodalPrompt] |
A string prompt, a list of message dicts, a list of Message TypedDicts, or a legacy MultimodalPrompt
|
| Input | **kwargs |
Additional keyword arguments forwarded to client.messages.create()
|
| Output | str |
The text content from the first content block of the Anthropic response |
| Raises | ValueError |
If sync method is called on async client (or vice versa), or if the response has an unexpected 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 that the returned object must conform to |
| Input | ObjectGenerationMethod |
The generation strategy: AUTO (default), TOOL_CALLING, or STRUCTURED_OUTPUT (not supported, raises error)
|
| Output | Dict[str, Any] |
A dictionary extracted from the tool call input field in the response
|
| Raises | ValueError |
If STRUCTURED_OUTPUT is requested, schema validation fails, or no tool use is found in the response
|
Usage Examples
Using with the Evaluator Framework
from anthropic import Anthropic
from phoenix.evals import Evaluator
# The framework auto-detects the Anthropic client via identify_anthropic_client()
client = Anthropic()
evaluator = Evaluator(client=client, model="claude-sonnet-4-20250514")
Message Format Conversion
The adapter converts various prompt formats to Anthropic's expected message structure. System messages are extracted and passed separately:
from phoenix.evals.llm.prompts import Message, MessageRole
messages = [
Message(role=MessageRole.SYSTEM, content="You are a helpful assistant."),
Message(role=MessageRole.USER, content="Hello!"),
]
# Internally, _build_messages() returns:
# messages = [{"role": "user", "content": "Hello!"}]
# system = "You are a helpful assistant."
Related Pages
- Arize_ai_Phoenix_LLM_Base_Types - Abstract base class
BaseLLMAdapterand core type definitions - Arize_ai_Phoenix_OpenAI_Adapter - OpenAI adapter following the same interface
- Arize_ai_Phoenix_Google_Adapter - Google GenAI adapter following the same interface
- Arize_ai_Phoenix_LLM_Prompts - Prompt template and message abstraction layer
- Arize_ai_Phoenix_Evals_Rate_Limiters - Rate limiting subsystem integrated via
get_anthropic_rate_limit_errors() - Arize_ai_Phoenix_Evals_Executors - Task execution framework that orchestrates adapter calls