Spaces:
Sleeping
Sleeping
File size: 4,541 Bytes
2e818da | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 | """Registered RAG retrieval pipeline versions.
Task 7 froze ``rag-naive-v1`` as the observed baseline and, from genuine
SigNoz-backed diagnosis (see ``docs/observability/diagnostic-workflow.md``),
picked deduplication of near-duplicate candidates -- over-fetch a larger raw
pool, remove near-duplicates, then truncate back to the caller's requested
count -- as the one architectural variable for ``rag-dedup-v2``.
This module is the single source of truth for what a "pipeline version"
means behaviourally. It does not itself touch Chroma, embeddings, or
telemetry -- ``ChromaDBClient.query_observed`` (``app/rag/chromadb_client.py``)
reads a :class:`PipelineVersion` from here and gates its over-fetch/dedup
logic on ``dedup_enabled``/``overfetch_factor``.
Design contract (do not weaken without updating Task 8's report):
- ``rag-naive-v1`` is immutable: ``dedup_enabled=False``, ``overfetch_factor=1``,
forever. A test in ``tests/rag/test_pipeline_version.py`` pins this exact
tuple so an accidental edit here fails loudly.
- The *default* (no pipeline version requested -- ``None``) must always
resolve to exactly ``rag-naive-v1``'s behavior. Ordinary product traffic
(Chat, LEARN_NODE, flashcards, quiz, StudyBuddy) never passes an explicit
pipeline version, so it is always on this default path and is therefore
provably unaffected by anything registered here.
- An explicitly requested but unregistered version string is a hard error
(``UnknownPipelineVersionError``), per the brief's "reject evaluation
startup when the requested version is unknown" -- silently falling back to
v1 behavior for a typo'd version name would make a v1/v2 comparison
silently meaningless.
"""
from __future__ import annotations
from dataclasses import dataclass
# Over-fetch factor for rag-dedup-v2: request `requested_top_k * factor` raw
# candidates from Chroma before dedup+truncate, so removing near-duplicates
# can still backfill up to the caller's original requested count instead of
# only ever shrinking the naive top-5 in place (the exact trap the plan
# preamble's acceptance gate calls out: "the improvement is not caused solely
# by returning fewer required candidates"). 3x is a deliberately modest
# choice -- big enough that Task 7's finding of low document_diversity
# (1.58/5 average) has real room to be corrected by pulling in alternate
# documents' chunks, small enough that it doesn't turn `chroma.vector_search`
# into a new dominant cost on top of the already-dominant `embedding.query`
# stage (a 3x-larger candidate pool over a ~10k-chunk shared collection is
# still a small single Chroma call, not a new order of magnitude).
DEDUP_V2_OVERFETCH_FACTOR = 3
DEFAULT_PIPELINE_VERSION = "rag-naive-v1"
CURRENT_PRODUCT_PIPELINE_VERSION = "rag-structured-hybrid-v3"
@dataclass(frozen=True)
class PipelineVersion:
"""One registered, behaviorally-complete retrieval pipeline configuration."""
name: str
dedup_enabled: bool
overfetch_factor: int
class UnknownPipelineVersionError(ValueError):
"""Raised when an explicitly requested pipeline version is not registered."""
_REGISTRY: dict[str, PipelineVersion] = {
"rag-naive-v1": PipelineVersion(
name="rag-naive-v1", dedup_enabled=False, overfetch_factor=1
),
"rag-dedup-v2": PipelineVersion(
name="rag-dedup-v2",
dedup_enabled=True,
overfetch_factor=DEDUP_V2_OVERFETCH_FACTOR,
),
}
def registered_versions() -> tuple[str, ...]:
"""All registered pipeline version names, for error messages and tests."""
return tuple(sorted(_REGISTRY))
def get_pipeline_version(name: str | None) -> PipelineVersion:
"""Resolve a pipeline version name to its behavior.
``name=None`` (the default for every ordinary product call site) always
resolves to ``rag-naive-v1`` -- unspecified pipeline version is never
ambiguous and never requires the caller to know version names exist.
Raises :class:`UnknownPipelineVersionError` for any non-``None`` name that
isn't registered, rather than silently falling back to v1 -- an
evaluation run that mistypes a version string must fail loudly, not
quietly measure the wrong pipeline.
"""
if name is None:
return _REGISTRY[DEFAULT_PIPELINE_VERSION]
try:
return _REGISTRY[name]
except KeyError as exc:
raise UnknownPipelineVersionError(
f"Unknown pipeline version {name!r}. Registered versions: "
f"{', '.join(registered_versions())}"
) from exc
|