recon + sqlglot validator + drill_down package; guard ReAct dimension picks against candidate list
This commit is contained in:
7
api/prompts/drill_down.interpret.system.txt
Normal file
7
api/prompts/drill_down.interpret.system.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
Task: write a short interpretation of an iterative drill-down across a metric.
|
||||
|
||||
You're given the analyst's question, the metric, and the slices tried (each: a dimension and its top rows). Identify the dimension(s) that show the strongest signal — biggest variance, most concentrated outliers, clearest pattern — and write a short, concrete summary.
|
||||
|
||||
Output: two to four sentences. Lead with the dimension(s) that mattered most. Cite specific values from the slices (e.g. "districts with unemployment above 5% accounted for 73% of defaults"). No preamble.
|
||||
|
||||
If no slice produced a meaningful signal, say so plainly.
|
||||
7
api/prompts/drill_down.interpret.user.txt
Normal file
7
api/prompts/drill_down.interpret.user.txt
Normal file
@@ -0,0 +1,7 @@
|
||||
Question:
|
||||
{question}
|
||||
|
||||
Metric: {metric}
|
||||
|
||||
Slices (in order tried):
|
||||
{slices_block}
|
||||
16
api/prompts/drill_down.next.system.txt
Normal file
16
api/prompts/drill_down.next.system.txt
Normal file
@@ -0,0 +1,16 @@
|
||||
Task: pick the next dimension to slice by, in an iterative drill-down investigation.
|
||||
|
||||
You're given the analyst's question, the candidate dimensions, the dimensions already tried (with their slice rows), and a remaining iteration budget. Decide which dimension to try next, or stop if the investigation has converged or budget is exhausted.
|
||||
|
||||
Output: a JSON object in one fenced ```json block:
|
||||
{
|
||||
"action": "drill" | "stop",
|
||||
"dimension": "<dimension name from the candidate list>", // required when action is "drill"
|
||||
"reason": "<one sentence>"
|
||||
}
|
||||
|
||||
Rules:
|
||||
- Pick a dimension that hasn't been tried yet and that the previous slices suggest might explain variance in the metric.
|
||||
- If every candidate has been tried, or the previous slice already shows a clear story, return action="stop".
|
||||
- Don't repeat dimensions.
|
||||
- Never invent a dimension that isn't in the candidate list.
|
||||
13
api/prompts/drill_down.next.user.txt
Normal file
13
api/prompts/drill_down.next.user.txt
Normal file
@@ -0,0 +1,13 @@
|
||||
Question:
|
||||
{question}
|
||||
|
||||
Metric we're slicing:
|
||||
{metric}
|
||||
|
||||
Candidate dimensions:
|
||||
{dimensions}
|
||||
|
||||
Already tried (with row previews):
|
||||
{history}
|
||||
|
||||
Remaining iterations: {budget}
|
||||
@@ -6,7 +6,16 @@ Output: a JSON object with exactly this shape, in one fenced ```json block:
|
||||
{
|
||||
"rationale": "<one sentence on why this plan>",
|
||||
"steps": [
|
||||
{"analysis": "<analysis_name>", "args": { ... }, "why": "<one sentence>"}
|
||||
{
|
||||
"analysis": "<analysis_name>",
|
||||
"args": { ... },
|
||||
"why": "<one sentence>",
|
||||
"fallback": { // OPTIONAL — see rules
|
||||
"analysis": "<analysis_name>",
|
||||
"args": { ... },
|
||||
"why": "<one sentence>"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
@@ -15,3 +24,4 @@ Rules:
|
||||
- The `args` keys must match the analysis's args_schema; additional keys are ignored, missing optional ones are fine.
|
||||
- Most questions are single-step. Only chain analyses when the second genuinely needs the first's output.
|
||||
- Comparing two periods is ONE `compare_periods` step, not two `direct_answer` steps.
|
||||
- A step's `fallback` is optional. Include one when the primary analysis is speculative (e.g. an exploratory `drill_down` that might find nothing useful) and there's a safer Analysis that can still produce an answer. The fallback runs only if the primary errors or yields no finding. Fallbacks must not themselves have fallbacks.
|
||||
|
||||
@@ -4,8 +4,9 @@ Output: exactly one fenced ```sql block, nothing else — no prose, no second bl
|
||||
|
||||
Constraints:
|
||||
- search_path is set to `financial`; don't qualify table names with the schema.
|
||||
- **Postgres folds unquoted identifiers to lowercase.** Always double-quote any column or table name that contains an uppercase letter — including all the `district` columns: `"A2"`, `"A3"`, `"A4"`, `"A5"`, `"A6"`, `"A7"`, `"A8"`, `"A9"`, `"A10"`, `"A11"`, `"A12"`, `"A13"`, `"A14"`, `"A15"`, `"A16"`. Mixing quoted and unquoted forms of the same column (`"A3"` and `A13`) will fail at runtime — be consistent.
|
||||
- Quote identifiers that collide with SQL keywords (notably `"order"`).
|
||||
- Dates in the source are YYMMDD integers (e.g. 950315 → 1995-03-15). Convert with TO_DATE(LPAD(date::text, 6, '0'), 'YYMMDD') whenever you need a real date for filtering, comparison, or display.
|
||||
- Dates in the source are YYMMDD integers (e.g. 950315 → 1995-03-15). Convert with `TO_DATE(LPAD(date::text, 6, '0'), 'YYMMDD')` whenever you need a real date for filtering, comparison, or display.
|
||||
- Loan `status` values: 'A' finished OK, 'B' finished defaulted, 'C' running OK, 'D' running in debt.
|
||||
- Transaction `type` values: 'PRIJEM' credit, 'VYDAJ' debit.
|
||||
- Read-only: never emit DDL or DML.
|
||||
|
||||
Reference in New Issue
Block a user