> ## Documentation Index
> Fetch the complete documentation index at: https://docs.trajectory.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Core Concepts

> Trajectories, Steps, Turns, Messages, and how they fit together.

## The Hierarchy

A single agent conversation maps to this four-level hierarchy:

```mermaid theme={null}
graph TD
    T["<b>Trajectory</b><br/>One per conversation"]
    T --> S1["<b>Step 1</b> (Turn 1)"]
    T --> S2["<b>Step 2</b> (Turn 2)"]
    T --> S3["<b>Step 3</b> (Turn 3)"]

    S1 --> M1["system message"]
    S1 --> M2["user message"]
    S1 --> M3["assistant message"]

    S2 --> M4["system message"]
    S2 --> M5["user message"]
    S2 --> M6["assistant message"]
    S2 --> M7["assistant message (tool call)"]
    S2 --> M8["tool message (result)"]
    S2 --> M9["assistant message (final)"]

    S3 --> M10["system message"]
    S3 --> M11["user message 1"]
    S3 --> M12["assistant message 1"]
    S3 --> M13["user message 2"]
    S3 --> M14["assistant message 2"]
    S3 --> M15["user message 3"]
    S3 --> M16["assistant message (tool call)"]
    S3 --> M17["tool message (result)"]
    S3 --> M18["assistant message (final)"]
```

| Level          | What it is                                                                                                  | Count                      |
| -------------- | ----------------------------------------------------------------------------------------------------------- | -------------------------- |
| **Trajectory** | The entire conversation, start to finish                                                                    | One per conversation       |
| **Step**       | A snapshot of the conversation at one decision point, containing all messages up to that point (cumulative) | One per turn               |
| **Turn**       | One user → agent exchange (user speaks, agent thinks/acts/responds)                                         | One or more per trajectory |
| **Message**    | A single message: user input, assistant output, tool call, or tool result                                   | One or more per turn       |

## Trajectory

A **Trajectory** is the SDK's top-level output — one per conversation. It wraps the full multi-turn agent session into a single, structured object.

| Field               | Type                | Description                                                  |
| ------------------- | ------------------- | ------------------------------------------------------------ |
| `task`              | `Task`              | Conversation metadata (ID, source, turn count, tokens, cost) |
| `steps`             | `list[Step]`        | Ordered decision-point snapshots (one per turn)              |
| `reward`            | `Reward`            | Optional aggregate reward signal for the whole conversation  |
| `metrics`           | `TrajectoryMetrics` | Token counts, tool call stats, error rates                   |
| `execution_metrics` | `ExecutionMetrics`  | Timing data (LLM time, total time)                           |
| `error`             | `str`               | Error message if the conversation failed                     |

## Step & Turn

A **Turn** is one user-to-agent exchange: the user sends a message, the agent may call tools, and the agent responds. Turns are the conceptual building block of a conversation.

A **Step** is a Turn's representation inside a Trajectory. Each Step contains the **cumulative** message history up to that point — not just the messages from that turn, but every message from the start of the conversation. This cumulative design means each Step is a self-contained training example: given this full context, here is what the agent did next.

```mermaid theme={null}
sequenceDiagram
    participant User
    participant Agent
    participant Tool

    rect rgb(40, 40, 50)
    note right of User: Turn 1 → Step 1
    User->>Agent: "What's the weather in SF?"
    Agent->>Tool: get_weather("SF")
    Tool-->>Agent: 62°F, foggy
    Agent-->>User: "It's 62°F and foggy in SF."
    end

    rect rgb(40, 40, 50)
    note right of User: Turn 2 → Step 2
    User->>Agent: "Compare that to NYC."
    Agent->>Tool: get_weather("NYC")
    Tool-->>Agent: 45°F, clear
    Agent-->>User: "NYC is 45°F and clear — 17° cooler than SF."
    end
```

**Step 1** would contain 4 messages (system, user, tool, assistant). **Step 2** would contain all 4 messages from Step 1 *plus* the 4 new messages from Turn 2 — 8 messages total.

## Message

A **Message** is the atomic unit — a single piece of content in the conversation. Each Message has a `role` that identifies who produced it:

| Role        | What it represents                | Example                   |
| ----------- | --------------------------------- | ------------------------- |
| `system`    | System prompt                     | Instructions to the agent |
| `user`      | Human input                       | "What's the weather?"     |
| `assistant` | Model output (text or tool calls) | "It's 62°F and foggy."    |
| `tool`      | Tool execution result             | `{"temp": 62}`            |

When the assistant invokes a tool, its message has a `tool_calls` list instead of (or in addition to) text content. The matching `tool` message carries a `tool_response` with the result or error.

## How the SDK Builds This

```mermaid theme={null}
graph LR
    A[Provider API] -->|fetch| B[Raw Traces]
    B -->|parse| C[Turns]
    C -->|accumulate messages| D[Steps]
    D -->|wrap| E[Trajectory]
    E -->|save| F[JSON file]
```

The SDK fetches raw traces from your observability provider, groups them into turns, builds cumulative steps, wraps everything in a Trajectory, and saves it to disk.

See the [API Reference](/sdk/api-reference) for full field definitions on all data models.
