Reject generic pages for concrete research identifiers #391
@@ -1812,6 +1812,9 @@ func nearestFlightQuery(query string) bool {
|
||||
// search-engine snippets from becoming a human-facing answer when a search
|
||||
// term has a common non-travel meaning.
|
||||
func researchFindingMatchesIntent(query string, finding epistemics.ResearchFinding) bool {
|
||||
if !findingContainsRequestedIdentifier(query, finding) {
|
||||
return false
|
||||
}
|
||||
if !nearestFlightQuery(query) {
|
||||
return true
|
||||
}
|
||||
@@ -1841,6 +1844,24 @@ func researchFindingMatchesIntent(query string, finding epistemics.ResearchFindi
|
||||
return true
|
||||
}
|
||||
|
||||
// findingContainsRequestedIdentifier prevents a generic landing page from
|
||||
// being presented as a result for a concrete model, article or brand request.
|
||||
// Identifiers are detected by their syntax, not by a catalogue of providers or
|
||||
// entities, so the rule stays valid as user vocabulary changes.
|
||||
func findingContainsRequestedIdentifier(query string, finding epistemics.ResearchFinding) bool {
|
||||
identifiers := regexp.MustCompile(`(?i)[a-z0-9][a-z0-9._-]{3,}`).FindAllString(query, -1)
|
||||
if len(identifiers) == 0 {
|
||||
return true
|
||||
}
|
||||
evidence := strings.ToLower(strings.Join([]string{finding.Source.Title, finding.Source.Locator, finding.Excerpt.Text}, " "))
|
||||
for _, identifier := range identifiers {
|
||||
if !strings.Contains(evidence, strings.ToLower(identifier)) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// nearestFlightRouteTerms retains only the two endpoint-shaped terms from a
|
||||
// structured flight search. It has no city or provider vocabulary: endpoint
|
||||
// relevance is determined from the request itself.
|
||||
|
||||
@@ -58,6 +58,30 @@ func TestNearestFlightEvidenceRequiresBothRouteEndpointsWhenKnown(t *testing.T)
|
||||
}
|
||||
}
|
||||
|
||||
func TestResearchReplyRejectsGenericLandingPageForConcreteIdentifier(t *testing.T) {
|
||||
result := epistemics.ResearchResult{Findings: []epistemics.ResearchFinding{{
|
||||
State: epistemics.FindingSupported,
|
||||
Source: epistemics.Source{Locator: "https://market.example", Title: "Интернет-магазин"},
|
||||
Excerpt: epistemics.SourceExcerpt{Text: "Широкий ассортимент товаров и услуг."},
|
||||
}}}
|
||||
reply, backed := renderResearchReply("на WB бренд marka-wear", result, nil)
|
||||
if backed || !strings.Contains(reply, "Проверяемых данных") {
|
||||
t.Fatalf("generic page was presented as a brand result: %q", reply)
|
||||
}
|
||||
}
|
||||
|
||||
func TestResearchReplyKeepsFindingContainingConcreteIdentifier(t *testing.T) {
|
||||
result := epistemics.ResearchResult{Findings: []epistemics.ResearchFinding{{
|
||||
State: epistemics.FindingSupported,
|
||||
Source: epistemics.Source{Locator: "https://market.example/marka-wear", Title: "Marka-wear"},
|
||||
Excerpt: epistemics.SourceExcerpt{Text: "Бренд marka-wear: товары и карточки."},
|
||||
}}}
|
||||
reply, backed := renderResearchReply("на WB бренд marka-wear", result, nil)
|
||||
if !backed || !strings.Contains(strings.ToLower(reply), "marka-wear") {
|
||||
t.Fatalf("concrete identifier finding was rejected: %q", reply)
|
||||
}
|
||||
}
|
||||
|
||||
func TestResponseReviewPreservesAttemptedResearchOutcome(t *testing.T) {
|
||||
if reviewMayReplacePlanningReply(false, true, false, "Уточните аэропорт.", "Пока не смог получить проверяемый ответ.") {
|
||||
t.Fatal("review replaced an honest unbacked research outcome")
|
||||
|
||||
Reference in New Issue
Block a user