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 Add Span Annotation

From Leeroopedia
Knowledge Sources
Domains AI Observability, Quality Assessment, Span Evaluation
Last Updated 2026-02-14 00:00 GMT

Overview

Concrete tool for attaching a single structured annotation or free-text note to a traced span, provided by the arize-phoenix-client package.

Description

The Spans.add_span_annotation() method creates a single annotation on a span identified by its OpenTelemetry span ID. It constructs a SpanAnnotationData dictionary internally (via the _create_span_annotation() helper) and delegates to log_span_annotations(span_annotations=[anno]) for the actual API call. The annotation consists of a name, annotator kind, and a result containing any combination of label, score, and explanation.

The Spans.add_span_note() method is a specialized variant for adding free-text notes to spans. Unlike regular annotations, notes support multiple entries per span through auto-generated timestamp-based identifiers. Notes are posted to a dedicated v1/span_notes endpoint.

Both methods operate on the Spans sub-client, which is accessed through client.spans.

Usage

Use add_span_annotation() when:

  • Attaching a single quality assessment (label, score, or explanation) to a specific span.
  • Performing human review and recording judgments one span at a time.
  • Running an LLM judge that evaluates spans individually.
  • Upserting an annotation (same span_id + annotation_name + identifier combination updates the existing record).

Use add_span_note() when:

  • Adding free-text commentary to a span without structured label or score.
  • Recording multiple observations on the same span (each note gets a unique identifier).

Code Reference

Source Location

  • Repository: Phoenix
  • File: packages/phoenix-client/src/phoenix/client/resources/spans/__init__.py
  • Lines: 605-721 (add_span_annotation), 723-775 (add_span_note)

Signature

def add_span_annotation(
    self,
    *,
    span_id: str,
    annotation_name: str,
    annotator_kind: Literal["LLM", "CODE", "HUMAN"] = "HUMAN",
    label: Optional[str] = None,
    score: Optional[float] = None,
    explanation: Optional[str] = None,
    metadata: Optional[dict[str, Any]] = None,
    identifier: Optional[str] = None,
    sync: bool = False,
) -> Optional[InsertedSpanAnnotation]:
    ...

def add_span_note(
    self,
    *,
    span_id: str,
    note: str,
) -> InsertedSpanAnnotation:
    ...

Import

from phoenix.client import Client

client = Client()
# Access via: client.spans.add_span_annotation(...)
# Access via: client.spans.add_span_note(...)

I/O Contract

Inputs (add_span_annotation)

Name Type Required Description
span_id str Yes The OpenTelemetry span ID of the span to annotate.
annotation_name str Yes The name of the annotation dimension (e.g., "relevance", "toxicity", "correctness").
annotator_kind Literal["LLM", "CODE", "HUMAN"] No The source of the annotation. Defaults to "HUMAN".
label Optional[str] No A categorical label for the annotation (e.g., "positive", "hallucinated"). At least one of label, score, or explanation must be provided.
score Optional[float] No A numerical score for the annotation. At least one of label, score, or explanation must be provided.
explanation Optional[str] No A free-text explanation of the annotation result. At least one of label, score, or explanation must be provided.
metadata Optional[dict[str, Any]] No Arbitrary key-value metadata associated with the annotation.
identifier Optional[str] No Deduplication key. Annotations are uniquely identified by (span_id, annotation_name, identifier). A None identifier is equivalent to "". Use non-empty identifiers to store multiple annotations with the same name on the same span.
sync bool No If True, the request is processed synchronously and returns the inserted annotation with its ID. If False (default), the request is queued asynchronously and returns None.

Inputs (add_span_note)

Name Type Required Description
span_id str Yes The OpenTelemetry span ID of the span to annotate. Must not be empty after stripping whitespace.
note str Yes The text content of the note. Must not be empty after stripping whitespace.

Outputs

Name Type Description
(add_span_annotation return) Optional[InsertedSpanAnnotation] When sync=True, returns an InsertedSpanAnnotation dict containing the id of the created/updated annotation. When sync=False, returns None.
(add_span_note return) InsertedSpanAnnotation Always returns synchronously with the id of the created note annotation.

Usage Examples

Add a Human Annotation with Label and Score

from phoenix.client import Client

client = Client()

annotation = client.spans.add_span_annotation(
    span_id="051581bf3cb55c13",
    annotation_name="relevance",
    annotator_kind="HUMAN",
    label="relevant",
    score=0.95,
    explanation="The response directly addresses the user's question.",
    sync=True,
)
print(f"Created annotation with ID: {annotation['id']}")

Add an LLM Judge Annotation

from phoenix.client import Client

client = Client()

# Asynchronous (fire-and-forget) annotation from an LLM evaluator
client.spans.add_span_annotation(
    span_id="a1b2c3d4e5f67890",
    annotation_name="hallucination",
    annotator_kind="LLM",
    label="no_hallucination",
    score=0.1,
    explanation="All claims in the response are supported by the retrieved context.",
    metadata={"model": "gpt-4o", "prompt_version": "v2"},
)

Add Multiple Annotations with Identifiers

from phoenix.client import Client

client = Client()

# Two different annotators can create separate annotations with the same name
client.spans.add_span_annotation(
    span_id="051581bf3cb55c13",
    annotation_name="correctness",
    annotator_kind="HUMAN",
    label="correct",
    score=1.0,
    identifier="reviewer-alice",
)

client.spans.add_span_annotation(
    span_id="051581bf3cb55c13",
    annotation_name="correctness",
    annotator_kind="HUMAN",
    label="partially_correct",
    score=0.7,
    identifier="reviewer-bob",
)

Add a Free-Text Note

from phoenix.client import Client

client = Client()

result = client.spans.add_span_note(
    span_id="051581bf3cb55c13",
    note="This span shows unusually high latency due to rate limiting.",
)
print(f"Note created with ID: {result['id']}")

Related Pages

Implements Principle

Page Connections

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