Skip to content

Asset Tracking

Benchmarks need to know which prompt, tool, schema, or configuration produced each result. Autobench tracking assigns content-derived versions, captures structured metadata, persists history, and binds exact asset versions to RunRecords.

Prompts And Text Assets

Track inline text:

from autobench import track

SYSTEM_PROMPT = track.prompt(
    name="support_system_prompt",
    text="Route the request to billing, account, or technical support.",
)

Or load it from a file:

SYSTEM_PROMPT = track.prompt(
    name="support_system_prompt",
    source="prompts/support.md",
)

TrackedPrompt.raw returns the text, and str(SYSTEM_PROMPT) provides the same value for APIs that expect a string. File-backed prompts retain their source path and source hash.

Tools

@track.tool preserves the callable's exact signature and return type while collecting tool metadata:

from typing import Literal

from autobench import track


@track.tool
def route_ticket(
    queue: Literal["billing", "account", "technical"],
    priority: int = 1,
) -> bool:
    """Route a ticket to a support queue."""
    return priority > 0

The resulting ToolAsset records:

  • qualified name and docstring
  • parameter names, kinds, annotations, defaults, and requirements
  • return annotation
  • source path and source hash
  • structured parameter schema
  • semantic type and version lineage

Annotations are normalized by structure rather than alias spelling. If the contents of a Literal, union, generic, model, or referenced type change, the asset hash changes even when the alias name stays the same.

Pydantic Models, Dataclasses, And Classes

from dataclasses import dataclass
from typing import Literal

from autobench import track
from pydantic import BaseModel, Field


@track.type
class Car(BaseModel):
    make: Literal["audi", "bmw", "mercedes"]
    model: str = Field(examples=["a3", "320i"])
    year: int = Field(gt=0)


@track.dataclass(frozen=True, slots=True)
class CarRequest:
    make: Literal["audi", "bmw", "mercedes"]
    model: str
    year: int

Pydantic models are hashed from normalized JSON Schema plus source identity. Standard dataclasses use dataclass field definitions and resolved annotations. Other typed classes use resolved class annotations, inspectable signatures, and source hashes.

TypeAsset and FieldAsset preserve field names, resolved annotations, descriptions, examples, aliases, defaults, required state, and relevant constraints.

Composing Another Class Decorator

When @track.type above a class-transforming decorator gives poor type-checker inference, use track.decorate_type:

from dataclasses import dataclass

from autobench import track


@track.decorate_type(dataclass, frozen=True, slots=True)
class Request:
    value: str

The decorator and its normalized arguments are stored as asset metadata. track.dataclass(...) is the typed convenience form for the standard dataclass decorator.

Arbitrary Assets

Use track.asset for configurations, policies, routing tables, or other application components:

@track.asset(kind="routing_policy", name="enterprise_routing")
def route_policy(ticket):
    return "priority" if ticket["enterprise"] else "standard"

The decorator returns the original object unchanged. Callables use source and signature metadata; manual version, hash, source_path, parent_version, and metadata values are available when automatic identity is not enough.

Versions, Diffs, And Persistence

TrackingRegistry keeps current assets and version history in memory during execution. Persist it with:

from pathlib import Path

from autobench import track

track.write_assets(Path(".autobench/assets"))

The YAML history contains an index plus one file per asset. Every new version links to its parent when available and stores a human-readable diff from the previous serialized state. Source changes, schema changes, decorator options, and metadata changes therefore remain reviewable.

Binding Assets To Runs

def run_case(ctx, case):
    ctx.attach_tracked_asset(SYSTEM_PROMPT)
    ctx.attach_tracked_asset(route_ticket)
    ctx.attach_tracked_asset(Car)
    return execute(case.input)

The exact AssetVersion values are copied into the RunRecord. Reports and optimization feedback can then relate metric changes to prompt, tool, or output-schema versions without guessing from source control state.