From d418ba175d176c6d13d56073ed8819f89b310179 Mon Sep 17 00:00:00 2001 From: A Vertex SDK engineer Date: Wed, 15 Jul 2026 14:16:02 -0700 Subject: [PATCH] fix: Preserve rrf_ranking_alpha=0.0 in MatchingEngineIndexEndpoint hybrid queries `HybridQuery.rrf_ranking_alpha` is an optional float that defaults to `None`. Two call sites in `matching_engine_index_endpoint.py` previously gated RRF wiring on the truthiness of this field (`if query.rrf_ranking_alpha`), which incorrectly treated an explicit `0.0` the same as an unset value. As a result, callers passing `rrf_ranking_alpha=0.0` (pure sparse ranking) had the `rrf` submessage silently omitted from the outgoing request, and the server fell back to its default alpha instead of honoring the caller's intent. Switch both sites to `is not None` so `0.0` is preserved end-to-end: - `find_neighbors` (public path, `FindNeighborsRequest.Query.RRF`) - `match` (private-service-access path, `MatchRequest.RRF`) Extend `_TEST_HYBRID_QUERIES` with a sparse-only entry that sets `rrf_ranking_alpha=0.0`, and update the two consumers (`test_private_service_access_hybrid_search_match_queries` and `test_index_public_endpoint_find_neighbors_queries`) to assert that the resulting RPC contains `rrf { alpha: 0.0 }` (instead of no rrf at all). Also switch the expected-side predicate in the private-service-access test from truthiness to `is not None` for consistency with the SDK. FUTURE_COPYBARA_INTEGRATE_REVIEW=https://github.com/googleapis/python-aiplatform/pull/6967 from googleapis:release-please--branches--main 4a0d1d2600075ee025fe0b27831a2e380062da43 PiperOrigin-RevId: 948540018 --- .../matching_engine_index_endpoint.py | 4 +-- .../test_matching_engine_index_endpoint.py | 28 ++++++++++++++++++- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/google/cloud/aiplatform/matching_engine/matching_engine_index_endpoint.py b/google/cloud/aiplatform/matching_engine/matching_engine_index_endpoint.py index 94da9ac225..e2cb9efc2b 100644 --- a/google/cloud/aiplatform/matching_engine/matching_engine_index_endpoint.py +++ b/google/cloud/aiplatform/matching_engine/matching_engine_index_endpoint.py @@ -1865,7 +1865,7 @@ def find_neighbors( dimensions=query.sparse_embedding_dimensions, ), ) - if query.rrf_ranking_alpha: + if query.rrf_ranking_alpha is not None: find_neighbors_query.rrf = ( gca_match_service_v1beta1.FindNeighborsRequest.Query.RRF( alpha=query.rrf_ranking_alpha, @@ -2200,7 +2200,7 @@ def match( match_service_pb2.MatchRequest.RRF( alpha=query.rrf_ranking_alpha, ) - if query_is_hybrid and query.rrf_ranking_alpha + if query_is_hybrid and query.rrf_ranking_alpha is not None else None ), ) diff --git a/tests/unit/aiplatform/test_matching_engine_index_endpoint.py b/tests/unit/aiplatform/test_matching_engine_index_endpoint.py index bb8d3642a8..15267f9d0c 100644 --- a/tests/unit/aiplatform/test_matching_engine_index_endpoint.py +++ b/tests/unit/aiplatform/test_matching_engine_index_endpoint.py @@ -258,6 +258,11 @@ sparse_embedding_dimensions=[1, 2, 3], sparse_embedding_values=[0.1, 0.2, 0.3], ), + HybridQuery( + sparse_embedding_dimensions=[1, 2, 3], + sparse_embedding_values=[0.1, 0.2, 0.3], + rrf_ranking_alpha=0.0, # Test edge case where alpha is 0 + ), ] _TEST_NUM_NEIGHBOURS = 1 _TEST_FILTER = [ @@ -1539,7 +1544,7 @@ def test_private_service_access_hybrid_search_match_queries( match_service_pb2.MatchRequest.RRF( alpha=_TEST_HYBRID_QUERIES[i].rrf_ranking_alpha, ) - if _TEST_HYBRID_QUERIES[i].rrf_ranking_alpha + if _TEST_HYBRID_QUERIES[i].rrf_ranking_alpha is not None else None ), ) @@ -2093,6 +2098,27 @@ def test_index_public_endpoint_find_neighbors_queries( approximate_neighbor_count=_TEST_APPROX_NUM_NEIGHBORS, fraction_leaf_nodes_to_search_override=_TEST_FRACTION_LEAF_NODES_TO_SEARCH_OVERRIDE, ), + gca_match_service_v1beta1.FindNeighborsRequest.Query( + neighbor_count=_TEST_NUM_NEIGHBOURS, + datapoint=gca_index_v1beta1.IndexDatapoint( + restricts=[ + gca_index_v1beta1.IndexDatapoint.Restriction( + namespace="class", + allow_list=["token_1"], + deny_list=["token_2"], + ) + ], + sparse_embedding=gca_index_v1beta1.IndexDatapoint.SparseEmbedding( + values=[0.1, 0.2, 0.3], dimensions=[1, 2, 3] + ), + ), + rrf=gca_match_service_v1beta1.FindNeighborsRequest.Query.RRF( + alpha=0.0, + ), + per_crowding_attribute_neighbor_count=_TEST_PER_CROWDING_ATTRIBUTE_NUM_NEIGHBOURS, + approximate_neighbor_count=_TEST_APPROX_NUM_NEIGHBORS, + fraction_leaf_nodes_to_search_override=_TEST_FRACTION_LEAF_NODES_TO_SEARCH_OVERRIDE, + ), ], return_full_datapoint=_TEST_RETURN_FULL_DATAPOINT, )