PT EN
Back to site

Architecture — Copilot and LLM

DATTA's AI is not a separate screen: it is embedded where the work happens — suggesting the formula while you edit a chart, answering questions about the dashboard you have open, writing the report narrative, pointing out what deserves attention before you ask, and processing entire columns inside your pipelines. This page describes how those four surfaces are assembled, what each one sends to the model, where the cache sits and which limits protect the platform.


1. The pieces

RoleWhat it does
Conversation proxyStreams the answer (SSE) between the frontend and the model, builds the context, manages the session and dispatches tool calls
Model managementModel catalog (Qwen3, DeepSeek, the active model, Gemini as the alternative), health checks and routing
Model access layerUnifies access to the local vLLM and to the cloud alternative behind an OpenAI-style API
Dashboard orchestrationBuilds the panel's context, applies the usage limit, generates the narrative and produces the proactive suggestions
Vector generationLocal embeddings with the active model, used by RAG
Prompt repositoryPrompts versioned by purpose and by context

When each surface comes in

SituationSurfaceWhat it sees
I am editing a chart and cannot recall the measure syntaxDATTAX.AI barThe chart's current DATTAX and the dataset schema
The dashboard is published and I want to understand a numberDashboard copilot ("Perguntar ao dashboard")The data actually rendered in that panel's charts
I want a question answered from the ingested documentsChatThe excerpts retrieved by semantic search in the indices
I need to classify or extract fields from thousands of rowsDATTAX AI primitivesThe column processed in batches, inside the pipeline

2. Edit-time copilot (DATTAX.AI bar)

The analyst edits a chart, types "add percentage vs previous year" in the bar, and the platform:

  1. Builds the prompt with the chart's current DATTAX, the dataset schema and the described intent.
  2. Forwards it to model routing, which resolves to the local vLLM.
  3. Receives the suggested DATTAX.
  4. Shows the difference side by side — the user is the one who accepts or rejects.

The system prompt is blunt: "Você é um assistente DATTAX. Retorne SOMENTE DATTAX válido. Não inclua markdown." ("You are a DATTAX assistant. Return ONLY valid DATTAX. Do not include markdown."), followed by the schema context.

The design foresees validating the output before it reaches the screen, failing with a message in Portuguese when the model returns something invalid. That validator is not implemented yet — it is design intent recorded for phase F10. Today the effective protection is the diff itself: nothing enters the chart without the user's explicit acceptance.


3. Dashboard copilot ("Perguntar ao dashboard")

The flow

  1. The user opens a published dashboard and the copilot appears in the top bar.
  2. They type the question — "Which region grew the most in Q1?".
  3. Before anything else, the platform validates access: an IDOR guard denies the question if the user is not the dashboard's owner, has no share and presents no valid public token.
  4. The usage limit is consumed: 20 questions per minute and 200 per hour, per user.
  5. The context is assembled: for each chart, the platform takes the last cached render (datta:dattabi:chart:<id>:render) or forces a fresh one, and concatenates the metadata (title, type, DATTAX) with a data sample of up to 1 KB per chart.
  6. The final prompt has the shape Pergunta: … followed by Contexto: with the assembled JSON, and the answer is streamed back.
  7. If the model calls the dattax.execute tool, the query runs in the DATTAX engine and the result goes back to the model to compose the answer.

The tools exposed to the model

ToolWhat it does
dattax.execute(script)Runs DATTAX and returns JSON
catalog.search(query)Searches metadata in the platform catalog
explain.chart(chartId)Explains how that chart was generated

Every tool has a documented JSON schema; models with function-calling support can invoke them.

Cache and limits

  • Dashboard context: datta:dattabi:copilot:ctx:<dashboardId>, 2-minute TTL.
  • Usage limit: datta:dattabi:copilot:rl:<user>:min and :hour.

4. Executive narrative

When it runs: on PDF export with the narrative option checked (includeNarrative=true).

Available styles:

StyleWhat it produces
executivaBrief overview, focused on the indicators
tecnicaPer-chart detail, correlations
storytellingNarrative prose with chained recommendations

Each style has its own system prompt in the prompt repository. The narrative is cached under datta:dattabi:dashboard:narrative:<dashId>:<style>:<hash>, where the hash is the content of the renders — refreshing the data therefore invalidates the narrative automatically.

If AI is unavailable, the PDF comes out without the narrative, along with an explanatory message. The report never gets stuck.


5. Proactive suggestions

When the dashboard opens, the platform fires an asynchronous analysis looking for outliers, trends and correlations. When the finding passes the configured threshold, the model is called only to phrase it in natural Portuguese, in the "did you know that…?" spirit, and the suggestion shows up in the top bar.

The result is cached under datta:dattabi:dashboard:suggestions:<dashId>:<hash> and the user can dismiss the suggestion permanently for that dashboard.


6. AI primitives in DATTAX

Executed inside the DATTAX engine, they process entire columns in the pipeline:

LLM EXTRACT FROM <col> INTO {schema}    -- schema-driven extraction
LLM CLASSIFY FROM <col> LABELS [...]    -- multi-label classification
LLM EMBED FROM <col> MODEL "..."        -- embedding generation

How the executor behaves

  • Processes in batches of N rows per request (default 20).
  • 30-second timeout per batch.
  • Exponential retry on 429 and 5xx.
  • Validates the response against the schema before injecting it into the result.
  • Reuses already-computed answers through the datta:dattax:llm:<primitive>:<hash> cache, keyed by the text hash plus the model — the same text is never paid for twice.

Quotas

AI consumption has a daily and monthly limit per user, checked before execution. Costs accumulate in the platform cache and the administrative quota panel shows the breakdown per user.


7. Local vLLM and the cloud alternative

Local stack: the default models are Qwen3-30B-A3B-Instruct and DeepSeek-Coder-V2-Lite, plus the active embedding model. The deployment uses GPUs when available, or CPU only for the smaller models, and exposes an OpenAI-compatible endpoint at http://vllm:8000/v1.

Cloud alternative: GEMINI_API_KEY or OPENAI_API_KEY, kept as an installation secret — always optional. The model access layer picks the destination by three criteria:

  1. availability of the local model;
  2. the administrator's preference (per tenant);
  3. failure — which triggers the alternative.

Architecture requirement (Project Guidelines §6): the platform must work with empty cloud keys.


8. RAG in chat

For the main Chat — not for the dashboard copilot:

  • The platform generates embeddings of the documents and the queries with the active model.
  • Retrieval is by vector search (KNN) in the datta-rag-docs index.
  • The top-K retrieved excerpts are injected into the prompt.
  • A tool lets the model fetch catalog metadata.

The dashboard copilot does not use external RAG: its context is strictly the open panel's. That is a scoping decision, not a temporary limitation.


9. Observability

MetricWhat it measures
datta_chat_stream_duration_secondsConversation streaming duration (p50/p95/p99)
datta_llm_tokens_generated_totalTokens generated
datta_llm_quota_exceeded_totalQuota overruns
datta_dattabi_copilot_requests_totalCopilot requests, per endpoint

Audit events: COPILOT.ASK, COPILOT.NARRATIVE and LLM.QUOTA_EXCEEDED. Distributed tracing covers the whole chain — one span per request, from the click to the model call.


10. Security

  • IDOR: the dashboard access guard runs on every copilot interaction, no exception.
  • Personal data: the prompt instructs the model to refuse fields marked pii=true.
  • Prompt injection: input is sanitized before reaching the model (<|…|>-style markers are removed).
  • Usage limit: per user, on the interactive surfaces and in the pipeline quotas.
  • Audit: every interaction is recorded.

Details in platform security.


11. References

  • DATTA BI user guide, Copilot section: DATTABI — User Guide.
  • Conversation, model and copilot endpoints: API reference.