第 11 章

第 11 章:ATIF——Agent 轨迹交换格式

第 11 章:ATIF——Agent 轨迹交换格式

每个 agent 的原生日志格式都不同:Claude Code 有自己的会话文件,Codex 用 config.toml 生态的记录方式,其他 agent 又各有一套。没有统一格式,任何查看器、数据集、训练管线都得为每个 agent 写专门解析器。ATIF(Agent Trajectory Interchange Format)用一份稳定的 JSON 规范解决了这个问题——本章逐字段讲透 ATIF v1.7,并演示如何构建与校验。

为什么需要统一的轨迹格式

Agent 的"解题过程"——消息、推理、工具调用、观察结果、指标——都散落在各自的原生日志里。没有共享格式时的连锁反应是:

  • 查看器要为每个 agent 写一种渲染器;
  • 数据集无法跨 agent 混合取样;
  • 训练管线要为每个新 agent 重写数据接入;
  • 对比分析(谁在哪些步骤上走得更好)更是无从谈起。

ATIF 提供一份跨 agent 稳定的表示,让轨迹可以统一地检查、对比、校验、加载与复用。完整规范见官方 ATIF RFC。

trajectory.json 在 Harbor 中的位置

在 Harbor 中,一份 ATIF 轨迹通常命名为 trajectory.json。支持该能力的 agent(预集成矩阵中 ATIF 列为 ✓ 者)会把它写入 agent 日志目录;在下载下来的 trial 结果里,路径是 agent/trajectory.json。

Harbor 用这个文件做两件事:

  • 渲染轨迹:结果查看器读取 agent/trajectory.json,在 Trajectory 页签中展示各步骤;
  • 加载轨迹:支持的 agent 可以用一份 ATIF 轨迹来"播种"新会话。

注意:产出 ATIF 与加载 ATIF 是两种独立能力。一个 agent 可以只写 trajectory.json 而不支持加载。自定义 agent 只有在确实会写出合法的 self.logs_dir / "trajectory.json" 时,才应声明 AgentCapabilities(atif=True)(见第 10 章)。

ATIF v1.7 顶层结构逐字段

Harbor 当前采用 ATIF-v1.7。一份轨迹文档包含以下顶层字段:

字段 用途
schema_version 格式版本标识,当前为 "ATIF-v1.7"
agent agent 名称、版本、模型名,以及可选的工具定义
steps 按序排列的 system / user / agent 交互步骤
session_id 可选;同一次运行产生的多份轨迹共享的标识
trajectory_id 可选的文档标识;在嵌入 subagent 时必填
final_metrics 可选;汇总的 token、成本与步骤指标
subagent_trajectories 可选;嵌入的 ATIF 子轨迹(v1.7 新增)
extra 根级自定义元数据

steps 内部的约定:step ID 从 1 开始且保持连续;agent 步骤可以包含 tool_calls(工具调用)、与之匹配的 observation(观察结果),以及每步指标。下面是一个最小但完整的例子——一条 user 指令,随后是一次带工具调用与观察结果的 agent 步骤:

{
  "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" }
        ]
      }
    }
  ]
}

阅读要点:tool_calls[].tool_call_id 与 observation.results[].source_call_id 一一对应,这是校验器检查"调用-结果配对"的依据;final_metrics、subagent_trajectories 等可选字段在需要时按 schema 添加即可。

用 Pydantic 模型构建轨迹

手写 JSON 容易错,Harbor 在 harbor.models.trajectories 中提供了 Pydantic 模型:

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"
)

用模型构建的好处是字段名、类型、必填项在构造期就被检查,to_json_dict() 保证序列化结果符合 schema。要特别留意:Harbor 的 Pydantic 模型拒绝未声明的字段——自定义元数据请放进 extra,不要随手在根级加字段。

校验轨迹

Harbor 自带校验器,CLI 一行即可:

uv run python -m harbor.utils.trajectory_validator path/to/trajectory.json

校验内容包括:schema 合法性、step ID 连续性、tool-call 引用配对、时间戳、以及被引用的本地图片是否存在。若轨迹里没有本地图片引用或环境里拿不到文件,用 --no-validate-images 跳过图片检查。

也可以在 Python 里调用同一个校验器:

from harbor.utils.trajectory_validator import TrajectoryValidator

validator = TrajectoryValidator()
if not validator.validate("trajectory.json"):
    for error in validator.get_errors():
        print(error)

无论轨迹来自预集成 agent、自定义 agent(第 10 章)还是外部工具,入库前过一遍校验器都是值得的习惯。

版本与扩展

Harbor 接受 ATIF-v1.0 至 ATIF-v1.7 的轨迹。v1.7 相对早期版本新增了:嵌入的 subagent 轨迹、每份文档的 trajectory_id、llm_call_count 等指标字段,以及若干扩展字段。早期版本的历史沿革见 RFC 的 changelog。

扩展实践上有两条铁律:

  • 自定义元数据放 extra:这是 schema 预留的合法扩展位;
  • 不要私加根级字段:Pydantic 模型会直接拒绝未声明字段,私加字段等于制造一份下游无法读取的轨迹。

本章小结

  • ATIF 用一份 JSON 规范统一记录 agent 的消息、推理、工具调用、观察与指标,是跨框架对比分析与训练数据生产的基础。
  • 在 Harbor 中轨迹通常命名为 trajectory.json,下载结果中的路径是 agent/trajectory.json,结果查看器与轨迹加载都依赖它。
  • 产出 ATIF 与加载 ATIF 是两种独立能力,自定义 agent 声明 AgentCapabilities(atif=True) 前先确认真的会写出合法文件。
  • ATIF-v1.7 顶层字段:agent、steps、session_id、trajectory_id(嵌入 subagent 时必填)、final_metrics、subagent_trajectories、extra。
  • steps 的 step ID 从 1 起且连续;tool_calls 与 observation.results 通过 ID 配对。
  • 构建轨迹用 harbor.models.trajectories 中的 Pydantic 模型,序列化走 to_json_dict()。
  • 校验用 trajectory_validator(CLI 或 Python),检查 schema、step 顺序、tool-call 引用、时间戳与本地图片。
  • 版本兼容范围为 ATIF-v1.0 到 v1.7;自定义元数据只能放 extra,模型拒绝未声明字段。

延伸阅读