From e726b88acd52369649c267651a0dde6735c0b4b9 Mon Sep 17 00:00:00 2001 From: Ettore Di Giacinto Date: Tue, 13 Oct 2026 08:10:28 +0000 Subject: [PATCH] fix(qdrant-store): warn about non-COSINE metrics and document them With DOT, EUCLID or MANHATTAN the backend returns Qdrant's raw scores, not similarity-like values. Router, face and voice stores compare against cosine thresholds, so log a warning at load when another metric is configured, and document the behaviour on the stores page. Assisted-by: Claude Code:claude-sonnet-5-5 Signed-off-by: Ettore Di Giacinto --- backend/go/qdrant-store/store.go | 5 +++++ docs/content/features/stores.md | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/backend/go/qdrant-store/store.go b/backend/go/qdrant-store/store.go index 8769fdd34..361bb8f48 100644 --- a/backend/go/qdrant-store/store.go +++ b/backend/go/qdrant-store/store.go @@ -17,6 +17,7 @@ import ( "github.com/mudler/LocalAI/pkg/grpc/base" pb "github.com/mudler/LocalAI/pkg/grpc/proto" "github.com/mudler/LocalAI/pkg/store" + "github.com/mudler/xlog" "github.com/qdrant/go-client/qdrant" "google.golang.org/grpc" "google.golang.org/grpc/codes" @@ -84,6 +85,10 @@ func (s *QdrantStore) Load(opts *pb.ModelOptions) error { return fmt.Errorf("qdrant-store: connect to %s: %w", cfg.Addr(), err) } s.client, s.cfg, s.collection = client, cfg, collectionName(cfg, opts.GetModel()) + if cfg.Distance != qdrant.Distance_Cosine { + xlog.Warn("qdrant-store: non-COSINE distance_metric returns raw distances or dot products, not similarities; keep COSINE for router, face and voice stores", + "distance_metric", cfg.Distance.String(), "collection", s.collection) + } ctx, cancel := s.ctx() defer cancel() diff --git a/docs/content/features/stores.md b/docs/content/features/stores.md index a28b44a39..9350ae9f5 100644 --- a/docs/content/features/stores.md +++ b/docs/content/features/stores.md @@ -221,6 +221,14 @@ results come back nearest-first. If a collection already exists with a different `distance_metric`, loading the store (or, if the collection appeared later, the first `find`) fails rather than returning scores with the wrong meaning. +{{% notice warning %}} +Only `COSINE` returns similarity-like scores. With `DOT`, `EUCLID` or `MANHATTAN` the backend +returns Qdrant's raw dot products or distances, which are not bounded to `[-1, 1]` and, for +`EUCLID` and `MANHATTAN`, run in the opposite direction. Router stores, face recognition and voice +recognition compare scores against cosine thresholds, so keep them on `COSINE`. The backend logs a +warning at load time when a store is configured with another metric. +{{% /notice %}} + {{% notice note %}} The backend creates collections with Qdrant's default settings. For custom settings (sharding and replication on a cluster, HNSW parameters, on-disk vectors, quantization), create the collection