fix(evidence): fail closed when BM25 is unavailable
This commit is contained in:
@@ -102,6 +102,7 @@ class QdrantVectorStore:
|
||||
write_reachable=False,
|
||||
write_detail=str(exc),
|
||||
expected_dimension=self._expected_dimension,
|
||||
bm25_compatible=None,
|
||||
)
|
||||
|
||||
dimension = info["config"]["params"]["vectors"]["size"]
|
||||
@@ -118,6 +119,7 @@ class QdrantVectorStore:
|
||||
expected_dimension=self._expected_dimension,
|
||||
observed_dimensions=dimensions,
|
||||
dimension_compatible=compatible,
|
||||
bm25_compatible=self._bm25_compatible(info),
|
||||
)
|
||||
|
||||
def search(
|
||||
@@ -176,6 +178,7 @@ class QdrantVectorStore:
|
||||
raise VectorStoreError("Hybrid BM25 is only available for Evidence")
|
||||
if query_text.strip() == "" or query_language not in _BM25_LANGUAGES:
|
||||
raise VectorStoreError("Evidence BM25 query is invalid")
|
||||
self._ensure_collection(strict=False, require_bm25=True)
|
||||
shared_filter = {"must": filter_must}
|
||||
response = self._call(
|
||||
"POST",
|
||||
@@ -225,7 +228,10 @@ class QdrantVectorStore:
|
||||
|
||||
def upsert(self, collection: str, records: list[VectorWriteRecord]) -> int:
|
||||
validate_collection(collection)
|
||||
self._ensure_collection(strict=True)
|
||||
self._ensure_collection(
|
||||
strict=True,
|
||||
require_bm25=any(record.sparse_text is not None for record in records),
|
||||
)
|
||||
points = []
|
||||
for write_record in records:
|
||||
validate_collection_kinds(collection, [write_record.record.kind])
|
||||
@@ -377,7 +383,15 @@ class QdrantVectorStore:
|
||||
else "Embedding dimension does not match configured dimension"
|
||||
)
|
||||
|
||||
def _ensure_collection(self, *, strict: bool) -> dict | None:
|
||||
@staticmethod
|
||||
def _bm25_compatible(info: dict) -> bool:
|
||||
sparse_vectors = info.get("config", {}).get("params", {}).get("sparse_vectors")
|
||||
if not isinstance(sparse_vectors, dict):
|
||||
return False
|
||||
bm25 = sparse_vectors.get("bm25")
|
||||
return isinstance(bm25, dict) and bm25.get("modifier") == "idf"
|
||||
|
||||
def _ensure_collection(self, *, strict: bool, require_bm25: bool = False) -> dict | None:
|
||||
response = self._call("GET", f"/collections/{self._collection}", None, allow_missing=True)
|
||||
if response is None:
|
||||
if not strict:
|
||||
@@ -420,6 +434,8 @@ class QdrantVectorStore:
|
||||
f"/collections/{self._collection}/index",
|
||||
{"field_name": field_name, "field_schema": "keyword"},
|
||||
)
|
||||
if require_bm25 and not self._bm25_compatible(result):
|
||||
raise VectorStoreError("Evidence BM25 collection configuration mismatch")
|
||||
return result
|
||||
|
||||
def _scroll(self, must: list[dict]) -> list[dict]:
|
||||
|
||||
Reference in New Issue
Block a user