feat(semantic-search): add a minScore relevance floor on the semantic kNN path - #19270
Conversation
|
Linear: CAT-2970 Thanks for your contribution! We have created an internal ticket to track this PR. A member of the core DataHub team will be assigned to review it within the next few business days - you will get a follow-up comment once a reviewer is assigned. |
There was a problem hiding this comment.
1 issue found across 6 files
Prompt for AI agents (unresolved issues)
Check if these issues are valid — if so, understand the root cause of each and fix them. If appropriate, use sub-agents to investigate and fix each issue separately.
<file name="metadata-io/src/test/java/com/linkedin/metadata/search/semantic/SemanticEntitySearchServiceTest.java">
<violation number="1" location="metadata-io/src/test/java/com/linkedin/metadata/search/semantic/SemanticEntitySearchServiceTest.java:227">
P2: Custom agent: **Enforce Pragmatic Test Coverage**
testSearchAppliesMinScoreFloor only covers the partial-drop path (0.95/0.80 kept, 0.50 dropped). The PR's core claim — an off-topic query with a floor returns nothing — is untested: no test drops all hits and asserts an empty result. Also, the test asserts only that retained scores are >= 0.75, not the exact values, and never covers a hit exactly at the floor even though the implementation keeps scores >= minScore. Add a case where every hit falls below the floor and assert numEntities 0 / empty entities, and cover the exact-value and equal-to-floor boundaries.</violation>
</file>
Reply with feedback, questions, or to request a fix.
Re-trigger cubic
| @@ -224,6 +224,27 @@ public void testSearchPagination() throws IOException { | |||
| assertEquals(result.getEntities().size(), 2); // Page size | |||
| } | |||
|
|
|||
| @Test | |||
There was a problem hiding this comment.
P2: Custom agent: Enforce Pragmatic Test Coverage
testSearchAppliesMinScoreFloor only covers the partial-drop path (0.95/0.80 kept, 0.50 dropped). The PR's core claim — an off-topic query with a floor returns nothing — is untested: no test drops all hits and asserts an empty result. Also, the test asserts only that retained scores are >= 0.75, not the exact values, and never covers a hit exactly at the floor even though the implementation keeps scores >= minScore. Add a case where every hit falls below the floor and assert numEntities 0 / empty entities, and cover the exact-value and equal-to-floor boundaries.
Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. At metadata-io/src/test/java/com/linkedin/metadata/search/semantic/SemanticEntitySearchServiceTest.java, line 227:
<comment>testSearchAppliesMinScoreFloor only covers the partial-drop path (0.95/0.80 kept, 0.50 dropped). The PR's core claim — an off-topic query with a floor returns nothing — is untested: no test drops all hits and asserts an empty result. Also, the test asserts only that retained scores are >= 0.75, not the exact values, and never covers a hit exactly at the floor even though the implementation keeps scores >= minScore. Add a case where every hit falls below the floor and assert numEntities 0 / empty entities, and cover the exact-value and equal-to-floor boundaries.</comment>
<file context>
@@ -224,6 +224,27 @@ public void testSearchPagination() throws IOException {
assertEquals(result.getEntities().size(), 2); // Page size
}
+ @Test
+ public void testSearchAppliesMinScoreFloor() throws IOException {
+ setupMockKnnResponse(
</file context>
Bundle ReportBundle size has no change ✅ |
… kNN path Adds an optional minScore to SearchFlags and honors it on the semantic (kNN) path. Hits scoring below the floor are dropped after the kNN returns, so a caller such as an agent can abstain (nothing is relevant enough) instead of surfacing weak matches. Post-kNN filtering keeps it engine-agnostic across the ES8 and OpenSearch shims. Wired end to end: model SearchFlags.pdl, the GraphQL SearchFlags input, and SearchFlagsInputMapper. When unset, behavior is unchanged.
b237262 to
2e41db6
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
alexsku
left a comment
There was a problem hiding this comment.
Nice — clean, well-scoped addition. Traced it end to end (GraphQL input → SearchFlagsInputMapper → opContext searchFlags → SemanticSearchService → SemanticEntitySearchService) and the wiring, the type plumbing, and the inclusive >= floor all check out. Optional and inert when unset, so it's a safe additive change. The doc note that the score is a raw, non-normalized engine value needing per-deployment calibration is exactly the right caveat to call out.
Approving. One thing I'd still like, non-blocking:
Test the empty path. testSearchAppliesMinScoreFloor only covers a partial drop (0.95/0.80 kept, 0.50 dropped). The whole point of the floor is the abstain case — an off-topic query returning nothing — and that's currently untested. Worth adding a case where every hit is below the floor asserting numEntities == 0 / empty entities, plus a hit exactly at the floor to pin the inclusive >= boundary. (Same thing the cubic bot flagged.)
Two minor notes, no action needed:
minScorelives on the sharedSearchFlagsinput, so a client that sets it on a keywordsearchAcrossEntitiesgets a silent no-op. It's documented, but a bit of a footgun on a shared type — might be worth a warn, or a semantic-specific input, down the line.- The floor runs on the oversampled candidate window before slicing, so
from > 0pages with a floor set can come back short / under-countnumEntities. Fine for the page-0 abstain use case, just flagging the interaction.
Adds an optional
minScoretoSearchFlagsand honors it on the semantic (kNN) search path. Hits scoring below the floor are dropped after the kNN returns, so a caller such as an agent can abstain ("nothing is relevant enough") instead of surfacing weak matches. An off-topic query that currently returns every result at a low score can now be given a floor so it returns nothing.Post-kNN filtering keeps this engine-agnostic across the ES8 and OpenSearch shims. Wired end to end: model
SearchFlags.pdl, the GraphQLSearchFlagsinput, andSearchFlagsInputMapper. When unset, no floor is applied and behavior is unchanged.Summary by cubic
Adds an optional minScore relevance floor on the semantic (kNN) search path to drop low-scoring hits. Previously the semantic path returned weak, off-topic hits; now callers can set a floor so results below it are removed and empty results are possible. When unset, behavior is unchanged.
Details
minScoreto GraphQLSearchFlagsand PegasusSearchFlags; maps throughSearchFlagsInputMapper.minScoreinSemanticEntitySearchServicebefore pagination; engine-agnostic across ES8 and OpenSearch.searchFlags: { minScore: <float> }. Tests cover mapping and filtering.Written for commit 2e41db6. Summary will update on new commits.