Upload Hiererchical Data via SDK
This page outlines the process for logging hierarchical data to Deepchecks.
Logging Hierarchical Data to Deepchecks
Deepchecks supports use cases that involve hierarchical relationships between spans, such as agentic systems, multi-step pipelines, and orchestrated workflows. In these cases, spans may have parent–child relationships, sibling order, and nested execution paths.
This hierarchy is critical both for observability and for evaluations that depend on lineage and ordering (for example, identifying all tool calls that are descendants of an agent).
Many frameworks (such as CrewAI or LangGraph) provide this structure automatically. For users running custom or internal frameworks, Deepchecks allows you to manually define and upload this hierarchical structure using spans. For an up-to-date list of supported frameworks and setup instructions, see the Frameworks page.
Example
This example demonstrates how to log a simple hierarchical trace with a Root span, an Agent span, and a Tool span using the Deepchecks SDK:
import time
from deepchecks_llm_client.client import DeepchecksLLMClient
from deepchecks_llm_client.data_types import EnvType, Span, SpanKind
# Initialize the Deepchecks client
client = DeepchecksLLMClient(
host="https://app.llm.deepchecks.com/",
api_token="x" # Replace "x" with your actual API key
)
# Example trace
trace_id = "trace_001"
session_id = "session_alpha"
base_time = time.time()
# Root span
root_span = Span(
span_id="span_1",
span_name="customer_support_chain",
trace_id=trace_id,
span_kind=SpanKind.CHAIN,
parent_id=None, #This is the root span since span_kind=SpanKind.CHAIN and parent_id=None
started_at=base_time,
finished_at=base_time + 5.0,
input="Customer asks: How do I reset my password?",
output="Password reset instructions provided",
status_code='OK',
session_id=session_id
)
# Agent span (child of Root)
agent_span = Span(
span_id="span_2",
span_name="routing_agent",
trace_id=trace_id,
span_kind=SpanKind.AGENT,
parent_id="span_1",
started_at=base_time + 0.1,
finished_at=base_time + 1.0,
input="Analyze query and route to handler",
output="Route to: password_reset_handler",
status_code='OK',
graph_parent_name="customer_support_chain",
session_id=session_id
)
# Tool span (child of Agent)
tool_span = Span(
span_id="span_3",
span_name="account_verification_tool",
trace_id=trace_id,
span_kind=SpanKind.TOOL,
parent_id="span_2",
started_at=base_time + 1.1,
finished_at=base_time + 1.5,
input="check_account_status(user_id='12345')",
output="{'status': 'active', 'can_reset': true}",
graph_parent_name="routing_agent",
session_id=session_id
)
# Collect spans
spans = [root_span, agent_span, tool_span]
# Log spans to Deepchecks
result = client.log_spans(
app_name="my_app", #Insert your Deepchecks app name here
version_name="v1", #Insert your Deepchecks version name here
env_type=EnvType.EVAL, #Insert the environment here
spans=spans
)Core Classes and Functions
The Span class
Span classThe Span dataclass represents a single unit of work in your system. You define the hierarchy of your trace by creating multiple Span objects and linking them via trace_id and parent_id.
Required fields
span_id – Unique identifier for the span
span_name – Descriptive name of the operation
trace_id – Identifier grouping spans into a single trace
span_kind – Type of span (CHAIN, AGENT, TOOL, LLM, RETRIEVAL)
parent_id – span_id of the parent (None for Root span)
started_at – Start timestamp (float)
finished_at – End timestamp (float)
Recommended / optional fields
input / output – Data passed into or out of the operation
full_prompt – Complete LLM prompt
expected_output – Expected result for evaluations
information_retrieval – Retrieved documents or data
tokens – Number of tokens processed
status_code / status_description – Execution status and context
graph_parent_name – Logical parent span name
session_id – Grouping identifier for related traces
metadata – Custom key–value properties
Root Span NoticeImportant: There must be exactly one Root span per trace, defined as
span_kind=CHAINandparent_id=None.
Logging Spans
To send your spans to Deepchecks, use the log_spans function of the DeepchecksLLMClient class:
client = DeepchecksLLMClient()
client.log_spans(
app_name="my_app",
version_name="v1",
env_type=EnvType.EVAL,
spans=[...list of Span objects...]
)Parameters
app_name – Name of your Deepchecks application
version_name – Deepchecks Version identifier
env_type – Environment type (EVAL or PROD)
spans – List of Span objects representing the trace
Hierarchical data evaluation timingAll spans in a trace should ideally be uploaded together, including the Root span, though this is not mandatory. Evaluations begin only once the Root span is ingested. Child spans uploaded before the Root will be stored until the Root arrives.
Key Considerations
Timestamps are critical
started_at and finished_at define both latency for observability and span order within the trace. Accurate timestamps ensure correct evaluation and visualization of the workflow.
Tokens are optional but recommended
Used for observability, cost tracking, and token-based evaluation metrics. If not provided, Deepchecks does not infer tokens.
Updated 3 days ago