Traigent Boost Agent
Your Role
When a user asks you to optimize a function or agent with Traigent, always start with a dry run. Real optimization costs real tokens and money. Never run real optimization until the user explicitly asks.
Present a cost estimate and get the user's explicit approval before any paid run.
Workflow:
- Set up the decorated function (for a single function, see the Fast Path below; for a whole codebase, Steps 1-7 of the 12-Step Lifecycle Playbook)
- Validate dataset, config space, and providers
- Dry-run in mock mode — verify the full pipeline end-to-end at zero cost
- Report what the dry run found, estimate real costs
- Wait for the user to say "run it for real"
When to Use
Requires traigent>=0.24.0 (the knobs API is present on all current SDK releases).
Use this skill when the user asks you to:
- "add Traigent to this agent"
- "optimize this agent"
- "boost accuracy/cost of an existing agent codebase"
- "onboard this agent to Traigent end-to-end"
- "full agent-build lifecycle"
- "wire an evaluator and optimize"
- instrument an existing LLM, RAG, tool-using, coding, or multi-stage agent with Traigent
- choose tuned variables and composite knobs for a real client codebase
For detailed grep patterns and evidence-mining heuristics, read references/codebase-analysis.md. For a minimal before/after implementation recipe, read references/instrument-recipe.md. For insight and iteration code, read references/insights-and-iteration.md.
Optimization Economics — Read This Before Sizing a Run
Do not default to recommending zero spend. The canonical Traigent posture on spending,
the five characterization questions with their exact options, the tailoring rules (including
the three-option paging rule), the explanation duty, and the local survey draft contract all
live in one file that ships inside this skill:
references/economics-characterization.v0.md. Read it from this skill's own directory
before you propose, size, or decline a run — it is deliberately not restated here. It is
generated from docs/shared/economics-characterization.v0.md in the traigent-skills repo,
which is where any edit goes; the copy shipped here is byte-identical.
Characterize, never compute a budget locally. Collect the characterization and relay it;
the Traigent service authors the budget, exactly as it authors the run-plan and the next-step
decision — budget authorship belongs to the service. Do not compute, adjust, or recommend a
budget locally: no budget arithmetic in markdown, no floor/cap table, no "roughly $X/day" of
your own. The reference describes what the service computes; it is not a local calculator, and
when the service returns no economics result, say so plainly and continue with no budget
number at all rather than inventing one.
This skill's part: characterize the value the client agent creates and relay it, so the
service can size a bounded first experiment to it.
Mandatory whenever you relay any of it: show the options, recommend exactly one, and
explain why in the user's own numbers — their agent, their volumes, their error costs. The
explanation is a product requirement, not decoration.
Safety is unchanged and unweakened: mock/dry-run first, explicit user approval before any
paid run, an explicit spend cap, and the recorded stop rule. The service sets
how much to invest; it never affects whether approval is required — it always is.
Fast Path: Optimize a Single Function
For a single decorated function (rather than a whole codebase), run this condensed dry-run-first sequence; the 12-Step Lifecycle Playbook below is the full-codebase version.
Step 1: Set Up the Decorator
The user's function needs four things: dataset, objectives, config space, and the function itself.
import traigent
import litellm # pip install "traigent[integrations]>=0.19" — the canonical runnable LLM call
from traigent import Choices, Range
@traigent.optimize(
eval_dataset="eval_data.jsonl", # 1. Dataset
objectives=["accuracy"], # 2. What to optimize
model=Choices(["gpt-4o-mini", "gpt-4o"]), # 3. Config space (inline)
temperature=Range(0.0, 1.0),
)
def my_function(query: str) -> str: # 4. The function
config = traigent.get_config()
resp = litellm.completion(
model=config["model"],
temperature=config["temperature"],
messages=[{"role": "user", "content": query}],
)
return resp.choices[0].message.content
One runnable body, reused everywhere. The litellm.completion(...) → resp.choices[0].message.content body above is the canonical, copy-paste-runnable function used across these skills. Reuse it verbatim wherever an example shows my_function/agent body — it runs keyless under mock mode (LiteLLM is intercepted) and unchanged for a real run. Optimize accuracy and cost? cost and latency are built-in objectives auto-derived from token accounting, so use objectives=["accuracy", "cost"] — no extra evaluator needed. See traigent-setup-quickstart for the full copy-paste example, traigent-optimize-config-space for Range/Choices/IntRange/LogRange/constraints, and traigent-setup-decorator for EvaluationOptions/InjectionOptions/ExecutionOptions.
Setup Mistakes to Catch
| Mistake |
SDK catches? |
Fix |
Config values as bare strings (model="gpt-4") |
Yes — TypeError |
Must be list or Range/Choices (model=Choices(["gpt-4"])) |
get_config() called outside the function |
Yes — OptimizationStateError |
Must be inside the decorated function body |
| Dataset file doesn't exist |
Yes — ValidationError |
Create it or fix the path |
| Empty objectives list |
No — silently defaults |
Verify objectives has at least one entry before running |
| Function doesn't return a value |
No — None scored silently |
Assert your function returns the prediction; None produces meaningless scores |
Step 2: Validate Before Running
Use the SDK's built-in validation tools before any optimization:
traigent validate eval_data.jsonl --objectives accuracy -v # dataset: valid JSON, `input` field (+ `output` for accuracy-like metrics); 5+ examples, 10-20+ recommended
traigent info # SDK version, Python version, enabled features
traigent algorithms # Available algorithms with descriptions and best-use cases
traigent check my_script.py --dry-run # discovers @traigent.optimize functions; validates decorator wiring only, not dataset contents
Step 3: Run Mock Optimization
Enable mock mode in code, then run the full optimization pipeline end to end (decorator wiring, config sampling, dataset loading, trial execution, scoring) with LLM calls intercepted. Mock mode is hard-blocked when ENVIRONMENT=production. For mock-mode setup mechanics and scope (what is and isn't intercepted, mock vs offline), see traigent-setup-quickstart.
Mock dry-runs still consume the plan's optimization_samples quota, and mock intercepts LiteLLM/LangChain calls only — raw openai/anthropic clients are NOT intercepted and still bill. See traigent-debugging for the quota entry and hermetic-startup env vars (TRAIGENT_MOCK_LLM, TRAIGENT_OFFLINE_MODE, LITELLM_LOCAL_MODEL_COST_MAP).
import os
os.environ["TRAIGENT_OFFLINE_MODE"] = "true" # Skip Traigent backend calls
import traigent
from traigent.testing import enable_mock_mode_for_quickstart
enable_mock_mode_for_quickstart() # Mock LLM responses (dev-only)
# Same @traigent.optimize-decorated my_function as Step 1 —
# its litellm.completion(...) call is intercepted automatically in mock mode.
results = my_function.optimize_sync(max_trials=4, algorithm="random")
print(f"Trials ran: {len(results.trials)}")
print(f"Failed trials: {len(results.failed_trials)}")
print(f"Stop reason: {results.stop_reason}")
print(f"Best config: {results.best_config}")
print(f"Best score: {results.best_score}")
Interpret Mock Results
| Check |
Pass |
Fail |
| Trials ran |
len(results.trials) > 0 |
No trials = config space or dataset error |
| No failures |
len(results.failed_trials) == 0 |
Failures = function or evaluator bug |
| Stop reason |
"max_trials_reached" or "optimizer" |
"error" = something broke |
| Config keys |
Expected keys in best_config |
Missing keys = config space mismatch |
Score interpretation depends on evaluator type: a config-aware scorer (reads traigent.get_config()) produces meaningful varied scores even in mock mode; an output-based/deterministic scorer (exact-match, JSON-schema, execution accuracy) sees the mock LLM's constant response and scores uniformly 0.0.
WARNING — uniform 0.0 under mock is plumbing-OK, not a failure:
If your scorer is output-based (exact-match, SQL execution accuracy, JSON-schema, etc.)
and all mock scores are 0.0, that is the correct expected result: the mock returns a
constant string that no deterministic scorer can score positively. Focus on whether trials
ran without errors (failed_trials == 0), not on the 0.0 score values.
For a varied score spread without real LLM calls, wire a config-aware mock-only demo
scorer (delete it for the real run) — see traigent-setup-quickstart (mock_demo_accuracy)
for the recipe.
If mock fails, set export TRAIGENT_DEBUG=1 for debug logging, fix decorator args for ConfigurationError (see mistakes table above), and see traigent-debugging (references/mock-mode.md) for the full mock failure diagnosis (evaluation errors, get_config() outside optimization context, missing integrations extra, all-trials-failed).
Do not proceed to real mode until mock passes cleanly.
Step 3.5: Evaluator Sanity Gate
Before the first paid run, verify the metric actually separates a correct output from a wrong one. This costs nothing — no LLM calls — but catches the single most expensive silent failure mode: an evaluation metric that swallows exceptions or silently returns 0.0 for every config (making the agent look broken when the metric is broken).
# `my_metric` is the scoring_function / metric you pass to @traigent.optimize.
# Use literal good/bad examples for YOUR task — no LLM call needed (that's the point).
expected_output = "the expected answer for one example" # your gold label
known_good = "a known-correct output for that example" # e.g. the gold answer itself
known_bad = "obviously wrong or empty output"
assert my_metric(known_good, expected_output) >= 0.9, (
"metric does not reward a correct output — fix before running real optimization"
)
assert my_metric(known_bad, expected_output) <= 0.1, (
"metric does not penalize a wrong output — fix before running real optimization"
)
For a custom_evaluator / BaseEvaluator, call .evaluate([good_example]) and .evaluate([bad_example]) directly and assert the returned metrics separate. Use one known-good + one known-bad example only — this is a smoke gate, not a full audit.
If both assertions pass: the metric wires correctly — proceed to Step 4.
If either fails: fix the metric before spending tokens. Common causes: wrong field name in the result, inverted logic (> vs <), exception swallowed to 0.0. See traigent-eval-build for diagnostic steps. For LLM-judge metrics, see traigent-eval-audit for the full reliability protocol.
Step 3.6: Tiny Real Cost and KPI Probe
After mock mode and the evaluator sanity gate pass, run one tiny real optimization before any full run: 1-2 dataset examples, minimal trials, and the cheapest candidate model (pennies, not dollars). Check both surfaces: results.total_cost must be neither None nor 0.0 with real calls (both mean cost is not wired), and each trial's metrics must contain the declared objectives with non-degenerate values (not all 0.0/all 1.0). If either surface fails, wire it before scaling up — see traigent-optimize-run → Cost Wiring Probe for the fix ladder (custom model pricing env vars, per-trial cost metrics, strict accounting).
Step 4: Report and Estimate Costs
After a successful mock run, tell the user:
- Pipeline validated — trials, config space, dataset all working
- Config space size — how many unique configurations
- Estimated LLM calls —
max_trials x dataset_size (upper bound)
- Cost limit — default $2.00 USD per run (
TRAIGENT_RUN_COST_LIMIT)
- Ask for go/no-go
Example:
Mock run passed: 4/4 trials, 0 failures, pipeline is valid.
Config space: 2 models x continuous temperature. With max_trials=10 and 15 dataset examples, that's up to 150 LLM calls.
Default cost limit is $2.00 USD. Want me to run it for real? This will use your API keys and cost real tokens.
Step 5: Run Real Optimization (Only When Asked)
When the user explicitly says to proceed:
Verify API keys first — models in the config space need corresponding provider keys, and Traigent auto-validates them before starting, raising ProviderValidationError with details if validation fails:
export OPENAI_API_KEY="sk-..." # For gpt-* models
export ANTHROPIC_API_KEY="sk-ant-..." # For claude-* models
export GEMINI_API_KEY="..." # For gemini-* models
Then skip the mock-mode activation and set cost controls:
import os
# Just don't call enable_mock_mode_for_quickstart() this run.
# Mock mode is process-local — start a fresh interpreter for the
# real run if the previous one had it on.
os.environ.pop("TRAIGENT_OFFLINE_MODE", None)
# Cost limit — default $2.00 USD per run
os.environ["TRAIGENT_RUN_COST_LIMIT"] = "2.00"
# Real runs are blocked by the cost-approval gate until this is set.
# Set it ONLY after the user has seen the cost estimate and explicitly
# approved the spend — never set it preemptively on the user's behalf.
os.environ["TRAIGENT_COST_APPROVED"] = "true"
Algorithm selector. For connected real runs, omit algorithm or use algorithm="auto".
auto is the default connected path to real cloud Optuna TPE. Use
algorithm="grid" / "random" only for explicit local/offline search.
Named smart selectors execute on connected runs since 0.20.1
(see version-matrix: smart-selector-exec). On an authenticated connected run, supported names
(bayesian/tpe/optuna/optuna_tpe/optuna_random) bind to the typed backend Optuna
strategy at session creation; unsupported smart names such as nsga2/cmaes fail fast with
a capability message (Traigent/Traigent#1752, #1758; on 0.20.0 no named smart selector
executed end-to-end). They never run locally: with offline=True the decorator raises
ConfigurationError, and the local optimizer registry raises OptimizationError.
from traigent.utils.exceptions import CostLimitExceeded, OptimizationError
try:
# Connected real run: omit algorithm or use "auto". Smart selector names
# like "bayesian" are connected-only (SDK 0.20.1+) and never run locally.
results = my_function.optimize_sync(max_trials=10, algorithm="auto")
except CostLimitExceeded as e:
print(f"Budget hit: ${e.accumulated:.2f} / ${e.limit:.2f}")
print("Increase TRAIGENT_RUN_COST_LIMIT to allow more spending.")
raise
except OptimizationError as e:
print(f"Optimization could not run: {e}")
raise
print(f"Best config: {results.best_config}")
print(f"Best score: {results.best_score}")
if results.total_cost:
print(f"Total cost: ${results.total_cost:.2f}")
else:
# None or 0.0 after real calls = cost is NOT wired (see Step 3.6) —
# say so loudly instead of hiding the row.
print("Total cost: NOT TRACKED — wire cost before the next run (Step 3.6)")
print(f"Duration: {results.duration:.1f}s")
print(f"Stop reason: {results.stop_reason}")
Never mock the real run. Before reporting these numbers, confirm this wasn't a mock/offline
run in disguise — total_cost should be positive and per-trial outputs should vary, not the
mock's constant response / uniform scores. See traigent-optimize-run → "Never mock the real
run" for the full check and recovery steps.
For algorithm choices, parallel execution, and further cost-limit controls, cross-reference traigent-optimize-run; for interpreting OptimizationResult beyond this snippet, cross-reference traigent-analyze-results. Do not promote the winner straight into production: export it as a candidate, check it on a held-out slice (see traigent-ci-safety-gate for the promotion gate and CI checks), and apply only after the gate and the user's explicit approval:
# Export the winning config as a CANDIDATE artifact for review/gating
my_function.export_config("candidate_config.json")
# After the holdout/promotion gate passes and the user approves:
my_function.apply_best_config(results)
answer = my_function("What is Python?")
Quick Reference
|
Mock (Dry Run) |
Real |
| Activation |
traigent.testing.enable_mock_mode_for_quickstart() |
(don't call it) |
TRAIGENT_OFFLINE_MODE |
true |
unset |
| API keys needed |
No |
Yes |
| LLM calls |
Mocked |
Real |
| Cost |
$0 |
Real tokens |
| Scores meaningful |
Custom scorer recommended (built-in mock returns generic text) |
Yes |
| Production-safe |
Hard-blocked when ENVIRONMENT=production |
— |
| Use when |
Always first |
After mock passes |
The 12-Step Lifecycle Playbook
ANALYZE the client codebase before writing code.
- Find LLM call sites, prompt construction, retrieval steps, tool loops, validators, judges, retries, and postprocessors.
- Useful greps: raw SDK calls (
chat.completions.create, responses.create, messages.create), framework calls (ChatOpenAI, ChatAnthropic, Runnable, AgentExecutor, create_react_agent, litellm.completion), retrieval (similarity_search, as_retriever, rerank), and loop/control terms (tool_calls, function_call, critic, judge, repair, retry).
- Identify the agent SHAPE: single LLM call, cheap-vs-expensive model path, multi-stage chain, input router, tool loop, generate-then-check, specialists, fallback, or iterative refinement.
- Pick the smallest function enclosing the scoreable agent behavior. Do not decorate an app route, auth layer, retry wrapper, or generic provider client if the actual input/output to evaluate is higher level.
- Use
references/codebase-analysis.md for grep patterns, shape markers, and codebase-specific evidence mining.
CURATE the evaluation dataset.
- Start from existing fixtures, golden sets, accepted traces, support tickets, or redacted logs before synthesizing new examples.
- Reserve the holdout slice BEFORE the first optimization run and record the partition (tuning slice / optional exemplar bank / holdout slice); if none exists yet, create one before any result counts as promotion-ready.
- Keep tuning and holdout slices separate, stratify by known input classes, and report sample count, source, label quality, and exclusions.
- Use JSONL with scoreable
input and output fields when a built-in evaluator can score the task.
- Mock/offline-check a tiny slice before any backend generation or paid provider work.
- DELEGATE:
traigent-dataset-curate owns dataset recipes, growth, example scoring, and quality loops.
CHOOSE the metric.
- Decide what "good" means before writing optimizer code: task success, correctness, cost, latency, safety, reliability, or a measured combination.
- Prefer built-in objective names when they match the product decision; use custom metric functions only when domain logic is checkable and necessary.
- Default: at least one objective labeled
accuracy (built-in objective or your metric_functions key). If accuracy doesn't apply to this problem, name the primary quality KPI after the product concept and note why accuracy was skipped.
- Treat must-not-violate behavior as a safety constraint or promotion gate, not as an ordinary objective to trade away.
- DELEGATE:
traigent-eval-choose-metric owns the metric interview and objective vocabulary.
WIRE OR BUILD the evaluator.
- Use the wire-first ladder:
eval_dataset -> scoring_function -> metric_functions -> custom_evaluator -> BaseEvaluator.
- Start deterministic when the task has ground truth or checkable domain logic; use LLM judges only when deterministic scoring cannot express the quality target.
- Audit any LLM judge before trusting it to drive optimization.
- DELEGATE:
traigent-eval-build owns evaluator code; traigent-eval-audit owns judge reliability checks.
SELECT TVARS with generate_config.
- Use only the real SDK helper:
from traigent.config_generator import generate_config
suggested = generate_config(
"path/to/agent.py",
function_name="my_agent",
enrich=False, # offline: no LLM call, no spend
)
print(suggested.agent_type) # inferred, e.g. "classification", "rag"
for rec in suggested.recommendations:
print(rec.name, rec.range_type, rec.impact_estimate)
print(" why :", rec.reasoning)
print(" apply:", rec.apply_guidance) # manual runtime steps, when the knob needs them
generate_config reads the target file and returns tvars, objectives, benchmarks, safety_constraints and recommendations, with the agent type INFERRED — you no longer pick a catalog type by hand.
- With
enrich=False it is preset-only: llm_calls_made == 0 and llm_cost_usd == 0.0. Pass enrich=True only with the user's approval, and respect budget_usd.
- Every recommendation carries
reasoning and an impact_estimate, and knob-pack rows carry apply_guidance (the manual runtime steps). Treat these as mandatory user-facing context: recommendations are search-space starting points, not universal performance claims. There is no confidence attribute on these rows — TVarRecommendation exposes name, range_type, range_kwargs, category, reasoning, impact_estimate, entry_id, catalog_entry_id, kind, effectuation_status, effectuation_strategy, evidence_refs, apply_guidance, recommended_values.
- Knob packs still exist in the shipped catalog and surface through
recommendations when they fit the inferred agent type — e.g. repo_context_strategy, file_view_window, edit_granularity, test_selection_strategy, patch_review_mode for coding agents; retrieval_k, context_selection_policy, context_order, summary_style, compression_ratio, citation_policy for long-context/RAG agents. Read each row's reasoning for what it means and apply_guidance for the manual runtime steps it needs.
- Do NOT use
traigent.config_generator.recommendations, recommend_configuration_space(), or list_recommendation_agent_types(). That public catalog surface was REMOVED from the SDK, and tests/unit/test_recommendation_catalog_absence.py asserts it stays removed — teaching it hands the user an ImportError.
- For range syntax, constraints, and typed parameters, cross-reference
traigent-optimize-config-space instead of duplicating it.
- When the suggestions do not fit:
generate_config infers the agent
type, so the old "matches no catalog type" dead end is gone — a single-call
classifier comes back as classification, not as an error. But an inferred
type is still a guess about someone else's code. If the returned
recommendations clearly do not describe the client's agent, drive the
configuration space from the client's REAL knobs (prompt/style variants,
temperature, sample count) instead of forcing the suggested one. Say in the
report that the space is client-derived, and keep surfacing each row's
reasoning, impact_estimate and apply_guidance either way.
- SELECT A COMPOSITE with this SHAPE-to-PATTERN decision table.
| Agent shape |
Composite pattern |
Use when |
| Single LLM call with sampling upside |
self_consistency or best_of_n |
Repeated candidates can improve a vote or judge-selected answer. |
| Cheap-vs-expensive model choice |
binary_cascade |
Start cheap and escalate to expert only when the margin is weak. |
| Multi-stage chain |
n_cascade |
Ordered stages escalate through three or more arms. |
| Input classes need different handling |
router |
Dispatch before execution using input adequacy or class signals. |
| Tool loop |
react_tool_loop |
The agent plans one tool step per iteration and stops on confidence. |
| Generate-then-check |
verification_gate |
Draft, verify, and revise based on a verifier pass score. |
| Multiple specialist prompts/models |
moe |
Several experts answer and a vote or judge aggregates them. |
| Primary plus backup |
fallback |
Try a primary path, then backup arms on no-accept or low margin. |
| Iterative draft improvement |
self_refine / bounded_refine_loop |
Improve a threaded draft until an acceptance signal passes or a literal iteration cap is hit. |
- For exact factory signatures,
StageRunner/LoopBodyRunner wiring, execute_composite, and telemetry, cross-reference traigent-optimize-composite-knobs; do not duplicate its catalog.
- DELEGATE:
traigent-optimize-composite-knobs owns composite factory details and runtime wiring.
- INSTRUMENT minimally and preserve behavior.
- Wrap the chosen scoreable function with
@traigent.optimize.
- Keep the original function signature stable: same name and input parameters. If production callers require a plain output but evaluation returns
(output, metrics), add a thin outer adapter rather than changing the call-site inputs.
- Merge catalog recommendations, local knobs, and composite members:
CONFIGURATION_SPACE = {
**recommendations["configuration_space"],
"model": ["gpt-4o-mini", "gpt-4o"],
"temperature": [0.0, 0.2, 0.7],
"candidate_count": [1, 2, 3],
**COMPOSITE.members,
}
- Inside the function, read
cfg = traigent.get_config(), route tuned values into the real prompt/retriever/tool/model call, execute the composite if selected, and return exactly (output, metrics) when you need per-trial numeric measures.
- Keep metrics content-free where required: accuracy, pass rate, cost, latency, token counts, route ids, iteration counts, and composite telemetry are fine. Do not put prompts, answers, retrieved documents, secrets, or PII into metrics.
- Use
references/instrument-recipe.md for the smallest before/after code diff.
VALIDATE in mock mode FIRST.
- Cross-reference
traigent-setup-quickstart and traigent-debugging for mock/offline setup.
- Use
from traigent.testing import enable_mock_mode_for_quickstart plus TRAIGENT_OFFLINE_MODE=true for keyless development.
- Confirm dataset loading, config sampling, stage wiring, tuple-return unpacking, and zero failed trials before real provider calls.
- Machine-checkable success contract — assert this instead of eyeballing the table:
assert results.trials, "no trials ran" · assert not getattr(results, "failed_trials", []), f"failed trials: {results.failed_trials}" · assert results.best_config is not None, "no best config selected".
- Mock reality: mock still consumes
optimization_samples quota; exact/execution-match scorers read uniform 0.0 under mock (expected, not broken); raw openai/anthropic clients are not intercepted and still bill.
- DELEGATE:
traigent-setup-quickstart owns first-run setup; traigent-debugging owns mock/offline failure diagnosis.
OPTIMIZE for real only with cost limits and explicit approval.
- Cross-reference
traigent-optimize-run for func.optimize(), optimize_sync(), algorithms, max_trials, parallelism, and CostLimitExceeded.
- Set an explicit
TRAIGENT_RUN_COST_LIMIT and verify provider keys before the real run. If a Traigent backend is used, set TRAIGENT_API_KEY and TRAIGENT_BACKEND_URL as appropriate for the client environment. See Getting your Traigent API key if you have not yet obtained TRAIGENT_API_KEY.
- Present a cost estimate and get the user's explicit approval before any paid run. The approval signal depends on context: interactive real runs are gated by
TRAIGENT_COST_APPROVED=true (set only after the user approves the estimate); CI/offline runs (including mock wiring checks under CI=true) require TRAIGENT_RUN_APPROVED=1 instead — see traigent-ci-safety-gate.
- Start with a bounded trial budget, keep the current production baseline in the search space, and save results artifacts for audit.
- DELEGATE:
traigent-optimize-run owns algorithms, budgets, and execution controls.
INSIGHT: configurations AND examples.
- Configuration side: start with
get_optimization_insights(results), then use traigent-analyze-variable-importance for importance-backed knob ranking.
- Example side: use
ExampleInsightsClient to compute example scores, read scores, and read dataset-quality metadata. Its reportable scope is non-signal metadata; do not claim hidden difficulty, informativeness, ambiguity, or causal signal values.
- Core
ExampleInsightsClient import warns deprecated since 0.13.x (see version-matrix: exampleinsights-deprecation): importing it from core traigent.analytics emits a DeprecationWarning pointing at the traigent-analytics plugin — but the plugin does not export this class, so keep the core import and ignore the warning for this class. If the plugin IS installed, the core shim stops exposing the class; use the deep import from traigent.analytics.example_insights import ExampleInsightsClient (see the verified import note in traigent-dataset-curate).
- Report baseline vs
results.best_config delta for the agreed metrics, cost, token use, trial count, failed trials, and results.stop_reason.
- Use
traigent-analyze-results for OptimizationResult inspection and traigent-analyze-variable-importance to explain which knobs mattered.
- If results are flat, noisy, failed, or negative, call it a no-boost result. Do not hide it or promote a winner that does not beat the baseline on the evaluation dataset.
- When wire-proofing against a Traigent backend, expect the run's
configuration-record count to differ from
len(results.trials) — the
backend de-duplicates/aggregates repeated configs. Assert your claims
(e.g. composite telemetry present) over the RETURNED records, and note
that aggregate results.total_cost can be None even when per-trial
cost measures are 0.0.
- Full code lives in
references/insights-and-iteration.md.
- DELEGATE:
traigent-analyze-results owns result-object depth; traigent-analyze-variable-importance owns richer TVAR importance reporting.
- RECOMMEND the most promising next steps.
- When the service payload carries a Traigent
attribution block (active-voice provenance), that block is the Traigent-authored next action: present its headline (active voice, Traigent as the subject) and why verbatim through traigent-analyze-guidance, without re-wording or recomputing it locally. It is provenance, not a performance claim — no guarantee, no evidence upgrade.
- Offline, or when the payload carries no
attribution block (older backend or older SDK client): fall back to the symptom-to-action table in references/insights-and-iteration.md and choose one next hypothesis, not a bundle of unrelated changes.
- Use example-side findings only as evidence for targeted curation or heldout checks.
- DELEGATE:
traigent-analyze-guidance owns post-run next-action selection.
- COMPLETE: recommend the safety gate and CI checks.
- In-run
safety_constraints is planned but not yet implemented (raises NotImplementedError at decoration time — see traigent-ci-safety-gate); do not teach it as usable today.
- Use
PromotionGate for candidate-vs-incumbent decisions on the same holdout — the working gating mechanism today.
- Recommend SAFETY and EFFICIENCY CI jobs before promotion: holdout regression for safety, plus cost and latency budget checks for efficiency.
- DELEGATE:
traigent-ci-safety-gate owns safety constraints, promotion gates, and CI recipes.
Claim scope
- End-to-end optimization results are observations from the client's evaluation dataset and run conditions.
- Insights are observations, not causes, unless supported by parameter-importance evidence.
- Gate decisions are statistical decisions on the evaluation dataset.
- Per-variable calibration certificates are the only procedural calibration claims; they do not certify future product behavior.
- Acceptable winner wording:
Calibration-backed winner (client-attested).
- Never say
guarantee, never imply universal lift, and never present catalog recommendations as proof that the client agent will improve.
Traigent Interaction Policy
Track an interaction profile and adapt to it. Persona (stable): control=delegate|guided|inspect,
expertise=se|ds|unknown. Mood (this session): pace=execute|balanced|explore. Default when
unknown: guided,se,balanced. Infer from explicit user statements first, then recent behavior;
an explicit correction wins immediately. Never store or send this profile anywhere by default.
Fetch the live profile (when available)
At session or skill start, if a configured Traigent client is available, seed the profile from the
backend with the skill name:
policy = None
try: policy = await client.get_interaction_policy(skill="<this skill>")
except Exception: pass
Treat the returned profile as the STARTING seed: its control/expertise/pace axes plus
question_budget, options_max, and jargon_level replace the static defaults below. Explicit user
corrections in-conversation ALWAYS override the seed. If the call is unavailable or
fallback_policy="static_v1", simply use the static defaults below; the SDK already fails soft.
- Always be concise.
- Match terminology to expertise. For
se: plain engineering words; define each Traigent or
statistics term once in plain language (no Bayesian / variance-decomposition / Pareto jargon
unless asked). For ds: compact optimization and statistical terms are fine.
- Presenting options: show at most 3, mark exactly one Recommended, and give one short
persona-appropriate trade-off per option.
- Autonomy. For
delegate or execute: pick the recommended reversible action and proceed, asking
only at hard gates. For guided: offer options with a recommendation at the key decisions. For
inspect or explore: give brief rationale or evidence before asking, and ask before branch
choices.
- Hard gates — always confirm regardless of persona: paid or provider model calls, sending data or
private content off the machine, destructive edits, decisions the Traigent service is meant to
return, and any missing fact the step truly requires.
- Always end by recommending the next Traigent skill or action to take.
- Never weaken Traigent safety: dry-run before any paid run; get explicit approval before real cost
or before any data leaves the machine; treat service-returned plans and next steps as
authoritative. Never put the persona profile or any private content into telemetry, run metadata,
experiment names, logs, or provenance files.
1---2name: traigent-boost-agent3description: End-to-end lifecycle playbook — from a single decorated function to a full 12-step codebase onboarding — for adding Traigent to an existing client agent codebase and measurably boosting accuracy, cost, latency, or reliability. Use when asked to add Traigent to an existing agent codebase, onboard this agent to Traigent end-to-end, run a full agent-build lifecycle, wire an evaluator and optimize for an agent with code to instrument, boost accuracy/cost of an existing agent, select TVARs with generate_config() on agent code, choose composite knobs by agent shape, instrument @traigent.optimize into agent code, validate in mock mode, run real optimization with budgets, inspect results, iterate to refine an existing agent, or gate a promoted config. For brand-new users without an existing agent codebase, see traigent-setup-quickstart. ALWAYS start with dry-run (mock mode) to validate the full pipeline, then switch to real execution only when the user explicitly requests it.4license: Apache-2.05---67# Traigent Boost Agent89<!-- PROTECTED -->10## Your Role1112When a user asks you to optimize a function or agent with Traigent, **always start with a dry run**. Real optimization costs real tokens and money. Never run real optimization until the user explicitly asks.13Present a cost estimate and get the user's explicit approval before any paid run.1415**Workflow:**16171. Set up the decorated function (for a single function, see the Fast Path below; for a whole codebase, Steps 1-7 of the 12-Step Lifecycle Playbook)182. Validate dataset, config space, and providers193. Dry-run in mock mode — verify the full pipeline end-to-end at zero cost204. Report what the dry run found, estimate real costs215. **Wait** for the user to say "run it for real"22<!-- /PROTECTED -->2324## When to Use2526Requires `traigent>=0.24.0` (the knobs API is present on all current SDK releases).2728Use this skill when the user asks you to:2930- "add Traigent to this agent"31- "optimize this agent"32- "boost accuracy/cost of an existing agent codebase"33- "onboard this agent to Traigent end-to-end"34- "full agent-build lifecycle"35- "wire an evaluator and optimize"36- instrument an existing LLM, RAG, tool-using, coding, or multi-stage agent with Traigent37- choose tuned variables and composite knobs for a real client codebase3839For detailed grep patterns and evidence-mining heuristics, read `references/codebase-analysis.md`. For a minimal before/after implementation recipe, read `references/instrument-recipe.md`. For insight and iteration code, read `references/insights-and-iteration.md`.4041## Optimization Economics — Read This Before Sizing a Run4243**Do not default to recommending zero spend.** The canonical Traigent posture on spending,44the five characterization questions with their exact options, the tailoring rules (including45the three-option paging rule), the explanation duty, and the local survey draft contract all46live in one file that ships inside this skill:47**`references/economics-characterization.v0.md`**. Read it from this skill's own directory48before you propose, size, or decline a run — it is deliberately not restated here. It is49generated from `docs/shared/economics-characterization.v0.md` in the traigent-skills repo,50which is where any edit goes; the copy shipped here is byte-identical.5152**Characterize, never compute a budget locally.** Collect the characterization and relay it;53the Traigent service authors the budget, exactly as it authors the run-plan and the next-step54decision — **budget authorship belongs to the service.** Do not compute, adjust, or recommend a55budget locally: no budget arithmetic in markdown, no floor/cap table, no "roughly $X/day" of56your own. The reference describes what the service computes; it is not a local calculator, and57when the service returns no economics result, say so plainly and continue with **no budget58number at all** rather than inventing one.5960**This skill's part:** characterize the value the client agent creates and relay it, so the61service can size a bounded first experiment to it.6263**Mandatory whenever you relay any of it:** show the options, recommend exactly one, and64explain **why in the user's own numbers** — their agent, their volumes, their error costs. The65explanation is a product requirement, not decoration.6667Safety is unchanged and unweakened: mock/dry-run first, **explicit user approval before any68paid run**, an explicit spend cap, and the recorded stop rule. The service sets69*how much* to invest; it never affects *whether* approval is required — it always is.7071## Fast Path: Optimize a Single Function7273For a single decorated function (rather than a whole codebase), run this condensed dry-run-first sequence; the 12-Step Lifecycle Playbook below is the full-codebase version.7475### Step 1: Set Up the Decorator7677The user's function needs four things: dataset, objectives, config space, and the function itself.7879```python80import traigent81import litellm # pip install "traigent[integrations]>=0.19" — the canonical runnable LLM call82from traigent import Choices, Range8384@traigent.optimize(85 eval_dataset="eval_data.jsonl", # 1. Dataset86 objectives=["accuracy"], # 2. What to optimize87 model=Choices(["gpt-4o-mini", "gpt-4o"]), # 3. Config space (inline)88 temperature=Range(0.0, 1.0),89)90def my_function(query: str) -> str: # 4. The function91 config = traigent.get_config()92 resp = litellm.completion(93 model=config["model"],94 temperature=config["temperature"],95 messages=[{"role": "user", "content": query}],96 )97 return resp.choices[0].message.content98```99100> **One runnable body, reused everywhere.** The `litellm.completion(...)` → `resp.choices[0].message.content` body above is the canonical, copy-paste-runnable function used across these skills. Reuse it verbatim wherever an example shows `my_function`/agent body — it runs keyless under mock mode (LiteLLM is intercepted) and unchanged for a real run. **Optimize accuracy *and* cost?** `cost` and `latency` are built-in objectives auto-derived from token accounting, so use `objectives=["accuracy", "cost"]` — no extra evaluator needed. See `traigent-setup-quickstart` for the full copy-paste example, `traigent-optimize-config-space` for `Range`/`Choices`/`IntRange`/`LogRange`/constraints, and `traigent-setup-decorator` for `EvaluationOptions`/`InjectionOptions`/`ExecutionOptions`.101102#### Setup Mistakes to Catch103104| Mistake | SDK catches? | Fix |105|---|---|---|106| Config values as bare strings (`model="gpt-4"`) | Yes — `TypeError` | Must be list or Range/Choices (`model=Choices(["gpt-4"])`) |107| `get_config()` called outside the function | Yes — `OptimizationStateError` | Must be inside the decorated function body |108| Dataset file doesn't exist | Yes — `ValidationError` | Create it or fix the path |109| **Empty objectives list** | **No — silently defaults** | Verify `objectives` has at least one entry before running |110| **Function doesn't return a value** | **No — `None` scored silently** | Assert your function returns the prediction; `None` produces meaningless scores |111112### Step 2: Validate Before Running113114Use the SDK's built-in validation tools before any optimization:115116```bash117traigent validate eval_data.jsonl --objectives accuracy -v # dataset: valid JSON, `input` field (+ `output` for accuracy-like metrics); 5+ examples, 10-20+ recommended118traigent info # SDK version, Python version, enabled features119traigent algorithms # Available algorithms with descriptions and best-use cases120traigent check my_script.py --dry-run # discovers @traigent.optimize functions; validates decorator wiring only, not dataset contents121```122123### Step 3: Run Mock Optimization124125Enable mock mode in code, then run the full optimization pipeline end to end (decorator wiring, config sampling, dataset loading, trial execution, scoring) with LLM calls intercepted. Mock mode is hard-blocked when `ENVIRONMENT=production`. For mock-mode setup mechanics and scope (what is and isn't intercepted, mock vs offline), see `traigent-setup-quickstart`.126127> Mock dry-runs still consume the plan's `optimization_samples` quota, and mock intercepts LiteLLM/LangChain calls only — raw `openai`/`anthropic` clients are NOT intercepted and still bill. See `traigent-debugging` for the quota entry and hermetic-startup env vars (`TRAIGENT_MOCK_LLM`, `TRAIGENT_OFFLINE_MODE`, `LITELLM_LOCAL_MODEL_COST_MAP`).128129```python130import os131os.environ["TRAIGENT_OFFLINE_MODE"] = "true" # Skip Traigent backend calls132133import traigent134from traigent.testing import enable_mock_mode_for_quickstart135136enable_mock_mode_for_quickstart() # Mock LLM responses (dev-only)137138# Same @traigent.optimize-decorated my_function as Step 1 —139# its litellm.completion(...) call is intercepted automatically in mock mode.140results = my_function.optimize_sync(max_trials=4, algorithm="random")141142print(f"Trials ran: {len(results.trials)}")143print(f"Failed trials: {len(results.failed_trials)}")144print(f"Stop reason: {results.stop_reason}")145print(f"Best config: {results.best_config}")146print(f"Best score: {results.best_score}")147```148149#### Interpret Mock Results150151| Check | Pass | Fail |152|---|---|---|153| Trials ran | `len(results.trials) > 0` | No trials = config space or dataset error |154| No failures | `len(results.failed_trials) == 0` | Failures = function or evaluator bug |155| Stop reason | `"max_trials_reached"` or `"optimizer"` | `"error"` = something broke |156| Config keys | Expected keys in `best_config` | Missing keys = config space mismatch |157158Score interpretation depends on evaluator type: a config-aware scorer (reads `traigent.get_config()`) produces meaningful varied scores even in mock mode; an output-based/deterministic scorer (exact-match, JSON-schema, execution accuracy) sees the mock LLM's constant response and scores uniformly 0.0.159160> **WARNING — uniform 0.0 under mock is plumbing-OK, not a failure:**161> If your scorer is output-based (exact-match, SQL execution accuracy, JSON-schema, etc.)162> and all mock scores are 0.0, that is the correct expected result: the mock returns a163> constant string that no deterministic scorer can score positively. Focus on whether trials164> ran without errors (`failed_trials == 0`), not on the 0.0 score values.165>166> For a varied score spread without real LLM calls, wire a config-aware mock-only demo167> scorer (delete it for the real run) — see `traigent-setup-quickstart` (`mock_demo_accuracy`)168> for the recipe.169170If mock fails, set `export TRAIGENT_DEBUG=1` for debug logging, fix decorator args for `ConfigurationError` (see mistakes table above), and see `traigent-debugging` (`references/mock-mode.md`) for the full mock failure diagnosis (evaluation errors, `get_config()` outside optimization context, missing integrations extra, all-trials-failed).171172<!-- PROTECTED -->173**Do not proceed to real mode until mock passes cleanly.**174<!-- /PROTECTED -->175176### Step 3.5: Evaluator Sanity Gate177178Before the first paid run, verify the metric actually separates a correct output from a wrong one. This costs nothing — no LLM calls — but catches the single most expensive silent failure mode: an evaluation metric that swallows exceptions or silently returns 0.0 for every config (making the agent look broken when the metric is broken).179180```python181# `my_metric` is the scoring_function / metric you pass to @traigent.optimize.182# Use literal good/bad examples for YOUR task — no LLM call needed (that's the point).183expected_output = "the expected answer for one example" # your gold label184known_good = "a known-correct output for that example" # e.g. the gold answer itself185known_bad = "obviously wrong or empty output"186187assert my_metric(known_good, expected_output) >= 0.9, (188 "metric does not reward a correct output — fix before running real optimization"189)190assert my_metric(known_bad, expected_output) <= 0.1, (191 "metric does not penalize a wrong output — fix before running real optimization"192)193```194195For a `custom_evaluator` / `BaseEvaluator`, call `.evaluate([good_example])` and `.evaluate([bad_example])` directly and assert the returned `metrics` separate. Use **one known-good + one known-bad example only** — this is a smoke gate, not a full audit.196197> **If both assertions pass:** the metric wires correctly — proceed to Step 4.198>199> **If either fails:** fix the metric before spending tokens. Common causes: wrong field name in the result, inverted logic (`>` vs `<`), exception swallowed to `0.0`. See [traigent-eval-build](../traigent-eval-build/SKILL.md) for diagnostic steps. For LLM-judge metrics, see [traigent-eval-audit](../traigent-eval-audit/SKILL.md) for the full reliability protocol.200201### Step 3.6: Tiny Real Cost and KPI Probe202203After mock mode and the evaluator sanity gate pass, run one tiny **real** optimization before any full run: 1-2 dataset examples, minimal trials, and the cheapest candidate model (pennies, not dollars). Check both surfaces: `results.total_cost` must be neither `None` nor `0.0` with real calls (both mean cost is not wired), and each trial's `metrics` must contain the declared objectives with non-degenerate values (not all `0.0`/all `1.0`). If either surface fails, wire it before scaling up — see `traigent-optimize-run` → Cost Wiring Probe for the fix ladder (custom model pricing env vars, per-trial cost metrics, strict accounting).204205### Step 4: Report and Estimate Costs206207After a successful mock run, tell the user:2082091. **Pipeline validated** — trials, config space, dataset all working2102. **Config space size** — how many unique configurations2113. **Estimated LLM calls** — `max_trials x dataset_size` (upper bound)2124. **Cost limit** — default $2.00 USD per run (`TRAIGENT_RUN_COST_LIMIT`)2135. **Ask for go/no-go**214215Example:216217> Mock run passed: 4/4 trials, 0 failures, pipeline is valid.218>219> Config space: 2 models x continuous temperature. With `max_trials=10` and 15 dataset examples, that's up to 150 LLM calls.220>221> Default cost limit is $2.00 USD. Want me to run it for real? This will use your API keys and cost real tokens.222223### Step 5: Run Real Optimization (Only When Asked)224225<!-- PROTECTED -->226When the user explicitly says to proceed:227<!-- /PROTECTED -->228229Verify API keys first — models in the config space need corresponding provider keys, and Traigent auto-validates them before starting, raising `ProviderValidationError` with details if validation fails:230231```bash232export OPENAI_API_KEY="sk-..." # For gpt-* models233export ANTHROPIC_API_KEY="sk-ant-..." # For claude-* models234export GEMINI_API_KEY="..." # For gemini-* models235```236237Then skip the mock-mode activation and set cost controls:238```python239import os240241# Just don't call enable_mock_mode_for_quickstart() this run.242# Mock mode is process-local — start a fresh interpreter for the243# real run if the previous one had it on.244os.environ.pop("TRAIGENT_OFFLINE_MODE", None)245246# Cost limit — default $2.00 USD per run247os.environ["TRAIGENT_RUN_COST_LIMIT"] = "2.00"248249# Real runs are blocked by the cost-approval gate until this is set.250# Set it ONLY after the user has seen the cost estimate and explicitly251# approved the spend — never set it preemptively on the user's behalf.252os.environ["TRAIGENT_COST_APPROVED"] = "true"253```254255> **Algorithm selector.** For connected real runs, omit `algorithm` or use `algorithm="auto"`.256> `auto` is the default connected path to real cloud Optuna TPE. Use257> `algorithm="grid"` / `"random"` only for explicit local/offline search.258>259> **Named smart selectors execute on connected runs since 0.20.1**260> (see version-matrix: `smart-selector-exec`). On an authenticated connected run, supported names261> (`bayesian`/`tpe`/`optuna`/`optuna_tpe`/`optuna_random`) bind to the typed backend Optuna262> strategy at session creation; unsupported smart names such as `nsga2`/`cmaes` fail fast with263> a capability message (Traigent/Traigent#1752, #1758; on 0.20.0 no named smart selector264> executed end-to-end). They never run locally: with `offline=True` the decorator raises265> `ConfigurationError`, and the local optimizer registry raises `OptimizationError`.266267```python268from traigent.utils.exceptions import CostLimitExceeded, OptimizationError269270try:271 # Connected real run: omit algorithm or use "auto". Smart selector names272 # like "bayesian" are connected-only (SDK 0.20.1+) and never run locally.273 results = my_function.optimize_sync(max_trials=10, algorithm="auto")274except CostLimitExceeded as e:275 print(f"Budget hit: ${e.accumulated:.2f} / ${e.limit:.2f}")276 print("Increase TRAIGENT_RUN_COST_LIMIT to allow more spending.")277 raise278except OptimizationError as e:279 print(f"Optimization could not run: {e}")280 raise281282print(f"Best config: {results.best_config}")283print(f"Best score: {results.best_score}")284if results.total_cost:285 print(f"Total cost: ${results.total_cost:.2f}")286else:287 # None or 0.0 after real calls = cost is NOT wired (see Step 3.6) —288 # say so loudly instead of hiding the row.289 print("Total cost: NOT TRACKED — wire cost before the next run (Step 3.6)")290print(f"Duration: {results.duration:.1f}s")291print(f"Stop reason: {results.stop_reason}")292```293294> **Never mock the real run.** Before reporting these numbers, confirm this wasn't a mock/offline295> run in disguise — `total_cost` should be positive and per-trial outputs should vary, not the296> mock's constant response / uniform scores. See `traigent-optimize-run` → "Never mock the real297> run" for the full check and recovery steps.298299For algorithm choices, parallel execution, and further cost-limit controls, cross-reference `traigent-optimize-run`; for interpreting `OptimizationResult` beyond this snippet, cross-reference `traigent-analyze-results`. Do not promote the winner straight into production: export it as a candidate, check it on a held-out slice (see `traigent-ci-safety-gate` for the promotion gate and CI checks), and apply only after the gate and the user's explicit approval:300301```python302# Export the winning config as a CANDIDATE artifact for review/gating303my_function.export_config("candidate_config.json")304305# After the holdout/promotion gate passes and the user approves:306my_function.apply_best_config(results)307answer = my_function("What is Python?")308```309310### Quick Reference311312| | Mock (Dry Run) | Real |313|---|---|---|314| Activation | `traigent.testing.enable_mock_mode_for_quickstart()` | (don't call it) |315| `TRAIGENT_OFFLINE_MODE` | `true` | unset |316| API keys needed | No | Yes |317| LLM calls | Mocked | Real |318| Cost | $0 | Real tokens |319| Scores meaningful | Custom scorer recommended (built-in mock returns generic text) | Yes |320| Production-safe | Hard-blocked when `ENVIRONMENT=production` | — |321| Use when | Always first | After mock passes |322323## The 12-Step Lifecycle Playbook3243251. ANALYZE the client codebase before writing code.326 - Find LLM call sites, prompt construction, retrieval steps, tool loops, validators, judges, retries, and postprocessors.327 - Useful greps: raw SDK calls (`chat.completions.create`, `responses.create`, `messages.create`), framework calls (`ChatOpenAI`, `ChatAnthropic`, `Runnable`, `AgentExecutor`, `create_react_agent`, `litellm.completion`), retrieval (`similarity_search`, `as_retriever`, `rerank`), and loop/control terms (`tool_calls`, `function_call`, `critic`, `judge`, `repair`, `retry`).328 - Identify the agent SHAPE: single LLM call, cheap-vs-expensive model path, multi-stage chain, input router, tool loop, generate-then-check, specialists, fallback, or iterative refinement.329 - Pick the smallest function enclosing the scoreable agent behavior. Do not decorate an app route, auth layer, retry wrapper, or generic provider client if the actual input/output to evaluate is higher level.330 - Use `references/codebase-analysis.md` for grep patterns, shape markers, and codebase-specific evidence mining.3313322. CURATE the evaluation dataset.333 - Start from existing fixtures, golden sets, accepted traces, support tickets, or redacted logs before synthesizing new examples.334 - Reserve the holdout slice BEFORE the first optimization run and record the partition (tuning slice / optional exemplar bank / holdout slice); if none exists yet, create one before any result counts as promotion-ready.335 - Keep tuning and holdout slices separate, stratify by known input classes, and report sample count, source, label quality, and exclusions.336 - Use JSONL with scoreable `input` and `output` fields when a built-in evaluator can score the task.337 - Mock/offline-check a tiny slice before any backend generation or paid provider work.338 - DELEGATE: `traigent-dataset-curate` owns dataset recipes, growth, example scoring, and quality loops.3393403. CHOOSE the metric.341 - Decide what "good" means before writing optimizer code: task success, correctness, cost, latency, safety, reliability, or a measured combination.342 - Prefer built-in objective names when they match the product decision; use custom metric functions only when domain logic is checkable and necessary.343 - Default: at least one objective labeled `accuracy` (built-in objective or your `metric_functions` key). If accuracy doesn't apply to this problem, name the primary quality KPI after the product concept and note why accuracy was skipped.344 - Treat must-not-violate behavior as a safety constraint or promotion gate, not as an ordinary objective to trade away.345 - DELEGATE: `traigent-eval-choose-metric` owns the metric interview and objective vocabulary.3463474. WIRE OR BUILD the evaluator.348 - Use the wire-first ladder: `eval_dataset` -> `scoring_function` -> `metric_functions` -> `custom_evaluator` -> `BaseEvaluator`.349 - Start deterministic when the task has ground truth or checkable domain logic; use LLM judges only when deterministic scoring cannot express the quality target.350 - Audit any LLM judge before trusting it to drive optimization.351 - DELEGATE: `traigent-eval-build` owns evaluator code; `traigent-eval-audit` owns judge reliability checks.3523535. SELECT TVARS with `generate_config`.354 - Use only the real SDK helper:355356```python357from traigent.config_generator import generate_config358359suggested = generate_config(360 "path/to/agent.py",361 function_name="my_agent",362 enrich=False, # offline: no LLM call, no spend363)364365print(suggested.agent_type) # inferred, e.g. "classification", "rag"366for rec in suggested.recommendations:367 print(rec.name, rec.range_type, rec.impact_estimate)368 print(" why :", rec.reasoning)369 print(" apply:", rec.apply_guidance) # manual runtime steps, when the knob needs them370```371372 - `generate_config` reads the target file and returns `tvars`, `objectives`, `benchmarks`, `safety_constraints` and `recommendations`, with the agent type INFERRED — you no longer pick a catalog type by hand.373 - With `enrich=False` it is preset-only: `llm_calls_made == 0` and `llm_cost_usd == 0.0`. Pass `enrich=True` only with the user's approval, and respect `budget_usd`.374 <!-- PROTECTED -->375 - Every recommendation carries `reasoning` and an `impact_estimate`, and knob-pack rows carry `apply_guidance` (the manual runtime steps). Treat these as mandatory user-facing context: recommendations are search-space starting points, not universal performance claims. There is no `confidence` attribute on these rows — `TVarRecommendation` exposes `name`, `range_type`, `range_kwargs`, `category`, `reasoning`, `impact_estimate`, `entry_id`, `catalog_entry_id`, `kind`, `effectuation_status`, `effectuation_strategy`, `evidence_refs`, `apply_guidance`, `recommended_values`.376 <!-- /PROTECTED -->377 - Knob packs still exist in the shipped catalog and surface through `recommendations` when they fit the inferred agent type — e.g. `repo_context_strategy`, `file_view_window`, `edit_granularity`, `test_selection_strategy`, `patch_review_mode` for coding agents; `retrieval_k`, `context_selection_policy`, `context_order`, `summary_style`, `compression_ratio`, `citation_policy` for long-context/RAG agents. Read each row's `reasoning` for what it means and `apply_guidance` for the manual runtime steps it needs.378 - **Do NOT use** `traigent.config_generator.recommendations`, `recommend_configuration_space()`, or `list_recommendation_agent_types()`. That public catalog surface was REMOVED from the SDK, and `tests/unit/test_recommendation_catalog_absence.py` asserts it stays removed — teaching it hands the user an ImportError.379 - For range syntax, constraints, and typed parameters, cross-reference `traigent-optimize-config-space` instead of duplicating it.380 - **When the suggestions do not fit**: `generate_config` infers the agent381 type, so the old "matches no catalog type" dead end is gone — a single-call382 classifier comes back as `classification`, not as an error. But an inferred383 type is still a guess about someone else's code. If the returned384 `recommendations` clearly do not describe the client's agent, drive the385 configuration space from the client's REAL knobs (prompt/style variants,386 temperature, sample count) instead of forcing the suggested one. Say in the387 report that the space is client-derived, and keep surfacing each row's388 `reasoning`, `impact_estimate` and `apply_guidance` either way.3893906. SELECT A COMPOSITE with this SHAPE-to-PATTERN decision table.391392| Agent shape | Composite pattern | Use when |393|---|---|---|394| Single LLM call with sampling upside | `self_consistency` or `best_of_n` | Repeated candidates can improve a vote or judge-selected answer. |395| Cheap-vs-expensive model choice | `binary_cascade` | Start cheap and escalate to expert only when the margin is weak. |396| Multi-stage chain | `n_cascade` | Ordered stages escalate through three or more arms. |397| Input classes need different handling | `router` | Dispatch before execution using input adequacy or class signals. |398| Tool loop | `react_tool_loop` | The agent plans one tool step per iteration and stops on confidence. |399| Generate-then-check | `verification_gate` | Draft, verify, and revise based on a verifier pass score. |400| Multiple specialist prompts/models | `moe` | Several experts answer and a vote or judge aggregates them. |401| Primary plus backup | `fallback` | Try a primary path, then backup arms on no-accept or low margin. |402| Iterative draft improvement | `self_refine` / `bounded_refine_loop` | Improve a threaded draft until an acceptance signal passes or a literal iteration cap is hit. |403404 - For exact factory signatures, `StageRunner`/`LoopBodyRunner` wiring, `execute_composite`, and telemetry, cross-reference `traigent-optimize-composite-knobs`; do not duplicate its catalog.405 - DELEGATE: `traigent-optimize-composite-knobs` owns composite factory details and runtime wiring.4064077. INSTRUMENT minimally and preserve behavior.408 - Wrap the chosen scoreable function with `@traigent.optimize`.409 - Keep the original function signature stable: same name and input parameters. If production callers require a plain output but evaluation returns `(output, metrics)`, add a thin outer adapter rather than changing the call-site inputs.410 - Merge catalog recommendations, local knobs, and composite members:411412```python413CONFIGURATION_SPACE = {414 **recommendations["configuration_space"],415 "model": ["gpt-4o-mini", "gpt-4o"],416 "temperature": [0.0, 0.2, 0.7],417 "candidate_count": [1, 2, 3],418 **COMPOSITE.members,419}420```421422 - Inside the function, read `cfg = traigent.get_config()`, route tuned values into the real prompt/retriever/tool/model call, execute the composite if selected, and return exactly `(output, metrics)` when you need per-trial numeric measures.423 <!-- PROTECTED -->424 - Keep metrics content-free where required: accuracy, pass rate, cost, latency, token counts, route ids, iteration counts, and composite telemetry are fine. Do not put prompts, answers, retrieved documents, secrets, or PII into metrics.425 <!-- /PROTECTED -->426 - Use `references/instrument-recipe.md` for the smallest before/after code diff.4274288. VALIDATE in mock mode FIRST.429 - Cross-reference `traigent-setup-quickstart` and `traigent-debugging` for mock/offline setup.430 - Use `from traigent.testing import enable_mock_mode_for_quickstart` plus `TRAIGENT_OFFLINE_MODE=true` for keyless development.431 - Confirm dataset loading, config sampling, stage wiring, tuple-return unpacking, and zero failed trials before real provider calls.432 - Machine-checkable success contract — assert this instead of eyeballing the table:433 `assert results.trials, "no trials ran"` · `assert not getattr(results, "failed_trials", []), f"failed trials: {results.failed_trials}"` · `assert results.best_config is not None, "no best config selected"`.434 - Mock reality: mock still consumes `optimization_samples` quota; exact/execution-match scorers read uniform 0.0 under mock (expected, not broken); raw `openai`/`anthropic` clients are not intercepted and still bill.435 - DELEGATE: `traigent-setup-quickstart` owns first-run setup; `traigent-debugging` owns mock/offline failure diagnosis.4364379. OPTIMIZE for real only with cost limits and explicit approval.438 - Cross-reference `traigent-optimize-run` for `func.optimize()`, `optimize_sync()`, algorithms, `max_trials`, parallelism, and `CostLimitExceeded`.439 - Set an explicit `TRAIGENT_RUN_COST_LIMIT` and verify provider keys before the real run. If a Traigent backend is used, set `TRAIGENT_API_KEY` and `TRAIGENT_BACKEND_URL` as appropriate for the client environment. See [Getting your Traigent API key](../traigent-setup-quickstart/SKILL.md#get-your-traigent-api-key) if you have not yet obtained `TRAIGENT_API_KEY`.440 - Present a cost estimate and get the user's explicit approval before any paid run. The approval signal depends on context: interactive real runs are gated by `TRAIGENT_COST_APPROVED=true` (set only after the user approves the estimate); CI/offline runs (including mock wiring checks under `CI=true`) require `TRAIGENT_RUN_APPROVED=1` instead — see `traigent-ci-safety-gate`.441 - Start with a bounded trial budget, keep the current production baseline in the search space, and save results artifacts for audit.442 - DELEGATE: `traigent-optimize-run` owns algorithms, budgets, and execution controls.44344410. INSIGHT: configurations AND examples.445 - Configuration side: start with `get_optimization_insights(results)`, then use `traigent-analyze-variable-importance` for importance-backed knob ranking.446 - Example side: use `ExampleInsightsClient` to compute example scores, read scores, and read dataset-quality metadata. Its reportable scope is non-signal metadata; do not claim hidden difficulty, informativeness, ambiguity, or causal signal values.447 - Core `ExampleInsightsClient` import warns deprecated since 0.13.x (see version-matrix: `exampleinsights-deprecation`): importing it from core `traigent.analytics` emits a `DeprecationWarning` pointing at the `traigent-analytics` plugin — but the plugin does not export this class, so keep the core import and ignore the warning for this class. If the plugin IS installed, the core shim stops exposing the class; use the deep import `from traigent.analytics.example_insights import ExampleInsightsClient` (see the verified import note in `traigent-dataset-curate`).448 - Report baseline vs `results.best_config` delta for the agreed metrics, cost, token use, trial count, failed trials, and `results.stop_reason`.449 - Use `traigent-analyze-results` for `OptimizationResult` inspection and `traigent-analyze-variable-importance` to explain which knobs mattered.450 <!-- PROTECTED -->451 - If results are flat, noisy, failed, or negative, call it a no-boost result. Do not hide it or promote a winner that does not beat the baseline on the evaluation dataset.452 <!-- /PROTECTED -->453 - When wire-proofing against a Traigent backend, expect the run's454 configuration-record count to differ from `len(results.trials)` — the455 backend de-duplicates/aggregates repeated configs. Assert your claims456 (e.g. composite telemetry present) over the RETURNED records, and note457 that aggregate `results.total_cost` can be `None` even when per-trial458 cost measures are `0.0`.459 - Full code lives in `references/insights-and-iteration.md`.460 - DELEGATE: `traigent-analyze-results` owns result-object depth; `traigent-analyze-variable-importance` owns richer TVAR importance reporting.46146211. RECOMMEND the most promising next steps.463 - When the service payload carries a Traigent `attribution` block (active-voice provenance), that block is the Traigent-authored next action: present its `headline` (active voice, Traigent as the subject) and `why` **verbatim** through `traigent-analyze-guidance`, without re-wording or recomputing it locally. It is provenance, not a performance claim — no guarantee, no evidence upgrade.464 - Offline, or when the payload carries no `attribution` block (older backend or older SDK client): fall back to the symptom-to-action table in `references/insights-and-iteration.md` and choose one next hypothesis, not a bundle of unrelated changes.465 - Use example-side findings only as evidence for targeted curation or heldout checks.466 - DELEGATE: `traigent-analyze-guidance` owns post-run next-action selection.46746812. COMPLETE: recommend the safety gate and CI checks.469 - In-run `safety_constraints` is planned but not yet implemented (raises `NotImplementedError` at decoration time — see `traigent-ci-safety-gate`); do not teach it as usable today.470 - Use `PromotionGate` for candidate-vs-incumbent decisions on the same holdout — the working gating mechanism today.471 - Recommend SAFETY and EFFICIENCY CI jobs before promotion: holdout regression for safety, plus cost and latency budget checks for efficiency.472 - DELEGATE: `traigent-ci-safety-gate` owns safety constraints, promotion gates, and CI recipes.473474<!-- PROTECTED -->475## Claim scope476477- End-to-end optimization results are observations from the client's evaluation dataset and run conditions.478- Insights are observations, not causes, unless supported by parameter-importance evidence.479- Gate decisions are statistical decisions on the evaluation dataset.480- Per-variable calibration certificates are the only procedural calibration claims; they do not certify future product behavior.481- Acceptable winner wording: `Calibration-backed winner (client-attested)`.482- Never say `guarantee`, never imply universal lift, and never present catalog recommendations as proof that the client agent will improve.483<!-- /PROTECTED -->484485<!-- Reserved: managed longitudinal-guidance region. Step-level edits must not write here. -->486<!-- SLOW_UPDATE -->487<!-- /SLOW_UPDATE -->488489<!-- INTERACTION_POLICY v1 (synced — do not edit inline; edit docs/shared/interaction-policy.v1.md) -->490## Traigent Interaction Policy491Track an interaction profile and adapt to it. Persona (stable): control=`delegate|guided|inspect`,492expertise=`se|ds|unknown`. Mood (this session): pace=`execute|balanced|explore`. Default when493unknown: `guided,se,balanced`. Infer from explicit user statements first, then recent behavior;494an explicit correction wins immediately. Never store or send this profile anywhere by default.495496### Fetch the live profile (when available)497At session or skill start, if a configured Traigent client is available, seed the profile from the498backend with the skill name:499500```python501policy = None502try: policy = await client.get_interaction_policy(skill="<this skill>")503except Exception: pass504```505506Treat the returned `profile` as the STARTING seed: its control/expertise/pace axes plus507`question_budget`, `options_max`, and `jargon_level` replace the static defaults below. Explicit user508corrections in-conversation ALWAYS override the seed. If the call is unavailable or509`fallback_policy="static_v1"`, simply use the static defaults below; the SDK already fails soft.510511- Always be concise.512- Match terminology to expertise. For `se`: plain engineering words; define each Traigent or513 statistics term once in plain language (no Bayesian / variance-decomposition / Pareto jargon514 unless asked). For `ds`: compact optimization and statistical terms are fine.515- Presenting options: show at most 3, mark exactly one **Recommended**, and give one short516 persona-appropriate trade-off per option.517- Autonomy. For `delegate` or `execute`: pick the recommended reversible action and proceed, asking518 only at hard gates. For `guided`: offer options with a recommendation at the key decisions. For519 `inspect` or `explore`: give brief rationale or evidence before asking, and ask before branch520 choices.521- Hard gates — always confirm regardless of persona: paid or provider model calls, sending data or522 private content off the machine, destructive edits, decisions the Traigent service is meant to523 return, and any missing fact the step truly requires.524- Always end by recommending the next Traigent skill or action to take.525- Never weaken Traigent safety: dry-run before any paid run; get explicit approval before real cost526 or before any data leaves the machine; treat service-returned plans and next steps as527 authoritative. Never put the persona profile or any private content into telemetry, run metadata,528 experiment names, logs, or provenance files.529<!-- /INTERACTION_POLICY v1 -->