This skill helps an LLM generate correct AxAgent tuning and evaluation code using @ax-llm/ax. Use when the user asks about agent.optimize(...), judgeOptions, eval datasets, optimization targets, saved optimizedProgram artifacts, or agent optimization guidance.
65
78%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Fix and improve this skill with Tessl
tessl review fix ./website/static/typescript/.well-known/agent-skills/ax-agent-optimize/SKILL.mdUse this skill for agent.optimize(...) workflows. Prefer short, modern, copyable patterns. Do not repeat general agent-authoring guidance unless the user needs it. For generic ax(...) or flow(...) tuning with top-level optimize(...), use the ax-gepa skill instead.
Your job is to help the model choose a good optimization setup for the user's actual goal:
agent.optimize(...) only after the agent is already configured and runnable.input and criteria, then let agent.optimize(...) use its default actor target and judge-based metric.optimize(program, train, metric, options) for non-agent generators and flows; do not rewrite normal agent task-record examples to the generic helper.metric only when success is easy to score from the prediction and task record.judgeAI plus judgeOptions when the judge should run on a stronger or separate model than the agent runtime model.AxGen evaluator when the user needs LLM-as-judge behavior outside the built-in agent.optimize(...) flow.target unless the user clearly wants responder-only tuning or explicit program IDs.f.object(...) over vague f.json(...) whenever the agent must reason about returned fields.axSerializeOptimizedProgram(result.optimizedProgram!), then restore with axDeserializeOptimizedProgram(saved) and agent.applyOptimization(...).bootstrap is enabled, bootstrapped demos are persisted inside result.optimizedProgram.demos; raw failed traces are not saved in v1.autoUpgrade) appear in captured traces/demos as their truncated preview string, not the full value — same as declared truncate-style contextFields. This is expected; do not treat the shortened value as a bug in the saved demos.train and validation unless the user already has a holdout set.agent.optimize(...) now optimizes generic components exposed by the selected target programs; target: 'actor' only tunes actor components, target: 'responder' only tunes responder components, and target: 'all' broadens the component set.result.optimizedProgram.componentMap is the canonical saved artifact for agent GEPA runs. It may include actor instructions, descriptions, tool descriptions/names, templates, or runtime primitives depending on what the selected target exposes.Pick the optimization shape from the user's need:
expectedActions and forbiddenActions.target: 'responder', but only if the task is not mostly tool-selection or clarification behavior.agent.playbook().evolve(dataset)) to mine failures into verified playbook bullets under a held-out gate. Python, Java, C++, Go, and Rust expose the same loop with native method casing; see ax-playbook. optimize(...) maximizes a metric by tuning instructions and demos; playbook evolution grows durable rules.Choose task design carefully:
Optimization works much better when the agent and dataset remove avoidable ambiguity:
maxSubAgentCalls small in examples unless the user is explicitly testing broad fan-out behavior.javascript: prefixes, mixed prose/code, and multi-snippet turns.Good pattern:
Bad pattern:
json with an underspecified shapeAtlas without clarifying whether that is a project, team, or accountChoose the scoring path based on how objectively the task can be measured:
metric when you can score success directly from prediction and example.judgeOptions.description to tell the built-in judge what to value most.agent.optimize(...) and still wants LLM judging.Quick rules:
AxGen evaluator.Important:
metric overrides the built-in judge path entirely.AxGen.metric and judge guidance unless the user explicitly wants two separate scoring systems and understands only the custom metric drives optimization.AxGen judge metric, prefer a numeric score:number output over a string tier when possible. It is simpler and less fragile in practice.import {
AxAIGoogleGeminiModel,
AxJSRuntime,
axDefaultOptimizerLogger,
agent,
ai,
f,
fn,
axDeserializeOptimizedProgram,
axSerializeOptimizedProgram,
} from '@ax-llm/ax';
const tools = [
fn('sendEmail')
.namespace('email')
.description('Send an email message')
.arg('to', f.string('Recipient email address'))
.arg('body', f.string('Email body text'))
.returns(
f.object({
sent: f.boolean('Whether the email was sent'),
to: f.string('Recipient email address'),
})
)
.handler(async ({ to }) => ({ sent: true, to }))
.build(),
];
const studentAI = ai({
name: 'google-gemini',
apiKey: process.env.GOOGLE_APIKEY!,
config: { model: AxAIGoogleGeminiModel.Gemini31FlashLite, temperature: 0.2 },
});
const judgeAI = ai({
name: 'google-gemini',
apiKey: process.env.GOOGLE_APIKEY!,
config: { model: AxAIGoogleGeminiModel.Gemini35Flash, temperature: 1.0 },
});
const assistant = agent('query:string -> answer:string', {
ai: studentAI,
judgeAI,
contextFields: [],
runtime: new AxJSRuntime(),
functions: tools,
contextPolicy: { preset: 'checkpointed', budget: 'balanced' },
judgeOptions: {
description: 'Prefer correct tool use over polished wording.',
model: 'judge-model',
},
});
const tasks = [
{
input: { query: 'Send an email to Jim saying good morning.' },
criteria: 'Use the email tool and send the message to Jim.',
expectedActions: ['email.sendEmail'],
},
];
const result = await assistant.optimize(tasks, {
maxMetricCalls: 12,
verbose: true,
});
const saved = axSerializeOptimizedProgram(result.optimizedProgram!);
const restored = axDeserializeOptimizedProgram(saved);
assistant.applyOptimization(restored);Start here unless the user clearly needs a hand-built scorer:
const tasks = [
{
input: { query: 'Send an email to Jim saying good morning.' },
criteria: 'Use the email tool and send the message to Jim.',
expectedActions: ['email.sendEmail'],
},
];
const result = await assistant.optimize(tasks);
assistant.applyOptimization(result.optimizedProgram!);target defaults to actor optimization.metric defaults to the built-in LLM judge.judgeAI is optional; if omitted, the agent falls back to its configured judge model or runtime model.bootstrap: true is a good next step for tool-heavy agents when you want GEPA to start from successful traces from the provided tasks.criteria.Use this when the task has crisp correctness and cost/behavior tradeoffs:
const result = await assistant.optimize(tasks, {
target: 'actor',
metric: ({ prediction, example }) => {
if (prediction.completionType !== 'final' || !prediction.output) {
return 0;
}
let score = 0;
if (prediction.output.answer.includes('Jim')) score += 0.4;
if (
prediction.functionCalls.some(
(call) => call.qualifiedName === 'email.sendEmail'
)
) {
score += 0.4;
}
if (prediction.turnCount <= 3) {
score += 0.2;
}
return score;
},
});Use this pattern when:
Use this when the agent behavior needs holistic review:
const result = await assistant.optimize(tasks, {
judgeAI,
judgeOptions: {
model: AxAIGoogleGeminiModel.Gemini35Flash,
description:
'Be strict about unnecessary child-agent calls, weak clarifications, and incorrect tool choices.',
},
maxMetricCalls: 12,
});Use this pattern when:
AxGen Judge PatternUse this only when the user needs LLM judging outside the built-in agent.optimize(...) path:
import { AxGen, s } from '@ax-llm/ax';
const judgeGen = new AxGen(
s(`
taskInput:json "Task input",
candidateOutput:json "Candidate output",
expectedOutput?:json "Optional reference output"
->
score:number "Normalized score from 0 to 1"
`)
);
judgeGen.setInstruction(
'Score the candidate output from 0 to 1. Reward correctness and task completion. Return only the score field.'
);
const metric = async ({ prediction, example }) => {
const result = await judgeGen.forward(judgeAI, {
taskInput: example,
candidateOutput: prediction,
expectedOutput: example.expectedOutput,
});
return Math.max(0, Math.min(1, result.score));
};
const result = await optimizer.compile(program, train, metric, {
validationExamples: validation,
});Use this pattern when:
AxGen, flow, or another program directlyagent.optimize(...) wrapperexpectedActions and forbiddenActions when tool correctness matters.judgeOptions mirrors normal forward options and supports extra judge guidance through description.metric, that overrides the built-in judge path.Decision rules:
AxGen evaluator when the user is not calling agent.optimize(...) but still wants LLM judging.judgeOptions.description to steer the judge toward the user's real priority, such as tool correctness, brevity, groundedness, or policy compliance.mcpEvaluation: 'live' is explicit.ax-mcp for recording/replay transport setup and MCP side-effect policy.AxMCPRecordingTransport to capture a real session once and AxMCPReplayTransport for deterministic optimization/evaluation.AxEventRuntime; do not leave a live subscription active in a default
optimization run.agent.optimize(...) runs each evaluation rollout from a clean continuation state.getState() and setState(...) is not used during eval rollouts.askClarification(...) is treated as a scored evaluation outcome instead of going through the responder.prediction.completionType === 'askClarification', populated prediction.clarification, and absent prediction.output.prediction.completionType === 'final' and populated prediction.output.target: 'responder' still works, but clarification-heavy tasks are usually low-signal for responder optimization.functions: [...] for specialist delegation. Their calls appear as normal function-call records.team.writer(...) only after narrowing tool output in JS."result.optimizedProgram if the user wants portable artifacts.new AxOptimizedProgramImpl(...), then call agent.applyOptimization(...).componentMap reapplies the learned strings.AxGen.json tool returns when the agent must reason about specific fields across tool or child-agent calls.If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.