Skip to content

Commit cfbae68

Browse files
committed
feat: add sql_snippets, join_specs, and benchmark accuracy improvements
- Add genie_sql_filters, genie_sql_measures, genie_sql_expressions, and genie_join_specs to serialized_space for better Genie SQL generation - Update ABAC_PROMPT.md with unambiguous benchmark rules, business default instructions, and domain-adaptive generation guidance - Use two-step create-then-patch for Genie Space (CREATE endpoint doesn't support sql_snippets/join_specs) - Restructure TUNING.md to prioritize Genie accuracy review checklist - Increase Databricks FMAPI timeout to 600s for larger prompt responses - Remove abac.auto.tfvars from make setup (generated by make generate) Made-with: Cursor
1 parent 422cb22 commit cfbae68

11 files changed

Lines changed: 779 additions & 402 deletions

File tree

uc-quickstart/utils/genie/aws/ABAC_PROMPT.md

Lines changed: 83 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -228,40 +228,111 @@ Violating any of these causes validation failures. Double-check consistency acro
228228
6. Select masking functions from the library above (or create new ones)
229229
7. Generate both output files. For entity names in tag_assignments, always use **fully qualified** names (`catalog.schema.table` or `catalog.schema.table.column`). For function_name in fgac_policies, use relative names only (e.g. `mask_pii`). Every fgac_policy MUST include `catalog`, `function_catalog`, and `function_schema`. **CRITICAL**: set `function_schema` to the schema where the tagged columns actually live — do NOT default all policies to the first schema. In `masking_functions.sql`, group the `CREATE FUNCTION` statements by schema with separate `USE SCHEMA` blocks. Only create each function in the schema where it is needed
230230
8. Every `match_condition` and `when_condition` MUST only use `hasTagValue()` and/or `hasTag()` — no other functions or operators
231-
9. Generate Genie Space config — all five fields below. Tailor everything to the user's actual tables, domain, and business context:
232-
- `genie_space_title` — a concise, descriptive title (e.g., "Financial Compliance Analytics", "Clinical Data Explorer")
231+
9. Generate Genie Space config — all nine fields below. **Derive everything from the user's actual tables, columns, and domain** — do NOT copy the finance/healthcare examples below if the user's data is from a different industry. Adapt terminology, metrics, filters, and joins to whatever vertical the tables belong to (retail, manufacturing, telecom, education, logistics, etc.):
232+
- `genie_space_title` — a concise, descriptive title reflecting the user's domain (e.g., finance → "Financial Compliance Analytics", retail → "Retail Sales & Inventory Explorer", telecom → "Network Performance Dashboard")
233233
- `genie_space_description` — 1–2 sentence summary of what the space covers and who it's for
234-
- `genie_sample_questions` — 5–10 natural-language questions a business user would ask (shown as conversation starters in the UI)
235-
- `genie_instructions` — domain-specific guidance for the Genie LLM (e.g., how to calculate metrics, date conventions, terminology, masking behaviour awareness)
236-
- `genie_benchmarks` — 3–5 benchmark questions with ground-truth SQL for evaluating accuracy
234+
- `genie_sample_questions` — 5–10 natural-language questions a business user in that domain would ask (shown as conversation starters in the UI). Must reference the user's actual table/column names.
235+
- `genie_instructions` — domain-specific guidance for the Genie LLM. **Must include business defaults** — look at status/state columns in the user's tables and define which values are the default filter (e.g., if a table has `OrderStatus` with values like 'Fulfilled'/'Cancelled'/'Pending', instruct: "default to fulfilled orders"). Also cover date conventions, metric calculations, terminology, and masking awareness relevant to the user's domain.
236+
- `genie_benchmarks` — 3–5 benchmark questions with ground-truth SQL. **Each question must be unambiguous and self-contained** — include explicit qualifiers so the question and SQL agree on scope (e.g., "What is the average risk score for active customers?" not "What is the average customer risk score?"). Avoid questions that could reasonably be interpreted with different WHERE clauses.
237+
- `genie_sql_filters` — default WHERE clauses derived from the user's status/state columns (e.g., active records, completed transactions, open orders). Each filter has `sql`, `display_name`, `comment`, and `instruction`.
238+
- `genie_sql_measures` — standard aggregate metrics derived from the user's numeric columns (e.g., sums, averages, counts that are meaningful in the domain). Each measure has `alias`, `sql`, `display_name`, `comment`, and `instruction`.
239+
- `genie_sql_expressions` — computed dimensions derived from the user's date/category columns (e.g., year extraction, bucketing, status grouping). Each expression has `alias`, `sql`, `display_name`, `comment`, and `instruction`.
240+
- `genie_join_specs` — relationships between the user's tables based on foreign key columns (look for matching ID columns like `CustomerID`, `OrderID`, `ProductID`). Each join has `left_table`, `left_alias`, `right_table`, `right_alias`, `sql`, `comment`, and `instruction`.
237241

238242
### Output Format — Genie Space Config (in `abac.auto.tfvars`)
239243

240-
Include these variables alongside groups, tag_policies, etc.:
244+
Include these variables alongside groups, tag_policies, etc. The example below shows a **finance/healthcare** scenario — adapt all values to match the user's actual tables and industry:
241245

242246
```hcl
243247
genie_space_title = "Financial & Clinical Analytics"
244248
genie_space_description = "Explore transaction data, patient encounters, and compliance metrics. Designed for analysts, compliance officers, and clinical staff."
245249
246250
genie_sample_questions = [
247251
"What is the total revenue by region for last quarter?",
248-
"Show the top 10 customers by transaction volume",
252+
"Show the top 10 active customers by transaction volume",
249253
"Which accounts have been flagged for AML review?",
250254
"How many patient encounters occurred last month?",
251-
"What is the average transaction amount by account type?",
255+
"What is the average completed transaction amount by account type?",
252256
]
253257
254-
genie_instructions = "When calculating revenue, sum the Amount column. 'Last month' means the previous calendar month (not last 30 days). Round monetary values to 2 decimal places. Patient names are masked for non-clinical roles — queries about patient counts or encounter dates are always allowed."
258+
genie_instructions = "When asked about 'customers' without a status qualifier, default to active customers (CustomerStatus = 'Active'). When asked about 'transactions' without specifying status, default to completed transactions (TransactionStatus = 'Completed'). 'Last month' means the previous calendar month (not last 30 days). Round monetary values to 2 decimal places. Patient names are masked for non-clinical roles — queries about patient counts or encounter dates are always allowed."
255259
256260
genie_benchmarks = [
257261
{
258-
question = "What is the total transaction amount?"
259-
sql = "SELECT SUM(Amount) as total_amount FROM catalog.schema.transactions"
262+
question = "What is the total amount of completed transactions?"
263+
sql = "SELECT SUM(Amount) as total_amount FROM catalog.schema.transactions WHERE TransactionStatus = 'Completed'"
260264
},
261265
{
262-
question = "How many patients were seen last month?"
266+
question = "How many patient encounters occurred last month?"
263267
sql = "SELECT COUNT(*) FROM catalog.schema.encounters WHERE EncounterDate >= DATE_TRUNC('month', CURRENT_DATE - INTERVAL 1 MONTH) AND EncounterDate < DATE_TRUNC('month', CURRENT_DATE)"
264268
},
269+
{
270+
question = "What is the average risk score for active customers?"
271+
sql = "SELECT AVG(RiskScore) as avg_risk_score FROM catalog.schema.customers WHERE CustomerStatus = 'Active'"
272+
},
273+
]
274+
275+
genie_sql_filters = [
276+
{
277+
sql = "customers.CustomerStatus = 'Active'"
278+
display_name = "active customers"
279+
comment = "Only include customers with Active status"
280+
instruction = "Apply when the user asks about customers without specifying a status"
281+
},
282+
{
283+
sql = "transactions.TransactionStatus = 'Completed'"
284+
display_name = "completed transactions"
285+
comment = "Only include completed transactions"
286+
instruction = "Apply when the user asks about transactions or amounts without specifying a status"
287+
},
288+
]
289+
290+
genie_sql_measures = [
291+
{
292+
alias = "total_revenue"
293+
sql = "SUM(transactions.Amount)"
294+
display_name = "total revenue"
295+
comment = "Sum of all transaction amounts"
296+
instruction = "Use for revenue, total amount, or sales calculations"
297+
},
298+
{
299+
alias = "avg_risk_score"
300+
sql = "AVG(customers.RiskScore)"
301+
display_name = "average risk score"
302+
comment = "Average AML risk score across customers"
303+
instruction = "Use when asked about risk scores or risk averages"
304+
},
305+
]
306+
307+
genie_sql_expressions = [
308+
{
309+
alias = "transaction_year"
310+
sql = "YEAR(transactions.TransactionDate)"
311+
display_name = "transaction year"
312+
comment = "Extracts year from transaction date"
313+
instruction = "Use for year-over-year analysis of transactions"
314+
},
315+
]
316+
317+
genie_join_specs = [
318+
{
319+
left_table = "catalog.schema.accounts"
320+
left_alias = "accounts"
321+
right_table = "catalog.schema.customers"
322+
right_alias = "customers"
323+
sql = "accounts.CustomerID = customers.CustomerID"
324+
comment = "Join accounts to customers on CustomerID"
325+
instruction = "Use when you need customer details for account queries"
326+
},
327+
{
328+
left_table = "catalog.schema.transactions"
329+
left_alias = "transactions"
330+
right_table = "catalog.schema.accounts"
331+
right_alias = "accounts"
332+
sql = "transactions.AccountID = accounts.AccountID"
333+
comment = "Join transactions to accounts on AccountID"
334+
instruction = "Use when you need account or customer context for transactions"
335+
},
265336
]
266337
```
267338

uc-quickstart/utils/genie/aws/Makefile

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,6 @@ setup: ## Copy example files and prompt for credentials
1919
else \
2020
echo "env.auto.tfvars already exists — skipping."; \
2121
fi
22-
@if [ ! -f abac.auto.tfvars ]; then \
23-
cp abac.auto.tfvars.example abac.auto.tfvars; \
24-
echo "Created abac.auto.tfvars — edit it with your ABAC config."; \
25-
else \
26-
echo "abac.auto.tfvars already exists — skipping."; \
27-
fi
2822
@mkdir -p ddl generated
2923
@echo "Created ddl/ and generated/ directories."
3024
@echo ""

uc-quickstart/utils/genie/aws/README.md

Lines changed: 26 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# OneReady — Genie Onboarding Quickstart
22

3-
Get your workspace **OneReady** for Genie in Databricks One. An AI-powered Terraform quickstart that automates business-user onboarding — from ABAC governance and masking functions to a fully configured Genie Space with AI-generated sample questions, instructions, and benchmarks — all from three config files, no `.tf` editing required.
3+
Get your workspace **OneReady** for Genie in Databricks One. An AI-powered Terraform quickstart that automates business-user onboarding — from ABAC governance and masking functions to a fully configured Genie Space with AI-generated sample questions, instructions, benchmarks, SQL filters, measures, and join specs — all from three config files, no `.tf` editing required.
44

55
## What This Quickstart Automates
66

@@ -12,8 +12,11 @@ Get your workspace **OneReady** for Genie in Databricks One. An AI-powered Terra
1212
- **Masking functions** — Auto-deploy SQL UDFs to enforce column-level data masking (e.g., mask SSN, redact PII, hash emails).
1313
- **Genie Space** — Auto-create a new Genie Space from your tables, or bring an existing one. New spaces include AI-generated config:
1414
- **Sample questions** — Conversation starters tailored to your data domain
15-
- **Instructions** — Domain-specific LLM guidance (metric definitions, date conventions, terminology)
16-
- **Benchmarks** — Ground-truth question + SQL pairs for evaluating Genie accuracy
15+
- **Instructions** — Domain-specific LLM guidance with business defaults (e.g., "customer" means active by default)
16+
- **Benchmarks** — Unambiguous ground-truth question + SQL pairs for evaluating Genie accuracy
17+
- **SQL filters** — Default WHERE clauses (e.g., active customers, completed transactions) that guide Genie's SQL generation
18+
- **SQL measures & expressions** — Standard metrics (total revenue, avg risk score) and computed dimensions (transaction year)
19+
- **Join specs** — Table relationships with join conditions so Genie knows how to combine tables
1720
- **Title & description** — Contextual naming based on your tables and domain
1821
- For existing spaces, set `genie_space_id` in `env.auto.tfvars` to apply `CAN_RUN` ACLs for all configured business groups
1922
- **SQL warehouse** — Auto-create a serverless warehouse or reuse an existing one.
@@ -64,6 +67,9 @@ Get your workspace **OneReady** for Genie in Databricks One. An AI-powered Terra
6467
│ │ │ │ genie_sample_questions (5–10) │ │
6568
│ │ │ │ genie_instructions │ │
6669
│ │ │ │ genie_benchmarks (3–5 w/ SQL) │ │
70+
│ │ │ │ genie_sql_filters / measures │ │
71+
│ │ │ │ genie_sql_expressions │ │
72+
│ │ │ │ genie_join_specs │ │
6773
│ └────────────┬────────────┘ └─────────────────┬─────────────────┘ │
6874
└───────────────┼─────────────────────────────────┼─────────────────────┘
6975
│ ▲ TUNE & VALIDATE │
@@ -94,8 +100,10 @@ Get your workspace **OneReady** for Genie in Databricks One. An AI-powered Terra
94100
│ │ (auto-deploy UDFs) │ │ USE_CATALOG │ │ • sample questions │ │
95101
│ │ │ │ USE_SCHEMA │ │ • instructions │ │
96102
│ │ + SQL Warehouse │ │ SELECT │ │ • benchmarks │ │
97-
│ │ (auto-created if │ │ │ │ • CAN_RUN ACLs │ │
98-
│ │ needed) │ │ │ │ for all groups │ │
103+
│ │ (auto-created if │ │ │ │ • sql filters / │ │
104+
│ │ needed) │ │ │ │ measures / joins │ │
105+
│ │ │ │ │ │ • CAN_RUN ACLs │ │
106+
│ │ │ │ │ │ for all groups │ │
99107
│ └────────────────────┘ └────────────────┘ └────────────────────┘ │
100108
└───────────────────────────────────────────────────────────────────────┘
101109
```
@@ -113,7 +121,7 @@ make validate-generated # 3. (Optional) Tune generated/ files, validate afte
113121
make apply # Validates → promotes → terraform apply
114122
```
115123

116-
That's it. `make apply` creates groups, tags, masking functions, FGAC policies, UC grants, and a Genie Space (with AI-generated sample questions, instructions, and benchmarks) — all in one command.
124+
That's it. `make apply` creates groups, tags, masking functions, FGAC policies, UC grants, and a Genie Space (with AI-generated sample questions, instructions, benchmarks, SQL filters/measures/expressions, and join specs) — all in one command.
117125

118126
To tear everything down: `make destroy`.
119127

@@ -166,16 +174,20 @@ Managed automatically based on `genie_space_id` in `env.auto.tfvars`:
166174
When `make generate` creates the ABAC config, it also generates Genie Space config in `abac.auto.tfvars`:
167175

168176

169-
| Variable | Purpose |
170-
| ------------------------- | --------------------------------------------------------------------------------------- |
171-
| `genie_space_title` | AI-generated title for the Genie Space (e.g., "Financial Compliance Analytics") |
172-
| `genie_space_description` | 1–2 sentence summary of the space's scope and audience |
173-
| `genie_sample_questions` | Natural-language questions shown as conversation starters in the Genie UI |
174-
| `genie_instructions` | Domain-specific guidance for the Genie LLM (metric definitions, date conventions, etc.) |
175-
| `genie_benchmarks` | Ground-truth question + SQL pairs for evaluating Genie accuracy |
177+
| Variable | Purpose |
178+
| ------------------------- | ---------------------------------------------------------------------------------------------------------- |
179+
| `genie_space_title` | AI-generated title for the Genie Space (e.g., "Financial Compliance Analytics") |
180+
| `genie_space_description` | 1–2 sentence summary of the space's scope and audience |
181+
| `genie_sample_questions` | Natural-language questions shown as conversation starters in the Genie UI |
182+
| `genie_instructions` | Domain-specific guidance including business defaults (e.g., "customer" = active by default) |
183+
| `genie_benchmarks` | Unambiguous ground-truth question + SQL pairs for evaluating Genie accuracy |
184+
| `genie_sql_filters` | Default WHERE clauses (e.g., active customers, completed transactions) that guide Genie's SQL generation |
185+
| `genie_sql_measures` | Standard aggregate metrics (e.g., total revenue, average risk score) |
186+
| `genie_sql_expressions` | Computed dimensions (e.g., transaction year, age bucket) |
187+
| `genie_join_specs` | Table relationships with join conditions (e.g., accounts to customers on CustomerID) |
176188

177189

178-
All five fields are included in the `serialized_space` when a new Genie Space is created. Review and tune them in `generated/abac.auto.tfvars` alongside the ABAC policies before applying.
190+
All nine fields are included in the `serialized_space` when a new Genie Space is created. Review and tune them in `generated/abac.auto.tfvars` alongside the ABAC policies before applying.
179191

180192
## Make Targets
181193

0 commit comments

Comments
 (0)