Skip to content

Traigent Decorator Reference

This document provides a comprehensive reference for the @traigent.optimize() decorator and @optimize() (when imported directly).

Overview

The @traigent.optimize() decorator is the main entry point for Traigent SDK. It enables zero-code-change optimization for any function containing LLM invocations by automatically detecting and optimizing LLM parameters.

Import Signatures

# Primary import pattern (recommended)
import traigent

@traigent.optimize(...)
def my_function(...):
    ...

# Alternative: direct import
from traigent.api.decorators import optimize

@optimize(...)
def my_function(...):
    ...

Both forms are functionally identical. The traigent.optimize form is recommended for clarity.

Complete Decorator Signature

def optimize(
    *,
    # Core optimization parameters
    objectives: list[str] | ObjectiveSchema | None = None,
    configuration_space: dict[str, Any] | ConfigSpace | None = None,
    default_config: dict[str, Any] | None = None,
    constraints: list[Constraint | BoolExpr | Callable[..., Any]] | None = None,
    safety_constraints: list[SafetyConstraint | CompoundSafetyConstraint] | None = None,

    # TVL integration
    tvl_spec: str | Path | None = None,
    tvl_environment: str | None = None,
    tvl: TVLOptions | dict[str, Any] | None = None,

    # Grouped option bundles (preferred)
    evaluation: EvaluationOptions | dict[str, Any] | None = None,
    injection: InjectionOptions | dict[str, Any] | None = None,
    effectuation: bool = False,
    execution: ExecutionOptions | dict[str, Any] | None = None,
    strategy: str | None = None,
    strategy_params: Mapping[str, Any] | None = None,

    # Multi-agent configuration
    agents: dict[str, AgentDefinition] | None = None,
    agent_prefixes: list[str] | None = None,
    agent_measures: dict[str, list[str]] | None = None,
    global_measures: list[str] | None = None,

    # Config persistence
    auto_load_best: bool = False,
    load_from: str | None = None,
    config_id: str | None = None,
    best_config_source: str = "off",
    best_config_strict: bool = False,
    best_config_cache_dir: str | None = None,
    best_config_cache_ttl_seconds: int = 24 * 60 * 60,
    best_config_stale_ok_ttl_seconds: int | None = None,
    enable_auto_load_dev_logs: bool | None = None,

    # Guided generation
    prompt_rewrite: dict[str, Any] | None = None,
    grow_dataset: dict[str, Any] | None = None,

    # Legacy compatibility
    legacy: LegacyOptimizeArgs | dict[str, Any] | None = None,

    # Runtime overrides
    **runtime_overrides: Any,
) -> Callable[[Callable[..., Any]], Any]

Parameter Groups

Core Optimization Parameters

objectives

  • Type: list[str] | ObjectiveSchema | None
  • Default: ["accuracy"]
  • Description: Target metrics to optimize

Understanding Accuracy: The meaning of "accuracy" depends on your use case: - Classification (built-in default): Exact / case-insensitive string match between the agent's output and expected_output. No embeddings, no LLM judge, no API key required. - Semantic Similarity (bring your own scorer): Pass a scoring_function or metric_functions={"accuracy": ...} that implements embedding-based comparison or an LLM judge. Traigent does not ship one by default, and LocalExecutionAdapter will fail loudly on dataset examples tagged evaluation_type: "semantic" if no such scorer is configured. - Custom Metrics: ROUGE, BLEU, or business-specific calculations via scoring_function / metric_functions / custom_evaluator.

See the Evaluation Guide for detailed explanations and examples.

String List Form (Simple):

@traigent.optimize(
    objectives=["accuracy", "cost", "latency"],
    ...
)

For exact SDK-owned objective names, Traigent supplies:

  • Orientations: Fixed defaults, such as maximize for accuracy and minimize for cost/latency; custom names require an explicit ObjectiveSchema
  • Weights: Equal weights for all objectives

ObjectiveSchema Form (Advanced):

from traigent.core.objectives import ObjectiveSchema, ObjectiveDefinition

@traigent.optimize(
    objectives=ObjectiveSchema.from_objectives(
        [
            ObjectiveDefinition(name="accuracy", weight=2.0, orientation="maximize"),
            ObjectiveDefinition(name="cost", weight=1.0, orientation="minimize"),
            ObjectiveDefinition(name="latency", weight=0.5, orientation="minimize"),
        ]
    ),
    ...
)

Explicit control over:

  • Weights: Relative importance of each objective
  • Orientations: "maximize", "minimize", or "band" (TVL 0.9)
  • Metadata: Additional objective configuration

Banded Objectives (TVL 0.9):

For objectives where you want to stay within a target range rather than maximize/minimize:

from traigent.core.objectives import ObjectiveSchema, ObjectiveDefinition
from traigent.tvl.models import BandTarget

@traigent.optimize(
    objectives=ObjectiveSchema.from_objectives(
        [
            ObjectiveDefinition(name="accuracy", weight=2.0, orientation="maximize"),
            # Banded objective: target response length between 100-200 tokens
            ObjectiveDefinition(
                name="response_length",
                orientation="band",
                band=BandTarget(low=100, high=200),
                band_test="TOST",    # Two One-Sided Tests for equivalence
                band_alpha=0.05,     # Significance level
                weight=1.0,
            ),
            # Alternative: center ± tolerance
            ObjectiveDefinition(
                name="cost",
                orientation="band",
                band=BandTarget(center=0.01, tol=0.005),  # Band is [0.005, 0.015]
                band_test="TOST",
                band_alpha=0.05,
                weight=1.0,
            ),
        ]
    ),
    ...
)

Banded objectives use TOST (Two One-Sided Tests) to statistically verify that the metric falls within the target band.

Current Status: Banded objectives are fully parsed and available in ObjectiveDefinition. During optimization, they are currently treated as minimize objectives. For full TOST-based statistical testing, use PromotionGate.evaluate() with collected sample data after optimization.

configuration_space

  • Type: dict[str, Any] | ConfigSpace | None
  • Default: None
  • Description: Search space describing tunable parameters

⚠️ Deprecation Notice (TVL 0.9): When using TVL spec files, the configuration_space key inside the spec is deprecated in favor of tvars (typed variables). The decorator parameter itself remains valid. Define your search space using tvars for full TVL 0.9 support including type safety, units, and registry domains.

Discrete Choices (List):

configuration_space={
    "model": ["gpt-4o-mini", "gpt-4.1", "claude-3-haiku"],
    "temperature": [0.1, 0.3, 0.5, 0.7, 0.9],
}

Continuous Ranges (Tuple):

configuration_space={
    "temperature": (0.0, 1.0),  # min, max
    "top_p": (0.0, 1.0),
}

Mixed Configuration:

configuration_space={
    "model": ["gpt-4o-mini", "gpt-4.1"],
    "temperature": (0.0, 1.0),
    "max_tokens": [100, 500, 1000, 2000],
}

SE-friendly tuned variables (first-class):

from traigent import Choices, Range

@traigent.optimize(
    configuration_space={
        "model": Choices(["gpt-4.1", "gpt-4.1-mini"]),
        "temperature": Range(0.0, 2.0),
    },
)
def my_agent(prompt: str) -> str:
    return run(prompt)

You can also pass a ConfigSpace object when you want to bundle tvars and structured constraints together.

default_config

  • Type: dict[str, Any] | None
  • Default: None
  • Description: Baseline configuration for first trial
@traigent.optimize(
    configuration_space={"model": ["gpt-4o-mini", "gpt-4.1"], "temperature": (0.0, 1.0)},
    default_config={"model": "gpt-4o-mini", "temperature": 0.7},
    ...
)

constraints

  • Type: list[Constraint | Callable[..., Any]] | None
  • Default: None
  • Description: Validation functions that return True/False

Constraint objects and callables can be mixed; Traigent normalizes them to a common callable interface internally.

Configuration-only Constraints:

def max_tokens_constraint(config):
    if config["model"] == "gpt-4.1" and config["max_tokens"] > 2000:
        return False
    return True

@traigent.optimize(
    constraints=[max_tokens_constraint],
    ...
)

Metrics-based Constraints:

def cost_constraint(config, metrics=None):
    if not metrics:
        return True  # config-only check, before any metrics exist
    cost = metrics.get("cost")
    # A trial with no measured cost has an unknown cost, not a free one.
    return cost is not None and cost <= 0.10

@traigent.optimize(
    constraints=[cost_constraint],
    ...
)

Structured Constraints (SE-friendly):

from traigent import Choices, Range, implies

model = Choices(["gpt-4.1", "gpt-4.1-mini"], name="model")
temp = Range(0.0, 2.0, name="temperature")

@traigent.optimize(
    configuration_space={"model": model, "temperature": temp},
    constraints=[implies(model.equals("gpt-4.1"), temp.lte(0.7))],
)
def my_agent(prompt: str) -> str:
    return run(prompt)

TVL Integration

Traigent supports the TVL (Tuned Variables Language) 0.9 specification for declarative optimization configuration. TVL specs provide:

  • Typed Variables (tvars): Parameters with explicit types (bool, int, float, enum[str], tuple[...]). Integer ranges preserve int type for proper sampling.
  • Structural Constraints: Boolean formulas over tvars (compiled to DNF)
  • Derived Constraints: Linear arithmetic over environment symbols
  • Banded Objectives: TOST equivalence testing with target bands (parsed; use PromotionGate for evaluation)
  • Promotion Policy: Epsilon-Pareto dominance with configurable error rates (use PromotionGate.from_spec_artifact() for statistical decisions)
  • Exploration Settings: Strategy (supports {type: ...} dict format), convergence criteria, parallelism, and budgets

When a TVL spec is loaded, the TVLSpecArtifact provides access to all parsed sections including tvars, constraints (compiled structural constraints as callables), derived_constraints, promotion_policy, convergence, exploration_budgets, and exploration_parallelism.

Runtime Wiring (TVL 0.9 exploration section):

  • exploration.budgets.max_trials → max_trials
  • exploration.budgets.max_spend_usd → cost_limit
  • exploration.budgets.max_wallclock_s → timeout
  • exploration.strategy.type → algorithm
  • exploration.parallelism.max_parallel_trials → parallel_config.trial_concurrency

Note: If both exploration (TVL 0.9) and optimization (legacy) sections are present in a spec, an error is raised. Use only one format.

tvl_spec

  • Type: str | Path | None
  • Default: None
  • Description: Path to TVL specification file
@traigent.optimize(
    tvl_spec="specs/my_optimization.tvl",
    tvl_environment="production",
    ...
)

tvl_environment

  • Type: str | None
  • Default: None
  • Description: Named environment overlay from the TVL spec

tvl

  • Type: TVLOptions | dict[str, Any] | None
  • Default: None
  • Description: Structured TVL options controlling how the spec is applied (configuration space, objectives, constraints, budgets) and how to resolve registry domains
from traigent.tvl.options import TVLOptions

@traigent.optimize(
    tvl=TVLOptions(
        spec_path="specs/my_optimization.tvl",
        environment="production",
        validate_constraints=True,        # Compile and validate structural constraints
        registry_resolver=my_resolver,    # Required if spec uses registry domains
        apply_evaluation_set=True,        # Wire evaluation_set.uri to evaluation settings
        apply_configuration_space=True,
        apply_objectives=True,
        apply_constraints=True,
        apply_budget=True,
    ),
    ...
)

TVLOptions Fields:

  • spec_path: Path to the TVL specification file (required)
  • environment: Named environment overlay from the spec
  • validate_constraints: Whether to compile and validate structural constraints (default: True)
  • registry_resolver: Resolver for registry domains (required if spec uses registry:// domains)
  • apply_evaluation_set: Wire TVL evaluation_set.uri to evaluation settings (default: True)
  • apply_configuration_space: Apply TVL configuration space (default: True)
  • apply_objectives: Apply TVL objectives (default: True)
  • apply_constraints: Apply TVL constraints (default: True)
  • apply_budget: Apply TVL budget settings (default: True)

Grouped Option Bundles

evaluation

  • Type: EvaluationOptions | dict[str, Any] | None
  • Default: None
from traigent.api.decorators import EvaluationOptions

# As an instance
@traigent.optimize(
    evaluation=EvaluationOptions(
        eval_dataset="qa_test.jsonl",
        custom_evaluator=my_evaluator,
        scoring_function=my_scorer,
    ),
    ...
)

# As a dict
@traigent.optimize(
    evaluation={
        "eval_dataset": "qa_test.jsonl",
        "custom_evaluator": my_evaluator,
    },
    ...
)

EvaluationOptions Fields:

  • eval_dataset: Dataset path, list of paths, inline example list, or Dataset instance
  • custom_evaluator: Custom evaluation function
  • scoring_function: Custom scoring function
  • metric_functions: Dict of metric name to evaluator functions
Evaluation Methods

Traigent supports multiple evaluation approaches through its parameters:

Method Parameter Use Case
Exact Match Default (no param needed) Classification, yes/no, categories (binary pass/fail)
Graded Scoring scoring_function Custom graded evaluation (0.0-1.0) - partial matches, fuzzy matching
LLM-as-Judge custom_evaluator Complex quality assessment - nuanced evaluation, code review
Multi-Metric / RAGAS metric_functions Multiple dimensions, semantic similarity (via RAGAS)
LLM-as-Judge Example

For tasks requiring nuanced evaluation (code quality, writing style, factual accuracy), implement an LLM-based evaluator:

def llm_evaluator(output: str, expected: str, **kwargs) -> float:
    """Use an LLM to evaluate output quality."""
    # Your LLM evaluation logic here
    # See 06_custom_evaluator.py for complete implementation
    return 0.8  # Replace: return your calculated score (0.0 to 1.0)

@traigent.optimize(
    custom_evaluator=llm_evaluator,
    # ... other parameters
)
def my_function(prompt: str) -> str:
    ...

Complete example: see the repository's custom evaluator walkthrough for a full LLM-as-Judge implementation.

injection

  • Type: InjectionOptions | dict[str, Any] | None
  • Default: None
from traigent.api.decorators import InjectionOptions

@traigent.optimize(
    injection=InjectionOptions(
        injection_mode="context",  # or "parameter", "seamless"
        config_param="config",  # required when injection_mode="parameter"
        auto_override_frameworks=True,
        framework_targets=["OpenAI", "Anthropic"],
    ),
    ...
)

InjectionOptions Fields:

  • injection_mode: How to inject config ("context", "parameter", "seamless")
  • config_param: Parameter name when using "parameter" mode
  • auto_override_frameworks: Auto-detect framework classes
  • framework_targets: Explicit list of framework classes

execution

  • Type: ExecutionOptions | dict[str, Any] | None
  • Default: None
from traigent.api.decorators import ExecutionOptions
from traigent.config.parallel import ParallelConfig

@traigent.optimize(
    execution=ExecutionOptions(
        algorithm="grid",
        offline=True,
        local_storage_path="./my_results",
        minimal_logging=True,
        parallel_config=ParallelConfig(thread_workers=4, trial_concurrency=2),
        max_total_examples=1000,
        samples_include_pruned=True,
        reps_per_trial=1,
        reps_aggregation="mean",
    ),
    ...
)

ExecutionOptions Fields:

  • algorithm: optimizer selector. "auto" is the default smart optimizer; "grid" and "random" run local search and still sync results when authenticated; smart algorithms require cloud and hard-error when unavailable or offline.
  • offline: force local-only operation with zero Traigent backend egress and no portal sync.
  • local_storage_path: Custom storage directory
  • minimal_logging: Reduce log verbosity
  • parallel_config: Concurrency configuration
  • max_total_examples: Global sample budget
  • samples_include_pruned: Count pruned trials in budget
  • reps_per_trial: Repetitions per configuration. OSS SDK accepts only 1; non-default values raise pydantic.ValidationError and require Traigent Enterprise.
  • reps_aggregation: Repetition aggregation method. OSS SDK accepts only "mean"; non-default values raise pydantic.ValidationError and require Traigent Enterprise.
  • evaluator: external evaluator bundle for API-contract integrations. This does not change optimizer routing; it only changes how each trial is evaluated.

Removed: mock and mock_mode_config

The inert mock (MockModeOptions) and mock_mode_config parameters were removed (Traigent#1370 Item 6). Passing either raises TypeError. Enable mock mode in local tutorial or test code by calling traigent.testing.enable_mock_mode_for_quickstart(); the legacy TRAIGENT_MOCK_LLM=true env var remains for shell fixtures only.

Runtime Overrides

The **runtime_overrides parameter accepts additional settings:

Optimization Algorithm:

@traigent.optimize(
    algorithm="grid",  # "grid" or "random" (local); smart algorithms run in the Traigent cloud
    ...
)

Legacy execution_mode= inputs are deprecated compatibility shims. Use algorithm= and offline= for new code.

Run controls such as max_trials and timeout are passed to .optimize():

result = await my_agent.optimize(max_trials=10, timeout=3600)

Cost Controls:

result = await my_agent.optimize(
    cost_limit=5.00,  # USD
    cost_approved=False,  # Real bool only; strings do not approve
)

Env approval requires exact TRAIGENT_COST_APPROVED=true; 1/yes do not approve.

Metric-Limit Controls:

@traigent.optimize(
    metric_limit=1000,  # Soft cumulative metric stop
    metric_name="samples",
    metric_include_pruned=True,
    ...
)

budget_limit / budget_metric / budget_include_pruned were removed in 0.13.0 and now raise TypeError. Use cost_limit for hard USD spend control, or metric_limit / metric_name for other cumulative metrics.

Stop Conditions:

@traigent.optimize(
    plateau_window=10,  # trials
    plateau_epsilon=0.01,  # improvement threshold
    ...
)

Complete Examples

Basic Single-Objective Optimization

import traigent

@traigent.optimize(
    objectives=["accuracy"],
    configuration_space={
        "model": ["gpt-4o-mini", "gpt-4.1"],
        "temperature": [0.1, 0.5, 0.9],
    },
    evaluation={"eval_dataset": "qa_test.jsonl"},
)
def answer_question(question: str) -> str:
    llm = OpenAI()  # Parameters auto-optimized
    return llm.complete(question)

Multi-Objective with Constraints

@traigent.optimize(
    objectives=["accuracy", "cost", "latency"],
    configuration_space={
        "model": ["gpt-4o-mini", "gpt-4.1", "claude-3-haiku"],
        "temperature": (0.0, 1.0),
        "max_tokens": [100, 500, 1000],
    },
    constraints=[
        lambda cfg: cfg["max_tokens"] <= 500 if cfg["model"] == "gpt-4.1" else True,
        lambda cfg, metrics: (
            not metrics
            or (metrics.get("cost") is not None and metrics["cost"] <= 0.10)
        ),
    ],
    evaluation={"eval_dataset": "support_tickets.jsonl"},
    parallel_config={"thread_workers": 4},
)
def process_ticket(ticket: str) -> str:
    return support_chain.run(ticket)

No-Egress Local Storage

from traigent.core.objectives import ObjectiveDefinition, ObjectiveSchema

safety_objectives = ObjectiveSchema.from_objectives([
    ObjectiveDefinition("accuracy", orientation="maximize", weight=1.0),
    ObjectiveDefinition("safety", orientation="maximize", weight=1.0),
])

@traigent.optimize(
    objectives=safety_objectives,
    configuration_space={
        "model": ["gpt-4.1", "claude-3-sonnet"],
        "temperature": [0.1, 0.3, 0.5],
    },
    evaluation={"eval_dataset": "medical_qa.jsonl"},
    algorithm="grid",
    offline=True,
    local_storage_path="./medical_optimizations",
    minimal_logging=True,
)
def medical_assistant(query: str) -> str:
    return process_medical_query(query)

Using ObjectiveSchema for Weighted Objectives

from traigent.core.objectives import ObjectiveSchema, ObjectiveDefinition

@traigent.optimize(
    objectives=ObjectiveSchema.from_objectives(
        [
            ObjectiveDefinition(name="accuracy", weight=3.0, orientation="maximize"),
            ObjectiveDefinition(name="cost", weight=1.0, orientation="minimize"),
            ObjectiveDefinition(name="latency", weight=0.5, orientation="minimize"),
        ]
    ),
    configuration_space={
        "model": ["gpt-4o-mini", "gpt-4.1"],
        "temperature": (0.0, 1.0),
    },
    evaluation={"eval_dataset": "dataset.jsonl"},
)
def my_agent(query: str) -> str:
    return process(query)