Skip to main content

nlq-validator

A lightweight Natural Language Query (NLQ) validator that keeps your LLM assistant on-topic. Train it on a handful of example questions, and it will accept in-domain queries while rejecting off-topic ones — no server, no API key required for the core functionality.

Features

  • TF-IDF scoring out of the box — no model downloads needed
  • Semantic embeddings via sentence-transformers for paraphrase-aware matching
  • Threshold calibration — find the F1-optimal cutoff for your domain
  • Incremental retraining — add examples without rebuilding from scratch
  • LLM-powered question generation — auto-generate training data from your system prompt (Claude, ChatGPT, Gemini, Mistral, Grok, Perplexity)
  • Async support for all LLM integrations
  • Zero runtime dependencies beyond scikit-learn for the core validator

Installation

pip install nlq-validator

Optional extras

pip install 'nlq-validator[embeddings]'   # sentence-transformers for semantic matching
pip install 'nlq-validator[anthropic]'    # Claude integration
pip install 'nlq-validator[openai]'       # ChatGPT, Grok, Perplexity integrations
pip install 'nlq-validator[gemini]'       # Google Gemini integration
pip install 'nlq-validator[mistral]'      # Mistral integration
pip install 'nlq-validator[all-llm]'      # All LLM integrations

Quick start

from nlq_validator import NLQValidator

SYSTEM_PROMPT = (
    "You are a SQL assistant. You help users write queries, "
    "understand JOINs, indexes, and query optimization."
)

# Train from a plain-text file (one question per line)
v = NLQValidator.from_training_file("questions.txt", SYSTEM_PROMPT)

result = v.validate("How do I write a SELECT statement?")
print(result.is_valid)   # True

result = v.validate("What is my horoscope today?")
print(result.is_valid)   # False
print(result.errors)     # ['Query appears off-topic (score=0.000, threshold=0.250)']

Training data format

Supported file formats: .txt (one question per line), .csv (first column), .json (list of strings or list of {"text": "..."} objects).

# questions.txt
How do I write a SELECT statement?
What is a SQL JOIN?
How do I filter rows with WHERE clause?
What is the difference between INNER JOIN and LEFT JOIN?
...

Threshold calibration

The default threshold of 0.25 is a conservative starting point. Use calibrate() to find the optimal value for your domain:

in_domain = ["How do I use GROUP BY?", "What is a primary key?", ...]
off_domain = ["How do I bake bread?", "What is my horoscope?", ...]

result = v.calibrate(in_domain, off_domain)
result.summary()          # prints precision/recall/F1 table
v.apply_calibration(result)  # applies suggested threshold

Incremental retraining

v.retrain(["How do I write a CTE?", "What is a window function?"])
# or from a file:
v.retrain_from_file("more_questions.txt")

Semantic embeddings

For queries that use different words but mean the same thing:

v = NLQValidator.from_training_file(
    "questions.txt",
    SYSTEM_PROMPT,
    embedding_model="all-MiniLM-L6-v2",   # requires nlq-validator[embeddings]
)

LLM-powered question generation

Generate training data automatically from your system prompt:

from nlq_validator.integrations.claude import ClaudeIntegration

llm = ClaudeIntegration()   # reads ANTHROPIC_API_KEY env var
v = NLQValidator.from_llm(llm, SYSTEM_PROMPT, count=50)

Async variant:

v = await NLQValidator.from_llm_async(llm, SYSTEM_PROMPT, count=50)

Supported LLM providers

Provider Extra Class Env vars
Claude [anthropic] ClaudeIntegration ANTHROPIC_API_KEY, ANTHROPIC_MODEL
ChatGPT [openai] ChatGPTIntegration OPENAI_API_KEY, OPENAI_MODEL
Gemini [gemini] GeminiIntegration GEMINI_API_KEY, GEMINI_MODEL
Mistral [mistral] MistralIntegration MISTRAL_API_KEY, MISTRAL_MODEL
Grok [openai] GrokIntegration XAI_API_KEY, XAI_MODEL
Perplexity [openai] PerplexityIntegration PERPLEXITY_API_KEY, PERPLEXITY_MODEL

Save and load

v.save("my_model.pkl")
v2 = NLQValidator.load("my_model.pkl")

License

MIT — see LICENSE.

Metadata

Release files for nlq-validator 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for nlq-validator 0.1.0
File Size Uploaded Provenance
nlq_validator-0.1.0.tar.gz 15.6 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for nlq-validator 0.1.0
File Interpreter ABI Platform
nlq_validator-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 31.4 kB

Release files / nlq_validator-0.1.0.tar.gz

Download URL nlq_validator-0.1.0.tar.gz
Size 15.6 kB
Tags Source
SHA-256 checksum
How to use checksums
468a9fdde3956fae09ef8dfd693c2ff5d57dc9e9cba20eb5f0b8d794cfe0c828
BLAKE2b-256 checksum
How to use checksums
8195107978ce9a49487b9d3fc6f8513397bffff13e5481718cbd026edaab55e0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 14, 2026.

Transparency log

Release files / nlq_validator-0.1.0-py3-none-any.whl

Download URL nlq_validator-0.1.0-py3-none-any.whl
Size 15.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
27e2b622219c06c38408e6bc8bae382de0d20a4ecee6ce709213b5ed3d8b7fef
BLAKE2b-256 checksum
How to use checksums
b2aa55625e1f82e4961ad37c82c7faff5ce6f0e618cb7a8d51dc4830c85326fd
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.12

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 14, 2026.

Transparency log

Security for nlq-validator 0.1.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for nlq_validator-0.1.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 14, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page