Skip to content
Browse documentation
Analysis & visualization

Analysis strategies

Choose direct queries, iterative reasoning, or selected profile context.

Choose how AVA turns a question into an answer: a direct query, a reasoning loop, or analysis with selected profile context. The examples assume ava already has a loaded source, as shown in Analyze data.

Choose a strategy

Choose a strategy per analyze() call:

StrategyWhat it doesWhen to use it
directGenerate a query, execute it, and optionally summarize. Can retry failed execution with a corrected query.Start here for a focused question.
loopExplore, reason, and execute queries over multiple steps before returning an answer.Questions that benefit from intermediate exploration.
subsetKeep the full schema, select relevant profile statistics, then run direct analysis.Focus a large profile on the question.

Strategy options

All strategy inputs are nested under config.strategy:

FieldTypeRequiredDefault / behavior
type'direct', 'loop', or 'subset'When strategy is providedSelects the strategy.
maxRetriesnumberNo; direct only2 correction retries after the first attempt when type: 'direct' is explicit.
maxStepsnumberNo; loop only12 normal reasoning steps.

Direct

Generate a query from the question and data context, execute it, then optionally summarize the returned data. Only failed execution enters the correction loop.

Direct: generate and execute a query. On execution failure, feed the failed query and error back into generation while correction retries remain; otherwise throw. On success, optionally summarize and return the result.
typescript
const result = await ava.analyze('What is total revenue by region?', {
  strategy: { type: 'direct', maxRetries: 2 },
});

With this configuration, a failed execution can be corrected twice after the initial attempt. In the current implementation, omitting strategy entirely follows the direct path with 10 correction retries. Set it explicitly for a predictable budget. Model API retries are separately controlled by llm.maxRetries (default 3).

Query-generation and summary failures propagate to the caller; they do not restart the execution correction loop. With includeSummary: false, the result's text is an empty string.

Loop

The model chooses one action at each step using the question, data context, and accumulated history. Exploration is optional: it can go straight to an answer query when it has enough information.

Loop: choose and perform an action. CONFIRM with a successful answer returns the result. Otherwise, record observations and repeat while steps remain. At the limit, return an available answer; if none exists, generate and execute one final query, returning its result or throwing an error.
ActionWhat happensWhat happens next
EXPLOREExecute one or more exploratory queries to check values, formats, or relationships.Add results or execution errors to the history for the next step.
REFINERevise the understanding and plan without executing a query.Add the plan to the history and take another step.
SQLExecute one candidate answer query in the engine's language.Save the successful result, or record the execution error so a later step can correct it.
CONFIRMVerify that the executed answer addresses the question.Return the saved result if one exists; otherwise continue the loop.

SQL is the action tag even when the engine executes a language other than SQL. These actions are choices, not a fixed four-step sequence.

typescript
const result = await ava.analyze('Compare regional revenue and explain the differences', {
  strategy: { type: 'loop', maxSteps: 6 },
});

maxSteps limits normal reasoning steps. At the limit, AVA returns an available successful answer without requiring another CONFIRM. If no successful answer is available, it makes one additional query-generation and execution attempt using the full history. This final attempt returns directly on success and throws on failure.

Execution errors inside the normal loop become feedback for the next step. Model-call failures and invalid action responses stop the analysis instead. Model API retries still follow llm.maxRetries, so maxSteps is not a strict count of all model calls.

On the usual CONFIRM path, text contains the verification and conclusion. At the step limit or after the final attempt, it uses an earlier confirmation if present, otherwise the result data serialized as JSON. includeSummary: false always leaves text empty; Loop does not run a separate summarization call.

Subset

Select the profile statistics relevant to the question before running Direct analysis. This reduces the statistical context sent to query generation; it does not remove tables or fields from the schema or filter the underlying data.

Subset: reuse or compute a profile. If available, select relevant table and field statistics while preserving the full schema. Keep all profile details if nothing is selected, or use the original context if no profile exists. Then run Direct analysis.
typescript
const result = await ava.analyze('What is total revenue by region?', {
  strategy: { type: 'subset' },
});

Subset uses an existing profile or computes one if the engine supports it. It selects profile details while preserving the complete schema. Without a profile it keeps the original context; if nothing is selected, it keeps all profile details. There are no additional subset configuration fields.

An empty schema, a profiling failure, or a selector failure stops analysis; those errors do not fall back to Direct. Once selection succeeds, the current implementation uses Direct with 10 execution correction retries and the same optional summary behavior.