Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Use this skill when writing or reviewing Ax bestOfN/refine code, reward functions, thresholds, native sample selection, serial attempts, generated advice, and attempt diagnostics.
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-09 | ✗→✓ | ▲ Improved | -30% | 0% |
| case-01 | ✗→✓ | ▲ Improved | -7% | 0% |
| case-02 | ✗→✓ | ▲ Improved | -26% | 0% |
| case-08 | ✗→✓ | ▲ Improved | 2% | 0% |
| case-03 | ✗→✓ | ▲ Improved | -21% | 0% |
Use bestOfN(...) when you can score complete outputs independently. Use refine(...) when failed rounds should produce feedback that changes the next attempt.
Keep reward scoring, whole-output assertions, and streaming assertions separate:
addAssert(...) for whole-output hard invariants. Failed assertions feed correction text into the normal retry loop.addStreamingAssert(...) for partial streaming hard invariants. It aborts the current stream attempt as soon as the partial field fails, then feeds correction text into the normal retry loop.bestOfN(...) for complete-candidate selection.refine(...) for reward-scored retry rounds with generated feedback.typescriptimport { bestOfN, refine } from '@ax-llm/ax'; const selected = bestOfN(program, { n: 4, threshold: 0.8, rewardFn: ({ input, prediction, traces, chatLog }) => score(prediction), }); const improved = refine(program, { rounds: 3, samplesPerRound: 2, threshold: 0.85, rewardDescription: 'Prefer complete, grounded, concise answers.', rewardFn: ({ prediction }) => score(prediction), });
Rules:
forward(...) returns the selected prediction.streamingForward(...) is unsupported; score complete outputs instead.getUsage() aggregates usage across attempts.getTraces() and getChatLog() return the selected attempt's diagnostics.getAttempts() returns all attempt metadata, including reward, errors, and advice application.Reward functions return a number. Higher is better. A threshold marks a good-enough candidate and can stop serial attempts early.
typescriptconst rewardFn = ({ prediction }) => { const exact = prediction.answer === 'Paris' ? 1 : 0; const concise = prediction.answer.length < 80 ? 0.2 : 0; return exact + concise; };
Use serial strategy when the reward needs traces, chat logs, tools, or full flow behavior.
strategy: "auto" uses native samples for AxGen and serial attempts for composite programs.strategy: "native-samples" uses sampleCount and a reward-backed resultPicker; candidate context includes outputs, not full per-candidate traces.strategy: "serial" runs isolated full-program attempts with fresh memory/session IDs.refine(...) generates advice after a below-threshold round. Advice is appended temporarily to matching kind: "instruction" components exposed by getOptimizableComponents() and applied through applyOptimizedComponents().
Rules:
finally, on success and error.adviceApplied: false.hint_ signature fields; Ax uses instruction-component advice.Do not use refine(...) for streaming. For partial-output safety, use addStreamingAssert(fieldName, fn, message?) on AxGen. Streaming assertions fail fast within the current attempt with AxStreamingAssertionError, then retry with correction feedback when retries remain.
Other measured skills in the registry, with their headline benchmark lift.