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

# ATIF

> Record and exchange agent trajectories in a standard JSON format.

The **Agent Trajectory Interchange Format (ATIF)** records an agent's complete
interaction history as JSON: messages, reasoning, tool calls, observations, and
metrics.

## Why

Agents produce [different native logs](/core-concepts/jobs/loading-trajectories#native-trajectories).
Without a shared format, every viewer, dataset, and training pipeline needs an
agent-specific parser. ATIF provides one stable representation across agents,
making trajectories easier to inspect, compare, validate, load, and reuse.

See the [ATIF RFC](https://github.com/harbor-framework/harbor/blob/main/rfcs/0001-trajectory-format.md)
for the complete specification.

## `trajectory.json` in Harbor

<Info>
  In Harbor, an ATIF trajectory is usually named **`trajectory.json`**.
</Info>

Agents with `capabilities.atif = true` write it to the agent log directory. In a
downloaded trial result, the path is `agent/trajectory.json`.

Harbor uses this file to:

* **Render trajectories:** The [results viewer](/core-concepts/results/view-job-results#start-the-viewer)
  reads `agent/trajectory.json` and displays its steps in the **Trajectory** tab.
* **Load trajectories:** Supported agents can use an
  [ATIF trajectory](/core-concepts/jobs/loading-trajectories#atif-trajectories) to seed a new
  session.

<Note>
  Producing ATIF and loading ATIF are separate capabilities. An agent may write
  `trajectory.json` without supporting [loading trajectories](/core-concepts/jobs/loading-trajectories).
</Note>

Custom agents should declare `AgentCapabilities(atif=True)` only when they write
a valid `self.logs_dir / "trajectory.json"`.

## Structure

Harbor's current format is `ATIF-v1.7`. A trajectory contains:

| Field                   | Purpose                                                        |
| ----------------------- | -------------------------------------------------------------- |
| `agent`                 | Agent name, version, model, and optional tool definitions.     |
| `steps`                 | Ordered system, user, and agent interactions.                  |
| `session_id`            | Optional identifier shared by trajectories from one run.       |
| `trajectory_id`         | Optional document identifier; required for embedded subagents. |
| `final_metrics`         | Optional aggregate token, cost, and step metrics.              |
| `subagent_trajectories` | Optional embedded ATIF trajectories.                           |
| `extra`                 | Custom root-level metadata.                                    |

Step IDs start at `1` and remain sequential. Agent steps can include
`tool_calls`, matching `observation` results, and per-step `metrics`.

```json theme={"system"}
{
  "schema_version": "ATIF-v1.7",
  "session_id": "session-123",
  "agent": {
    "name": "my-agent",
    "version": "1.0.0",
    "model_name": "openai/gpt-5.6-sol"
  },
  "steps": [
    {
      "step_id": 1,
      "source": "user",
      "message": "Create hello.txt."
    },
    {
      "step_id": 2,
      "source": "agent",
      "message": "I'll create it.",
      "tool_calls": [
        {
          "tool_call_id": "call-1",
          "function_name": "write_file",
          "arguments": {"path": "hello.txt", "content": "Hello"}
        }
      ],
      "observation": {
        "results": [
          {"source_call_id": "call-1", "content": "File created"}
        ]
      }
    }
  ]
}
```

<Accordion title="Build with Harbor models">
  Harbor provides Pydantic models in `harbor.models.trajectories`:

  ```python theme={"system"}
  import json
  from pathlib import Path

  from harbor.models.trajectories import Agent, Step, Trajectory

  trajectory = Trajectory(
      agent=Agent(name="my-agent", version="1.0.0"),
      steps=[
          Step(step_id=1, source="user", message="Create hello.txt."),
          Step(step_id=2, source="agent", message="Done."),
      ],
  )

  Path("trajectory.json").write_text(
      json.dumps(trajectory.to_json_dict(), indent=2) + "\n"
  )
  ```
</Accordion>

## Validate a trajectory

```bash theme={"system"}
uv run python -m harbor.utils.trajectory_validator path/to/trajectory.json
```

Validation checks the schema, sequential step IDs, tool-call references,
timestamps, and referenced local images. Use `--no-validate-images` to skip the
image-file check.

<Accordion title="Validate in Python">
  ```python theme={"system"}
  from harbor.utils.trajectory_validator import TrajectoryValidator

  validator = TrajectoryValidator()

  if not validator.validate("trajectory.json"):
      for error in validator.get_errors():
          print(error)
  ```
</Accordion>

## Versions and extensions

Harbor accepts `ATIF-v1.0` through `ATIF-v1.7`. Version 1.7 adds embedded
subagent trajectories, per-document trajectory IDs, `llm_call_count`, and
additional extension fields. See the
[RFC changelog](https://github.com/harbor-framework/harbor/blob/main/rfcs/0001-trajectory-format.md#version-history)
for earlier versions.

<Tip>
  Use the schema's `extra` fields for custom metadata. Harbor's Pydantic models
  reject undeclared fields.
</Tip>

## Resources

[ATIF RFC](https://github.com/harbor-framework/harbor/blob/main/rfcs/0001-trajectory-format.md), [Harbor trajectory models](https://github.com/harbor-framework/harbor/tree/main/src/harbor/models/trajectories), [Valid trajectory examples](https://github.com/harbor-framework/harbor/tree/main/tests/golden), [Trajectory validator](https://github.com/harbor-framework/harbor/blob/main/src/harbor/utils/trajectory_validator.py)
