04 — Agentic analytics¶
Archived page
This page was written for an earlier version of ZLens and may not match the current product. See About the archive for the current page.
Who this is for: anyone who wants AI to answer data questions from governed blocks, not from improvised SQL.
What you'll do: build the local knowledge graph, ask questions through the agent, watch the graduated-trust model route between certified blocks and flagged proposals, promote a good proposal to a certified block, generate a local App package from a prompt, and connect the MCP server so Claude/Cursor can do the same.
Time: 25 minutes.
Setup: continues from 03 — Dashboards & Apps. You'll need one LLM provider:
ANTHROPIC_API_KEY,OPENAI_API_KEY,GEMINI_API_KEY, or a local Ollama daemon (ollama pull llama3.1). Keys can also be set in the notebook's Settings page; they're stored locally with0600permissions.
The graduated-trust model¶
The agent never silently invents SQL. Every answer is routed through tiers:
| Tier | Source | Label |
|---|---|---|
| 1 | A certified DQL artifact exactly matches the question: executable blocks for direct KPI/saved-block answers, or business terms/views for definition and context answers | ✓ Certified |
| 2 | No exact match, or the user asks for a named entity, custom filter, ranking, breakdown, comparison, drill-through, or different grain — the agent proposes SQL grounded in business context, dbt, semantic metadata, and runtime schema, saved as a draft | ⚠ Uncertified |
| 3 | Not answerable from the project | Refusal, with what's missing |
Tier-2 drafts land in domains/<domain>/blocks/_drafts/ in domain-first
projects, or blocks/_drafts/ in legacy projects, so popular questions become
candidates for certification — that's the promotion loop.
Follow-up questions keep the same trust model. If a user asks "drill into Enterprise last week" after a certified revenue answer, the agent uses the prior answer as context, searches for a distinct certified drilldown block first, and only then creates a review-ready draft. It does not silently reuse the top-level block or mark generated drilldown SQL as certified.
The same rule applies to single-customer or single-user questions. A certified
total_revenue block can ground the business meaning of revenue, but a question
like "what is revenue for Alice Johnson?" is a custom filter and should produce
review-required SQL unless a certified block already covers that exact grain.
Step 1 — Build the knowledge graph¶
zlens agent reindex
You should see a node/edge count — your business terms, business views, certified blocks, dbt models, metrics, and dimensions indexed into a local SQLite FTS5 knowledge graph at
.dql/cache/agent-kg.sqlite. Nothing leaves your machine except the LLM calls you configure.
Step 2 — Ask a question that hits a certified block¶
zlens agent ask "how has revenue trended by month?"
You should see
✓ Certified Answered from block: revenue_by_month (revenue · certified)followed by the result rows. The
llmContext,examples, attachedterms, and relatedbusiness_viewcontext you wrote earlier are what made retrieval land.
Inspect the routing decision:
zlens agent ask "how has revenue trended by month?" --format json | jq '.kind'
You should see
"certified".
Step 3 — Ask something no block covers¶
zlens agent ask "what share of orders are food vs drink?"
You should see the answer clearly labelled Uncertified: the LLM proposed SQL against the dbt
ordersmart (is_food_order/is_drink_order), and the proposal was saved as a review draft.
List accumulated proposals:
find domains blocks -path "*/_drafts/*.dql" 2>/dev/null
Questions that get asked repeatedly accumulate in _drafts/ — that's your
prioritized review queue for what to certify next.
When several certified blocks repeat the same metric expression or filtered
definition, the local runtime can propose a semantic-layer composting changeset:
draft metric YAML under semantic-layer/metrics/_drafts/ plus a PR-body summary
with the donor blocks that proved the pattern. The preview endpoint is
read-only (/api/propose/composting); the generate endpoint writes only selected
candidate ids (/api/propose/composting/generate). These drafts are still
human-reviewed and start with status: draft.
Measure the follow-up path with an eval suite:
zlens agent eval docs/guides/agent-evals.yml --format json
You should see certified hit rate, generated follow-up pass rate, safe refusal rate, wrong-certified count, draft capture count, and context size metrics. JSON output also includes a per-case trace for context selection, follow-up rewrite/carry, lane routing, validation, execution, draft capture, and scoring. Add
--executewhen a local runtime is running and you want bounded SQL previews compared against expected rows. Add--savewhen eval-generated drafts should be written to the local draft queue; otherwise eval reports the draft path without mutating the project. For tool-observed flows, addexpected.minToolCallsto a case so a deep/research eval fails when the provider loop returns without using the governed tools; use--min-tool-requirement 1to make those tool-observation cases a hard gate.
Step 4 — Promote a good proposal to a certified block¶
Review the draft like any code: open it in Block Studio, fix the SQL if
needed, add owner, llmContext, and tests, then run it through the same
gate as tutorial 02:
zlens certify --from-draft domains/<domain>/blocks/_drafts/<draft-file>.dql
You should see the rule table go green and the block land in the domain block folder as
certified. Re-runzlens agent reindex, ask the same question again, and the answer is now ✓ Certified — the loop is closed.
Feedback tunes retrieval over time:
zlens agent feedback up --question "monthly revenue" --block "block:revenue_by_month"
Follow-up drilldowns use the same loop:
zlens agent ask "drill into Enterprise last week"
You should see either a certified drilldown block, if one exists, or an Uncertified draft proposal tagged for review. Repeated drilldown asks make the draft a stronger certification candidate.
Step 5 — Generate a local App from a prompt¶
The OSS app builder writes reviewable files. It does not generate hidden React or bypass certification state:
zlens app generate "Build a weekly revenue health app for the COO"
You should see an
apps/<app-id>/package with:
dql.app.jsondashboards/overview.dqldREADME.md
Certified blocks become certified dashboard tiles. Missing or AI-created sections become text/draft placeholders with review tasks, so the generated App is useful immediately but still safe for Git review.
Build the App manifest after review:
zlens app build
Step 6 — Connect an external AI agent¶
The same graduated-trust loop is exposed to any MCP client (Claude Code, Claude Desktop, Cursor, Codex):
zlens mcp test
zlens connect claude-code
# or: zlens connect codex
# or: zlens connect all
zlens connect claude-code writes project-local .mcp.json plus CLAUDE.md.
zlens connect codex writes project-local .codex/config.toml plus AGENTS.md.
Full setup for every client is in Connect an AI agent (MCP).
The server exposes workflow tools such as inspect_dql_project, ask_dql,
query_via_block, query_via_metadata, build_dql_block, and
build_dql_app. Ask your agent a revenue question and it answers from your
certified blocks when the block grain fits, citing them — and files drafts
when it has to generate a deeper or different-grain answer.
What you now have¶
✓ A local knowledge graph over blocks, dbt models, and metrics ✓ Agent answers that are certified-first, flagged when improvised ✓ The promotion loop: draft → review → certify → re-ask → certified ✓ A local generated App package with certified tiles and draft review tasks ✓ An MCP server giving Claude, Codex, Cursor, and other agents governed access to your analytics