Skip to content

🎯 feat: add RAG_DISTANCE_THRESHOLD to drop weak retrieval matches - #288

Merged
danny-avila merged 4 commits into
mainfrom
claude/relevance-threshold
Apr 24, 2026
Merged

danny-avila merged 4 commits into
mainfrom
claude/relevance-threshold

Conversation

@danny-avila

Copy link
Copy Markdown
Collaborator

Summary

Adds an optional RAG_DISTANCE_THRESHOLD env var. When set, results returned by /query and /query_multiple are filtered by their vector distance after the top-k search — any match with distance greater than the threshold is dropped. The score returned by similarity_search_with_score_by_vector is a distance (lower = more similar), so this prunes the weakly-related tail that top-k alone would still surface.

  • New helper _apply_distance_threshold in document_routes.py, applied to both single-file and multi-file query paths.
  • Env var is unset by default → behavior unchanged for existing deployments.

Closes #109.

Motivation

From the issue reporter:

In case of larger knowledge bases, file search returns quite a lot of document chunks even with quite little relevance score. If you use some of the larger models (e.g. GPT-4o or Claude 3.5 Sonnet), it can increase costs quite quickly.

The right threshold depends on the embedding model and distance strategy, so the README calls out that operators should inspect their actual scores before choosing one rather than baking a default.

Test plan

  • Deploy with RAG_DISTANCE_THRESHOLD=0.5; issue a query and confirm only chunks with distance ≤ 0.5 are returned.
  • Unset the env var; confirm behavior matches pre-change.
  • CI (build-and-test) should pass.

@danny-avila

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a3f599cb55

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

"""
if RAG_DISTANCE_THRESHOLD is None:
return documents
return [(doc, score) for doc, score in documents if score <= RAG_DISTANCE_THRESHOLD]

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Invert threshold comparison for Atlas similarity scores

The new filter keeps entries with score <= RAG_DISTANCE_THRESHOLD, which assumes scores are distances (lower is better). That assumption does not hold for the Atlas path: AtlasMongoVector.similarity_search_with_score_by_vector forwards Atlas vectorSearchScore values (similarity scores where higher is better). In VECTOR_DB_TYPE=atlas-mongo deployments that enable RAG_DISTANCE_THRESHOLD (for example 0.5), this logic removes the best matches and keeps weaker ones in both /query and /query_multiple.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — fixed in fd61df7 by scoping the filter to pgvector only. Atlas (VECTOR_DB_TYPE=atlas-mongo) returns similarity scores (higher = better), so applying score <= threshold would keep the worst matches. The filter now short-circuits for Atlas and logs a one-time startup warning when the env var is set, so operators see their setting is being ignored. Happy to add a dedicated Atlas-aware min-similarity knob in a follow-up if there is demand.

@danny-avila

Copy link
Copy Markdown
Collaborator Author

@codex review

@danny-avila danny-avila changed the title ✨ feat: add RAG_DISTANCE_THRESHOLD to drop weak retrieval matches 🎯 feat: add RAG_DISTANCE_THRESHOLD to drop weak retrieval matches Apr 23, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: fd61df7a7d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread app/config.py Outdated
Comment on lines +218 to +221
_distance_threshold_raw = get_env_variable("RAG_DISTANCE_THRESHOLD", None)
RAG_DISTANCE_THRESHOLD = (
float(_distance_threshold_raw)
if _distance_threshold_raw not in (None, "")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Gate threshold parsing by vector DB type

RAG_DISTANCE_THRESHOLD is parsed as float unconditionally during config import, so any non-numeric value will raise ValueError and prevent startup even when VECTOR_DB_TYPE=atlas-mongo (where this setting is documented/implemented as ignored). This creates an avoidable outage path for Atlas deployments that carry a stale or templated non-numeric value for this env var; parsing should be conditional on pgvector (or validated with a safe fallback) before import-time initialization fails.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in bace969 — same pattern as #287. The float() cast now only runs under VECTOR_DB_TYPE=pgvector; under atlas-mongo the env var stays unparsed so a stale/non-numeric value no longer turns an unrelated Atlas deployment into a boot failure.

@danny-avila

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: bace969f04

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread app/routes/document_routes.py Outdated
Comment on lines +52 to +54
RAG_DISTANCE_THRESHOLD is not None
and VECTOR_DB_TYPE == VectorDBType.ATLAS_MONGO
):

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Emit Atlas warning when threshold env is set

This condition can never fire in Atlas mode because RAG_DISTANCE_THRESHOLD is only parsed in app/config.py when VECTOR_DB_TYPE == PGVECTOR, so in atlas-mongo it remains None even if the operator sets RAG_DISTANCE_THRESHOLD. As a result, Atlas deployments silently ignore the setting instead of logging the promised startup warning, which can mislead operators into believing weak-match filtering is active and mask avoidable token-cost increases.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch — fixed in 636f35c. Checking the raw env (os.getenv("RAG_DISTANCE_THRESHOLD")) in the Atlas warning branch instead of the parsed value, so operators who set the threshold under atlas-mongo actually see the startup warning that tells them their setting is being ignored.

Applies a post-search filter on /query and /query_multiple that
discards any (document, score) pairs whose vector distance exceeds
the configured threshold. The score returned by
similarity_search_with_score_by_vector is a distance (lower = more
similar), so this prunes the less-relevant tail that top-k search
would otherwise surface. Unset by default — behavior unchanged for
existing deployments.

Closes #109
Atlas Vector Search returns similarity scores (higher = better),
the opposite of pgvector's distances (lower = better), so the
naive `score <= threshold` comparison would keep the weakest
matches and drop the strongest under VECTOR_DB_TYPE=atlas-mongo.
Skip the filter on Atlas and emit a one-time startup warning so
operators notice their setting is being ignored. A dedicated
Atlas-aware min-similarity knob can be added if there is demand.
Same class of bug codex caught on #287's EMBEDDINGS_DIMENSIONS: the
float() cast ran unconditionally at import, so a stale or templated
non-numeric value would prevent startup for atlas-mongo deployments
where the setting is already documented as ignored. Gate the parse
on VECTOR_DB_TYPE=pgvector so Atlas boots cleanly regardless of the
env var value.
The parsed value is deliberately None under atlas-mongo (we skip the
float() cast so a stale non-numeric value can't break startup), so
checking it for the warning branch guaranteed the warning never fires.
Inspect os.getenv("RAG_DISTANCE_THRESHOLD") directly so Atlas operators
actually see that their configured threshold is being ignored instead
of assuming weak-match filtering is silently active.
@danny-avila
danny-avila force-pushed the claude/relevance-threshold branch from bace969 to 636f35c Compare April 23, 2026 17:30
@danny-avila

Copy link
Copy Markdown
Collaborator Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Bravo.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@danny-avila
danny-avila merged commit 7062795 into main Apr 24, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[ENHANCEMENT] Relevance limit settings

1 participant