Ax Optimizer Options Explained: How to Use MiPRO, ACE, and GEPA

Ax provides four distinct optimizer classes—MiPRO, ACE, GEPA, and BootstrapFewShot—that inherit from AxBaseOptimizer and offer Bayesian search, agentic playbook refinement, multi-objective evolution, and simple few-shot bootstrapping respectively, all sharing a common configureAuto() and compile() API.

The ax-llm/ax framework ships with a modular optimizer system built on the abstract AxBaseOptimizer class defined in src/ax/dsp/optimizer.js. These Ax optimizer options enable automated prompt engineering through distinct search strategies, from Python-backed Bayesian optimization to evolutionary multi-objective algorithms. Each concrete implementation exposes configuration knobs, auto-presets, and a standardized compilation workflow that transforms raw programs into optimized, high-performance versions.

Overview of Ax Optimizer Architecture

All optimizers in the ax-llm/ax repository extend AxBaseOptimizer. They share a unified lifecycle: instantiation with AxOptimizerArgs, optional preset configuration via configureAuto('light'|'medium'|'heavy'), and execution through compile(program, examples, metricFn, options?).

The four primary implementations differ in their optimization strategies:

  • AxMiPRO: Bayesian search requiring a Python optimizer service
  • AxACE: Agentic context engineering with iterative playbook refinement
  • AxGEPA: Multi-objective evolutionary search using Pareto fronts
  • AxBootstrapFewShot: Lightweight demo generation without search

MiPRO (AxMiPRO): Bayesian Optimization

Located in src/ax/dsp/optimizers/miproV2.ts, MiPRO (Mini Prompt Optimization) performs Bayesian search over instruction candidates, temperature settings, and demonstration counts using an external Python service.

Key Configuration Fields

MiPRO accepts these parameters through its constructor:

  • optimizerEndpoint: Required URL string for the Python optimizer service
  • numCandidates: Number of instruction candidates per round (default: 5)
  • initTemperature: Starting LLM temperature for evaluation (default: 0.7)
  • maxBootstrappedDemos: Upper bound on bootstrapped demonstrations (default: 3)
  • maxLabeledDemos: Upper bound on labeled demonstrations (default: 4)
  • numTrials: Total optimization trials sent to the Python service (default: 30)
  • bayesianOptimization: Enable TPESampler-based search (default: true)
  • earlyStoppingTrials: Stop after non-improving trials (default: 5)
  • minibatchSize: Size of evaluation batches when minibatch mode is enabled (default: 25)

MiPRO Usage Example

import { AxMiPRO, ax, ai } from '@ax-llm/ax';

const llm = ai({ name: 'openai', apiKey: process.env.OPENAI_APIKEY! });

const program = ax(`
  userQuestion:string "User query" ->
  answer:string "Model answer"
`);

const optimizer = new AxMiPRO({
  studentAI: llm,
  optimizerEndpoint: 'https://my-optimizer.example.com/api',
  optimizerTimeout: 30_000,
  optimizerRetries: 2,
});

optimizer.configureAuto('medium');

const result = await optimizer.compile(
  program,
  [{ userQuestion: 'What is the capital of France?' }],
  async ({ prediction }) => (prediction.answer.includes('Paris') ? 1 : 0)
);

console.log('Best score:', result.bestScore);
console.log('Optimized instruction:', result.finalConfiguration.instruction);

ACE (AxACE): Agentic Context Engineering

Defined in src/ax/dsp/optimizers/ace.ts, ACE implements an agentic loop involving a generator, reflector, and curator that iteratively rewrites a structured playbook rather than raw instructions.

ACE Configuration Options

Configure ACE via AxACEOptions:

  • maxEpochs: Full passes over the example set (default: 1)
  • maxReflectorRounds: Reflection iterations per example (default: 2)
  • maxSectionSize: Maximum bullets per playbook section (default: 25)
  • similarityThreshold: Deduplication threshold for playbook bullets (default: 0.95)
  • allowDynamicSections: Permit new section creation on the fly (default: true)
  • initialPlaybook: Optional seed playbook to start optimization

The configureAuto() method maps presets to epoch/round counts: light (1/1), medium (2/2), heavy (3/3).

ACE Usage Example

import { AxACE, ax, ai } from '@ax-llm/ax';

const llm = ai({ name: 'openai', apiKey: process.env.OPENAI_APIKEY! });

const program = ax(`
  emailText:string "Email body" ->
  category:class "spam, important, normal" "Label"
`);

const optimizer = new AxACE({ studentAI: llm });
optimizer.configureAuto('medium');

const result = await optimizer.compile(
  program,
  [
    { emailText: 'Win a free iPhone now!' },
    { emailText: 'Project meeting at 10am' },
  ],
  async ({ prediction }) => (prediction.category === 'spam' ? 0 : 1)
);

console.log('Best score:', result.bestScore);
console.log('Final playbook:', result.playbook);

ACE also supports online adaptation via applyOnlineUpdate({example, prediction, feedback?}) for post-deployment refinement without full recompilation.

GEPA (AxGEPA): Evolutionary Pareto Optimization

GEPA (Generalized Evolutionary Pareto Algorithm), implemented in src/ax/dsp/optimizers/gepa.ts, performs multi-objective evolutionary search maintaining a Pareto front of candidate solutions with reflective mutation and optional program merges.

GEPA Configuration Parameters

  • numTrials: Maximum evolutionary iterations (default: 30)
  • minibatchSize: Evaluation batch size when minibatch mode is active (default: 20)
  • earlyStoppingTrials: Convergence threshold for Pareto front stagnation (default: 5)
  • tieEpsilon: Numerical tolerance for Pareto equality comparisons (default: 0)
  • feedbackMemorySize: Past feedback summaries retained for reflective prompts (default: 4)
  • mergeMax: Upper bound on total program merge attempts (default: 5)
  • sampleCount: Self-consistency samples during candidate evaluation (default: 1)

Auto-presets map to trial/minibatch counts: light (10/15), medium (20/25), heavy (35/35).

GEPA Usage Example

import { AxGEPA, ax, ai } from '@ax-llm/ax';

const llm = ai({ name: 'anthropic', apiKey: process.env.ANTHROPIC_APIKEY! });

const program = ax(`
  question:string "User question" ->
  answer:string "Model answer"
`);

const optimizer = new AxGEPA({
  studentAI: llm,
  numTrials: 40,
  minibatchSize: 30,
  mergeMax: 3,
});
optimizer.configureAuto('heavy');

const result = await optimizer.compile(
  program,
  [
    { question: 'Explain quantum entanglement in simple terms.' },
    { question: 'Summarize the plot of "The Matrix".' },
  ],
  async ({ prediction }) => (prediction.answer.length > 0 ? 1 : 0)
);

console.log('Best Pareto score:', result.bestScore);
console.log('Pareto front length:', result.paretoFront.length);
displayGEPAReport(result.report);

The displayGEPAReport helper renders a human-readable summary of the Pareto front evolution and final candidate selection.

BootstrapFewShot: Lightweight Alternative

For scenarios requiring simple demonstration generation without search overhead, AxBootstrapFewShot (in src/ax/dsp/optimizers/bootstrapFewshot.ts) provides fast few-shot bootstrapping. Key parameters include maxDemos (default: 4), maxRounds (default: 3), and boolean flags for verboseMode and debugMode.

Summary

  • MiPRO requires a Python optimizer endpoint (optimizerEndpoint) and performs Bayesian search over instructions and demonstrations via configureAuto() presets and the TPESampler algorithm.
  • ACE refines structured playbooks through agentic loops with configurable maxEpochs and maxReflectorRounds, supporting online updates via applyOnlineUpdate().
  • GEPA maintains Pareto fronts for multi-objective optimization using evolutionary search with mergeMax program merges and minibatch evaluation, producing detailed reports via displayGEPAReport.
  • All optimizers inherit from AxBaseOptimizer in src/ax/dsp/optimizer.js and return rich result objects containing optimized programs, best scores, and configuration artifacts through the standardized compile() method.

Frequently Asked Questions

What is the difference between MiPRO and ACE optimizers in Ax?

MiPRO performs Bayesian optimization over prompt parameters using an external Python service, making it suitable for heavy-duty prompt engineering with numerical search over temperatures and demo counts. ACE uses an agentic, rule-based approach to iteratively rewrite a structured playbook through generator-reflector-curator loops, better suited for structured guideline refinement without requiring external services.

Do I need a Python service to run GEPA or ACE optimizers?

No. Only MiPRO requires the optimizerEndpoint pointing to a Python optimizer service as implemented in src/ax/dsp/optimizers/pythonOptimizerClient.ts. Both ACE and GEPA run entirely within the TypeScript/JavaScript runtime using the studentAI LLM instance provided in their constructors.

How do I choose between light, medium, and heavy presets in Ax optimizers?

Light presets minimize computational cost with fewer trials (10-20) and smaller minibatches, ideal for rapid prototyping. Medium presets balance thoroughness and speed (20-30 trials), while heavy presets maximize optimization quality with 35+ trials and larger minibatches, recommended for production deployments where latency is less critical than performance.

Can I use multiple metrics with Ax optimizers?

GEPA explicitly supports multi-objective optimization via Pareto fronts, allowing simultaneous optimization of competing metrics like accuracy and verbosity. MiPRO and ACE typically optimize a single metric function, though you can combine multiple factors into a composite metric for these optimizers.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →