[Feature Request] Make NL-search LLM facet-value collection and prompt-sample caps configurable (replace hardcoded 20/10)
Describe your feature request
Allow Typesense's natural-language-search pipeline to expose configurable caps for how many facet values are collected and how many are shown in the schema prompt sent to the LLM. In v30.2 these two limits are hardcoded inside generate_schema_prompt():
- Collection cap (max facet values fetched): src/natural_language_search_model_manager.cpp — generate_schema_prompt(), call to coll->search(..., 20, ...) (around line 232)
- Prompt display cap (values shown in the schema table): src/natural_language_search_model_manager.cpp — generate_schema_prompt(), loop that limits to 10 values: for (size_t i = 0; i < values.size() && i < 10; ++i) (around lines 270–274)
These are literals in the v30.2 source and currently cannot be changed at runtime without recompiling.
Request: add runtime-configurable controls for both caps (server-wide config and per-request override), plus an optional per-model/per-collection override so deployments that cannot recompile can raise the limits safely.
Proposed knobs (examples):
- Server config (typesense.ini / CLI / env):
nlp.max_facet_values(default: 20),nlp.schema_prompt_sample_values(default: 10),nlp.max_nl_filter_values(global safety upper bound, e.g. 1000) - Per-request query parameters:
llm_max_facet_values(controls collection step),llm_schema_sample_values(controls how many are listed in prompt) - Per-model fields on
/nl_search_modelsregistration:max_facet_valuesandschema_sample_valuesso a model can opt-in to different behavior (these would be merged with server defaults)
Backward compatibility and safety:
- Keep current defaults (20 and 10) unless overridden.
- Enforce a global upper bound (server-configurable) to avoid accidental huge prompts/token blowups (e.g., default upper bound 1000).
- Apply per-request overrides only when explicitly present; require admin-enabled flag to allow large per-request values in production builds.
Please describe your use-case for the feature request
We use Typesense NL search (nl_query=true on multi_search) with a Gemini model registered under /nl_search_models. Our categories field has ~1,200 unique values. In v30.2 the pipeline fetches up to 20 values and then only shows the first 10 in the schema prompt. This truncation prevents the LLM from seeing long-tail categories (e.g. user query "zadelhoes" should map to category fietszadelhoes) and results in missed mappings.
We will not compile a custom build. We need a purely runtime way to raise these caps so the LLM receives the broader set of values without changing Typesense binaries.
Describe alternatives you've considered
- Recompiling Typesense with increased constants (works but not allowed in our environment).
- Stuffing all values into the model's
system_prompt(works and we validated it), but it's a per-model manual workaround that increases token usage on every request and isn't per-request/collection-scoped. - Pre-processing on the client side (e.g., client-side synonym mapping or multi-query patterns) — adds complexity and latency.
Additional context
- File and code references (v30.2):
- src/natural_language_search_model_manager.cpp — generate_schema_prompt(): coll->search(...) call contains the
20literal used for collecting facet values (call parameters around line ~232 in v30.2 source). - src/natural_language_search_model_manager.cpp — generate_schema_prompt(): the enum-values loop uses
i < 10and appends", ..."if more exist (loop around lines ~270–275 in v30.2 source).
- src/natural_language_search_model_manager.cpp — generate_schema_prompt(): coll->search(...) call contains the
- The prompt generation is used before the model's token budget is applied (i.e., these caps happen prior to considering
max_bytes), so simply increasingmax_bytesdoes not solve the problem.
Thanks — opening this feature request on behalf of teams who need runtime control of NL-search facet sampling and prompt enumeration to handle long-tail facet values without recompiling.
Source: typesense/typesense