Ask Explore in plain English
Source of truth:
sigmatic/docs/explore-plain-english.md(synced at build time — edit the original, not this copy). Explore can write a filter query for you from a question such as “failed logins for admin accounts in the last hour”. You check the query, change it if you need to, and run it yourself. The design is shared with VectorFlow’s lake and recorded in Veltro ADR-017.
Before you start
Section titled “Before you start”- An AI provider has to be configured and switched on in Settings > AI. Without one the box doesn’t appear. A local Ollama model works, so air-gapped installs can use it.
- The provider’s allowed data classes must include
events. The prompt carries your data source’s field names, and those come from indexed logs, so Sigmatic treats them as event data, the same as field-mapping suggestions. - Pick one data source. With “All visible” selected the box is disabled, because the question needs one set of field names.
Asking
Section titled “Asking”- Open Explore and pick a data source.
- Type your question in Ask in plain English and press Write query.
- The filters and time range appear in the normal Explore controls, in filter mode. Nothing has run yet.
- Read the notice above them. It says the query came from AI, and it calls out any filter that leaves events out (
not equals,does not exist) and any time range shorter than the one you had, including a filter on one of the data source’s date fields such as@timestamp. Those are the changes most likely to hide what you’re looking for. The notice stays up until you dismiss it or ask again, even if the next question is refused. If you switch data source while a question is pending, its answer is dropped, because it was written for the other source’s fields. - Edit anything you like, then press Run.
The query runs through the same path as one you build by hand, with the same team scope, row cap and timeout.
What the model sees
Section titled “What the model sees”The prompt holds your question, up to 300 field names from the data source’s mapping (field mapping targets first), the current time and the time range you have selected. It never holds log lines, field values or counts. Field names and the question are marked as untrusted data in the prompt.
The selected time range comes from the page URL, so Sigmatic checks it before it goes in the prompt. It has to be a duration such as 24h or 7d, or two dates with the start before the end. Anything else is refused with ai_page_time_range_invalid. Pick a range from the time controls and ask again.
The model can only answer with filter clauses and a time range. Sigmatic refuses anything else before you see it:
- a field that isn’t in the data source’s mapping
- an operator outside Explore’s list, or a value that doesn’t fit it (an
inlist of more than 50 values, a value over 512 characters, an invalid network forcidr) - more than 25 filters, or more than 5
containsorends withfilters - a time range longer than 90 days or in the future
- any extra key, such as an index, a data source, a query string or PPL
A refusal shows a short reason, and you can rephrase.
Audit and limits
Section titled “Audit and limits”Every question writes an ai_copilot.explore_query row to the audit log with your question (secrets redacted), the provider, the model and the query that came back. A refused question writes an ai_copilot.explore_query_refused row instead, with your question, the provider, the model and the refusal code. That includes refusals before the provider is called (AI switched off, events not allowed, the rate limit) and provider errors. Anyone who can read the audit log can read these rows, so don’t paste secrets into a question. The provider call itself writes the usual ai.invocation row, which holds digests only.
When you run a generated query, its explore.query audit row records nl_outcome: accepted if you ran it unchanged, edited if you changed it first, unverified if Sigmatic can’t find that generation for you in the last day. Sigmatic compares the query it would actually send, so a renamed time key or an extra space counts as a change. Each outcome is recorded once per generation; running the same query again keeps the generation id but leaves nl_outcome out.
Each user can ask 20 questions per 10 minutes, and the whole install 200. Past that, Explore returns ai_rate_limited and says when to try again.
Measuring accuracy
Section titled “Measuring accuracy”backend/evals/explore_nl_query.json holds 31 questions with the query we expect. Run them against a provider with:
cd backendSIGMATIC_EVAL_AI_PROVIDER=ollama \SIGMATIC_EVAL_AI_BASE_URL=http://127.0.0.1:11434 \SIGMATIC_EVAL_AI_MODEL=qwen2.5:7b \python scripts/eval_explore_nl_query.py --json results.jsonopenai_compatible and anthropic read the key from SIGMATIC_EVAL_AI_API_KEY_FILE. The script prints each case and the accuracy. It isn’t part of CI.