ad1happy2go opened a new pull request, #19422:
URL: https://github.com/apache/hudi/pull/19422

   > **Stacked on #19411** (Spark Thrift Server engine): this branch contains 
that PR's commit plus one commit of its own. **Review only the last commit** 
(`feat(gateway): schema hints`); the diff will collapse to it once #19411 
merges and this branch is rebased.
   
   ### Describe the issue this Pull Request addresses
   
   Part of the agentic-lakehouse umbrella #19256. Small local models routinely 
skip `describe_table` and guess column names (`bedrooms` for `beds`, invented 
table names), then fail or hallucinate -- the gateway's tool-based schema 
discovery depends on exactly the multi-hop planning that small models are worst 
at. Production text-to-SQL systems converge on a hybrid: compact schema context 
up front plus execution-error feedback that carries the real names. This PR 
adds both, auto-derived from the engine (never hand-written), behind one knob.
   
   ### Summary and Changelog
   
   `GATEWAY_SCHEMA_HINTS = off | errors | prompt | both` (default `both`); 
everything degrades gracefully and `off` restores today's pure tool-based 
discovery.
   
   **`tools/schema_cache.py` -- the snapshot**
   - Single-flight TTL cache (default 300s) over a new per-connector 
`fetch_schema()`: one `information_schema` query on Trino; `SHOW TABLES` + 
`DESCRIBE TABLE` per table on Spark (stops at the `# Partition Information` 
section). Size-capped (`GATEWAY_SCHEMA_MAX_TABLES`/`_MAX_COLUMNS`), Hudi 
`_hoodie_*` meta columns filtered so hints never steer the model toward them.
   - Strictly fail-open: a refresh failure keeps the previous snapshot and 
never breaks the query path; failures are debounced by the same TTL so an 
unreachable engine is not hammered by probes.
   
   **`errors` mode -- execution-guided self-correction**
   - A column/table-not-found error now returns an actionable hint built from 
the cached schema: fuzzy match on the offending identifier (leaf of qualified 
names) plus the real names to copy from: `Did you mean `beds`? Columns in 
`listings`: listing_id, address, price, beds, ...`. Handles Spark 
(`UNRESOLVED_COLUMN`, `TABLE_OR_VIEW_NOT_FOUND`) and Trino (`COLUMN_NOT_FOUND`, 
`TABLE_NOT_FOUND`) message shapes; non-name errors keep the existing generic 
hint; bounded at 700 chars.
   
   **`prompt` mode -- schema in the system prompt**
   - A compact snapshot (`listings(listing_id string, address string, ...)`) is 
rendered into the system prompt per turn via a callable `create_react_agent` 
prompt, so the model writes SQL against real names without a discovery hop; the 
message-trimming hook is preserved (`llm_input_messages`-aware). The snapshot 
is warmed at gateway startup and follows the TTL thereafter, so schema changes 
propagate without agent rebuilds.
   
   **Plumbing**
   - `LakehouseConnector.fetch_schema()` added with a `return {}` default -- 
third-party connectors are unaffected and simply have hints disabled until they 
implement it. `build_schema_cache()` + `schema_cache` parameter threaded 
through `build_registry`/`AgentCache`; helm chart gains `schemaHints`; README 
section + config rows.
   
   **Tests** -- 28 new offline tests: cache 
TTL/fail-open/caps/meta-filter/peek-background-refresh, did-you-mean hints for 
both engines' error shapes (incl. qualified identifiers, no-close-match 
fallback, bounded output, non-name errors silent), mode gating, end-to-end 
through both engines' tool handlers, prompt rendering and trimming interplay, 
and both connector fetchers.
   
   No code copied from other projects.
   
   ### Impact
   
   New optional configs (`GATEWAY_SCHEMA_HINTS`, 
`GATEWAY_SCHEMA_CACHE_TTL_SECONDS`, `GATEWAY_SCHEMA_MAX_TABLES/_MAX_COLUMNS`) 
documented in the module README; new helm value `schemaHints`. Default `both` 
changes model-facing behavior only (better hints, a schema block in the system 
prompt); the tool API and HTTP surfaces are unchanged. Costs one schema fetch 
per TTL window plus the prompt tokens for the capped snapshot; 
`GATEWAY_SCHEMA_HINTS=errors` keeps the prompt lean, `off` restores current 
behavior exactly.
   
   ### Risk Level
   
   low -- additive and fail-open by construction (schema fetch failures degrade 
hints, never queries). 172 offline tests pass; ruff and mypy clean; helm lint 
clean. Verified live against Apache Kyuubi serving Hudi 1.3 tables with 
llama3.1: the previously failing question ("active 3-bedroom homes under $800k 
in Downtown") went from hallucinated column names and a leaked tool-call JSON 
to correct names (`status`/`beds`/`neighborhood`) on the first tool call, and a 
forced `bedrooms` query returned the did-you-mean hint carrying the real column 
list.
   
   ### Documentation Update
   
   Module README updated in this PR ("Schema hints" section + config table 
rows). Website docs tracked with the umbrella #19256.
   
   ### Contributor's checklist
   
   - [x] Read through [contributor's 
guide](https://hudi.apache.org/contribute/how-to-contribute)
   - [x] Enough context is provided in the sections above
   - [x] Adequate tests were added if applicable
   


-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to