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 ascoring_functionormetric_functions={"accuracy": ...}that implements embedding-based comparison or an LLM judge. Traigent does not ship one by default, andLocalExecutionAdapterwill fail loudly on dataset examples taggedevaluation_type: "semantic"if no such scorer is configured. - Custom Metrics: ROUGE, BLEU, or business-specific calculations viascoring_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
accuracyand minimize forcost/latency; custom names require an explicitObjectiveSchema - 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, usePromotionGate.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_spacekey inside the spec is deprecated in favor oftvars(typed variables). The decorator parameter itself remains valid. Define your search space usingtvarsfor 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 preserveinttype 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
PromotionGatefor 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_trialsexploration.budgets.max_spend_usd→cost_limitexploration.budgets.max_wallclock_s→timeoutexploration.strategy.type→algorithmexploration.parallelism.max_parallel_trials→parallel_config.trial_concurrency
Note: If both
exploration(TVL 0.9) andoptimization(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 specvalidate_constraints: Whether to compile and validate structural constraints (default:True)registry_resolver: Resolver for registry domains (required if spec usesregistry://domains)apply_evaluation_set: Wire TVLevaluation_set.urito 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 instancecustom_evaluator: Custom evaluation functionscoring_function: Custom scoring functionmetric_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" modeauto_override_frameworks: Auto-detect framework classesframework_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 directoryminimal_logging: Reduce log verbosityparallel_config: Concurrency configurationmax_total_examples: Global sample budgetsamples_include_pruned: Count pruned trials in budgetreps_per_trial: Repetitions per configuration. OSS SDK accepts only1; non-default values raisepydantic.ValidationErrorand require Traigent Enterprise.reps_aggregation: Repetition aggregation method. OSS SDK accepts only"mean"; non-default values raisepydantic.ValidationErrorand 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)
Related Documentation¶
- Complete Function Specification - Full API reference
- Evaluation Guide - Understanding accuracy metrics, evaluation methods, and troubleshooting
- Injection Modes Guide - Configuration injection patterns
- Choosing the Right Optimization Model - Default smart optimization, local search, no-egress runs, and migration guidance
- Thread Pool Examples - Context propagation with threads
- Telemetry Documentation - Data collection and no-egress controls
- Custom evaluator walkthrough in the repository examples - LLM-as-Judge implementation