RefinerNode
Overview
- Generates corrective feedback for planning failures using an LLM.
- Exists to improve planner outputs in retry loops.
- Sits between
retry_handlerandASTPlannerNodein the SQL agent subgraph. - Class:
RefinerNode - Source:
packages/nl2sql/src/nl2sql/pipeline/nodes/refiner/node.py
Responsibilities
- Summarize planning errors and reasoning context.
- Invoke LLM to generate feedback.
- Emit
PLAN_FEEDBACKwarnings to drive retry.
Position in Execution Graph
Upstream:
- retry_handler
Downstream:
- ASTPlannerNode
Trigger conditions: - Executed when retry handler routes to refinement.
flowchart LR
RetryHandler[retry_handler] --> Refiner[RefinerNode] --> Planner[ASTPlannerNode]
Inputs
From SubgraphExecutionState:
errorsreasoningrelevant_tablesast_planner_response.plan(optional)sub_query.intent
Validation performed:
- If no LLM configured, emits
MISSING_LLM.
Outputs
Mutations to SubgraphExecutionState:
refiner_response(RefinerResponse)errors(includesPLAN_FEEDBACKwarning)reasoning
Side effects:
- LLM invocation.
Internal Flow (Step-by-Step)
- If no LLM configured, emit
MISSING_LLMand stop. - Render relevant tables with
render_schema_for_prompt(the planner's compact schema block, onlysample_valuesand the date and numeric columns'rangefrom the column stats), and the failed plan as compact JSON (model_dump_json(exclude_none=True)). - Build error and reasoning strings. The errors are the failed attempt's only, one line each as
- [node] ERROR_CODE: message; earlier attempts' errors are not repeated. - Invoke LLM with refinement prompt. It is two messages: the system message holds the instructions and then the schema (stable, so the provider can cache it); the human message holds the question, today's date (
run_date(settings.pipeline.today), as the planner gets it), failed plan, errors and reasoning. On Chinook the prompt is about 2,600 tokens (was about 8,000), 2,500 of them a prefix shared across questions. - Emit
PLAN_FEEDBACKwarning and returnRefinerResponse. - On exception, emit
REFINER_FAILED.
Contracts & Interfaces
Implements a LangGraph node callable:
Key contracts:
RefinerResponsePipelineError(PLAN_FEEDBACK,MISSING_LLM,REFINER_FAILED, or aPROVIDER_*error when the provider refused the call (see provider failures))
Determinism Guarantees
- Non‑deterministic unless LLM configured deterministically.
Error Handling
Emits PipelineError with:
MISSING_LLMPLAN_FEEDBACK(warning)REFINER_FAILED
Logs failures via logger.error.
Retry + Idempotency
- No internal retry logic.
- Idempotency depends on LLM determinism.
Performance Characteristics
- LLM call dominates latency.
- Serialization of inputs is in‑memory.
Observability
- Logger:
refiner - Adds reasoning entries with feedback content.
Configuration
- LLM configuration for agent name
refinerviallm.yaml.
Extension Points
- Modify
REFINER_PROMPTfor different refinement behavior. - Replace node in
build_sql_agent_graph()for alternate retry strategies.
Known Limitations
- No fallback if LLM unavailable.
- Feedback quality depends on LLM and prompt.
Related Code
packages/nl2sql/src/nl2sql/pipeline/nodes/refiner/node.py