From 315d7de6332c5260621a9f3677aeb79fad9affaa Mon Sep 17 00:00:00 2001 From: Matt Gotteiner Date: Tue, 20 May 2025 14:48:10 -0700 Subject: [PATCH 01/12] sort references --- app/backend/approaches/approach.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/backend/approaches/approach.py b/app/backend/approaches/approach.py index bc2f918860..3d5bf44714 100644 --- a/app/backend/approaches/approach.py +++ b/app/backend/approaches/approach.py @@ -298,7 +298,8 @@ async def run_agentic_retrieval( results = [] if response and response.references: - for reference in response.references: + references = sorted(response.references, key=lambda reference: int(reference.id)) + for reference in references: if isinstance(reference, KnowledgeAgentAzureSearchDocReference) and reference.source_data: results.append( Document( From 4ad455b2c050655a08592e9056742d41dc321f4c Mon Sep 17 00:00:00 2001 From: Matt Gotteiner Date: Tue, 20 May 2025 15:34:30 -0700 Subject: [PATCH 02/12] UI fixds --- app/backend/approaches/approach.py | 3 +-- app/frontend/src/components/Settings/Settings.tsx | 4 ++-- app/frontend/src/pages/chat/Chat.tsx | 1 + 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/backend/approaches/approach.py b/app/backend/approaches/approach.py index 3d5bf44714..bc2f918860 100644 --- a/app/backend/approaches/approach.py +++ b/app/backend/approaches/approach.py @@ -298,8 +298,7 @@ async def run_agentic_retrieval( results = [] if response and response.references: - references = sorted(response.references, key=lambda reference: int(reference.id)) - for reference in references: + for reference in response.references: if isinstance(reference, KnowledgeAgentAzureSearchDocReference) and reference.source_data: results.append( Document( diff --git a/app/frontend/src/components/Settings/Settings.tsx b/app/frontend/src/components/Settings/Settings.tsx index 7d101abf36..b1ce226b84 100644 --- a/app/frontend/src/components/Settings/Settings.tsx +++ b/app/frontend/src/components/Settings/Settings.tsx @@ -218,8 +218,8 @@ export const Settings = ({ className={styles.settingsSeparator} label={t("labels.maxSubqueryCount")} type="number" - min={1} - max={20} + min={2} + max={40} defaultValue={maxSubqueryCount.toString()} onChange={(_ev, val) => onChange("maxSubqueryCount", parseInt(val || "10"))} aria-labelledby={maxSubqueryCountId} diff --git a/app/frontend/src/pages/chat/Chat.tsx b/app/frontend/src/pages/chat/Chat.tsx index 8813d5c4a7..ce17d97f90 100644 --- a/app/frontend/src/pages/chat/Chat.tsx +++ b/app/frontend/src/pages/chat/Chat.tsx @@ -215,6 +215,7 @@ const Chat = () => { include_category: includeCategory.length === 0 ? undefined : includeCategory, exclude_category: excludeCategory.length === 0 ? undefined : excludeCategory, top: retrieveCount, + max_subqueries: maxSubqueryCount, temperature: temperature, minimum_reranker_score: minimumRerankerScore, minimum_search_score: minimumSearchScore, From dcb43c5573a2ffd889736bad3eeb93bbb9f8c529 Mon Sep 17 00:00:00 2001 From: Matt Gotteiner Date: Tue, 20 May 2025 15:45:37 -0700 Subject: [PATCH 03/12] ui fixes --- app/frontend/src/pages/ask/Ask.tsx | 4 ++++ app/frontend/src/pages/chat/Chat.tsx | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/app/frontend/src/pages/ask/Ask.tsx b/app/frontend/src/pages/ask/Ask.tsx index 6a1fae1a2b..c6082bce8c 100644 --- a/app/frontend/src/pages/ask/Ask.tsx +++ b/app/frontend/src/pages/ask/Ask.tsx @@ -102,6 +102,10 @@ export function Component(): JSX.Element { setShowSpeechOutputAzure(config.showSpeechOutputAzure); setShowAgenticRetrievalOption(config.showAgenticRetrievalOption); setUseAgenticRetrieval(config.showAgenticRetrievalOption); + if (config.showAgenticRetrievalOption) { + setRetrieveCount(10); + setMinimumRerankerScore(1.5); + } }); }; diff --git a/app/frontend/src/pages/chat/Chat.tsx b/app/frontend/src/pages/chat/Chat.tsx index ce17d97f90..2d43b318bc 100644 --- a/app/frontend/src/pages/chat/Chat.tsx +++ b/app/frontend/src/pages/chat/Chat.tsx @@ -135,6 +135,10 @@ const Chat = () => { setShowChatHistoryCosmos(config.showChatHistoryCosmos); setShowAgenticRetrievalOption(config.showAgenticRetrievalOption); setUseAgenticRetrieval(config.showAgenticRetrievalOption); + if (config.showAgenticRetrievalOption) { + setRetrieveCount(10); + setMinimumRerankerScore(1.5); + } }); }; From 3f793ca9bf5a0ae995a66574c3d81f374c1d265f Mon Sep 17 00:00:00 2001 From: Matt Gotteiner Date: Tue, 20 May 2025 16:02:12 -0700 Subject: [PATCH 04/12] update defaults --- app/frontend/src/pages/ask/Ask.tsx | 2 +- app/frontend/src/pages/chat/Chat.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/frontend/src/pages/ask/Ask.tsx b/app/frontend/src/pages/ask/Ask.tsx index c6082bce8c..3642b1a76a 100644 --- a/app/frontend/src/pages/ask/Ask.tsx +++ b/app/frontend/src/pages/ask/Ask.tsx @@ -104,7 +104,7 @@ export function Component(): JSX.Element { setUseAgenticRetrieval(config.showAgenticRetrievalOption); if (config.showAgenticRetrievalOption) { setRetrieveCount(10); - setMinimumRerankerScore(1.5); + setMinimumRerankerScore(2.1); } }); }; diff --git a/app/frontend/src/pages/chat/Chat.tsx b/app/frontend/src/pages/chat/Chat.tsx index 2d43b318bc..33b196fc1a 100644 --- a/app/frontend/src/pages/chat/Chat.tsx +++ b/app/frontend/src/pages/chat/Chat.tsx @@ -137,7 +137,7 @@ const Chat = () => { setUseAgenticRetrieval(config.showAgenticRetrievalOption); if (config.showAgenticRetrievalOption) { setRetrieveCount(10); - setMinimumRerankerScore(1.5); + setMinimumRerankerScore(2.1); } }); }; From 6629e9dc7a0ff4a072c84c0cfd83211913ac8986 Mon Sep 17 00:00:00 2001 From: Matt Gotteiner Date: Tue, 20 May 2025 16:37:40 -0700 Subject: [PATCH 05/12] update --- app/backend/approaches/approach.py | 34 +++++++++++++++++----------- app/frontend/src/pages/ask/Ask.tsx | 4 ---- app/frontend/src/pages/chat/Chat.tsx | 4 ---- 3 files changed, 21 insertions(+), 21 deletions(-) diff --git a/app/backend/approaches/approach.py b/app/backend/approaches/approach.py index bc2f918860..1228a2ba1f 100644 --- a/app/backend/approaches/approach.py +++ b/app/backend/approaches/approach.py @@ -4,6 +4,7 @@ from dataclasses import dataclass from typing import Any, Callable, Optional, TypedDict, Union, cast from urllib.parse import urljoin +import json import aiohttp from azure.search.documents.agent.aio import KnowledgeAgentRetrievalClient @@ -297,19 +298,26 @@ async def run_agentic_retrieval( ) results = [] - if response and response.references: - for reference in response.references: - if isinstance(reference, KnowledgeAgentAzureSearchDocReference) and reference.source_data: - results.append( - Document( - id=reference.doc_key, - content=reference.source_data["content"], - sourcepage=reference.source_data["sourcepage"], - search_agent_query=activity_mapping[reference.activity_source], - ) - ) - if top and len(results) == top: - break + grounding_text = response.response[0].content[0].text + if response and grounding_text: + grounding_response = json.loads(grounding_text) + for grounding_reference in grounding_response: + ref_id = grounding_reference.get("ref_id") + if ref_id is not None: + ref_id = str(ref_id) + for reference in response.references: + if isinstance(reference, KnowledgeAgentAzureSearchDocReference) and reference.id == ref_id and reference.source_data: + results.append( + Document( + id=reference.doc_key, + content=reference.source_data["content"], + sourcepage=reference.source_data["sourcepage"], + search_agent_query=activity_mapping[reference.activity_source], + ) + ) + break + if top and len(results) == top: + break return response, results diff --git a/app/frontend/src/pages/ask/Ask.tsx b/app/frontend/src/pages/ask/Ask.tsx index 3642b1a76a..6a1fae1a2b 100644 --- a/app/frontend/src/pages/ask/Ask.tsx +++ b/app/frontend/src/pages/ask/Ask.tsx @@ -102,10 +102,6 @@ export function Component(): JSX.Element { setShowSpeechOutputAzure(config.showSpeechOutputAzure); setShowAgenticRetrievalOption(config.showAgenticRetrievalOption); setUseAgenticRetrieval(config.showAgenticRetrievalOption); - if (config.showAgenticRetrievalOption) { - setRetrieveCount(10); - setMinimumRerankerScore(2.1); - } }); }; diff --git a/app/frontend/src/pages/chat/Chat.tsx b/app/frontend/src/pages/chat/Chat.tsx index 33b196fc1a..ce17d97f90 100644 --- a/app/frontend/src/pages/chat/Chat.tsx +++ b/app/frontend/src/pages/chat/Chat.tsx @@ -135,10 +135,6 @@ const Chat = () => { setShowChatHistoryCosmos(config.showChatHistoryCosmos); setShowAgenticRetrievalOption(config.showAgenticRetrievalOption); setUseAgenticRetrieval(config.showAgenticRetrievalOption); - if (config.showAgenticRetrievalOption) { - setRetrieveCount(10); - setMinimumRerankerScore(2.1); - } }); }; From 0142757e9404f2dbcccc658eac3f5a4dca1243bc Mon Sep 17 00:00:00 2001 From: Matt Gotteiner Date: Tue, 20 May 2025 16:49:21 -0700 Subject: [PATCH 06/12] update --- app/frontend/src/pages/ask/Ask.tsx | 2 +- app/frontend/src/pages/chat/Chat.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/frontend/src/pages/ask/Ask.tsx b/app/frontend/src/pages/ask/Ask.tsx index 6a1fae1a2b..c1111fcb51 100644 --- a/app/frontend/src/pages/ask/Ask.tsx +++ b/app/frontend/src/pages/ask/Ask.tsx @@ -29,7 +29,7 @@ export function Component(): JSX.Element { const [minimumRerankerScore, setMinimumRerankerScore] = useState(0); const [minimumSearchScore, setMinimumSearchScore] = useState(0); const [retrievalMode, setRetrievalMode] = useState(RetrievalMode.Hybrid); - const [retrieveCount, setRetrieveCount] = useState(3); + const [retrieveCount, setRetrieveCount] = useState(10); const [maxSubqueryCount, setMaxSubqueryCount] = useState(10); const [useSemanticRanker, setUseSemanticRanker] = useState(true); const [useSemanticCaptions, setUseSemanticCaptions] = useState(false); diff --git a/app/frontend/src/pages/chat/Chat.tsx b/app/frontend/src/pages/chat/Chat.tsx index ce17d97f90..9d050e5ce8 100644 --- a/app/frontend/src/pages/chat/Chat.tsx +++ b/app/frontend/src/pages/chat/Chat.tsx @@ -45,7 +45,7 @@ const Chat = () => { const [seed, setSeed] = useState(null); const [minimumRerankerScore, setMinimumRerankerScore] = useState(0); const [minimumSearchScore, setMinimumSearchScore] = useState(0); - const [retrieveCount, setRetrieveCount] = useState(3); + const [retrieveCount, setRetrieveCount] = useState(10); const [maxSubqueryCount, setMaxSubqueryCount] = useState(10); const [retrievalMode, setRetrievalMode] = useState(RetrievalMode.Hybrid); const [useSemanticRanker, setUseSemanticRanker] = useState(true); From e8850d0905d338cdafbcf8e76925758c598f07ea Mon Sep 17 00:00:00 2001 From: Matt Gotteiner Date: Tue, 20 May 2025 17:25:36 -0700 Subject: [PATCH 07/12] update --- app/backend/approaches/approach.py | 34 ++++++++++++------------------ 1 file changed, 14 insertions(+), 20 deletions(-) diff --git a/app/backend/approaches/approach.py b/app/backend/approaches/approach.py index 1228a2ba1f..d817270798 100644 --- a/app/backend/approaches/approach.py +++ b/app/backend/approaches/approach.py @@ -298,26 +298,20 @@ async def run_agentic_retrieval( ) results = [] - grounding_text = response.response[0].content[0].text - if response and grounding_text: - grounding_response = json.loads(grounding_text) - for grounding_reference in grounding_response: - ref_id = grounding_reference.get("ref_id") - if ref_id is not None: - ref_id = str(ref_id) - for reference in response.references: - if isinstance(reference, KnowledgeAgentAzureSearchDocReference) and reference.id == ref_id and reference.source_data: - results.append( - Document( - id=reference.doc_key, - content=reference.source_data["content"], - sourcepage=reference.source_data["sourcepage"], - search_agent_query=activity_mapping[reference.activity_source], - ) - ) - break - if top and len(results) == top: - break + if response and response.references: + references = sorted(response.references, key=lambda reference: int(reference.id)) + for reference in references: + if isinstance(reference, KnowledgeAgentAzureSearchDocReference) and reference.source_data: + results.append( + Document( + id=reference.doc_key, + content=reference.source_data["content"], + sourcepage=reference.source_data["sourcepage"], + search_agent_query=activity_mapping[reference.activity_source], + ) + ) + if top and len(results) == top: + break return response, results From 1f98b80582ee60ccfc95879463dffda0f6bdda03 Mon Sep 17 00:00:00 2001 From: Matt Gotteiner Date: Tue, 20 May 2025 17:27:03 -0700 Subject: [PATCH 08/12] update --- app/backend/approaches/approach.py | 1 - 1 file changed, 1 deletion(-) diff --git a/app/backend/approaches/approach.py b/app/backend/approaches/approach.py index d817270798..3d5bf44714 100644 --- a/app/backend/approaches/approach.py +++ b/app/backend/approaches/approach.py @@ -4,7 +4,6 @@ from dataclasses import dataclass from typing import Any, Callable, Optional, TypedDict, Union, cast from urllib.parse import urljoin -import json import aiohttp from azure.search.documents.agent.aio import KnowledgeAgentRetrievalClient From 5bf8b9668b719c3c88e1938e7520de528b514923 Mon Sep 17 00:00:00 2001 From: Matt Gotteiner Date: Tue, 20 May 2025 17:38:02 -0700 Subject: [PATCH 09/12] update --- app/frontend/src/pages/ask/Ask.tsx | 5 ++++- app/frontend/src/pages/chat/Chat.tsx | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/app/frontend/src/pages/ask/Ask.tsx b/app/frontend/src/pages/ask/Ask.tsx index c1111fcb51..000a723295 100644 --- a/app/frontend/src/pages/ask/Ask.tsx +++ b/app/frontend/src/pages/ask/Ask.tsx @@ -29,7 +29,7 @@ export function Component(): JSX.Element { const [minimumRerankerScore, setMinimumRerankerScore] = useState(0); const [minimumSearchScore, setMinimumSearchScore] = useState(0); const [retrievalMode, setRetrievalMode] = useState(RetrievalMode.Hybrid); - const [retrieveCount, setRetrieveCount] = useState(10); + const [retrieveCount, setRetrieveCount] = useState(3); const [maxSubqueryCount, setMaxSubqueryCount] = useState(10); const [useSemanticRanker, setUseSemanticRanker] = useState(true); const [useSemanticCaptions, setUseSemanticCaptions] = useState(false); @@ -102,6 +102,9 @@ export function Component(): JSX.Element { setShowSpeechOutputAzure(config.showSpeechOutputAzure); setShowAgenticRetrievalOption(config.showAgenticRetrievalOption); setUseAgenticRetrieval(config.showAgenticRetrievalOption); + if (config.showAgenticRetrievalOption) { + setRetrieveCount(10); + } }); }; diff --git a/app/frontend/src/pages/chat/Chat.tsx b/app/frontend/src/pages/chat/Chat.tsx index 9d050e5ce8..df4c70414c 100644 --- a/app/frontend/src/pages/chat/Chat.tsx +++ b/app/frontend/src/pages/chat/Chat.tsx @@ -45,7 +45,7 @@ const Chat = () => { const [seed, setSeed] = useState(null); const [minimumRerankerScore, setMinimumRerankerScore] = useState(0); const [minimumSearchScore, setMinimumSearchScore] = useState(0); - const [retrieveCount, setRetrieveCount] = useState(10); + const [retrieveCount, setRetrieveCount] = useState(3); const [maxSubqueryCount, setMaxSubqueryCount] = useState(10); const [retrievalMode, setRetrievalMode] = useState(RetrievalMode.Hybrid); const [useSemanticRanker, setUseSemanticRanker] = useState(true); @@ -135,6 +135,9 @@ const Chat = () => { setShowChatHistoryCosmos(config.showChatHistoryCosmos); setShowAgenticRetrievalOption(config.showAgenticRetrievalOption); setUseAgenticRetrieval(config.showAgenticRetrievalOption); + if (config.showAgenticRetrievalOption) { + setRetrieveCount(10); + } }); }; From 25b93a5e0e2386f0b0f7656e6e5e4e45d8492558 Mon Sep 17 00:00:00 2001 From: Matt Gotteiner Date: Tue, 20 May 2025 21:52:33 -0700 Subject: [PATCH 10/12] Add results merge strategy --- app/backend/approaches/approach.py | 8 ++++++- .../approaches/chatreadretrieveread.py | 2 ++ app/backend/approaches/retrievethenread.py | 2 ++ app/frontend/src/api/models.ts | 1 + .../src/components/Settings/Settings.tsx | 21 +++++++++++++++++++ app/frontend/src/locales/en/translation.json | 7 +++++++ app/frontend/src/pages/ask/Ask.tsx | 6 ++++++ app/frontend/src/pages/chat/Chat.tsx | 6 ++++++ 8 files changed, 52 insertions(+), 1 deletion(-) diff --git a/app/backend/approaches/approach.py b/app/backend/approaches/approach.py index 3d5bf44714..7dc81814bd 100644 --- a/app/backend/approaches/approach.py +++ b/app/backend/approaches/approach.py @@ -261,6 +261,7 @@ async def run_agentic_retrieval( filter_add_on: Optional[str] = None, minimum_reranker_score: Optional[float] = None, max_docs_for_reranker: Optional[int] = None, + results_merge_strategy: Optional[str] = None, ) -> tuple[KnowledgeAgentRetrievalResponse, list[Document]]: # STEP 1: Invoke agentic retrieval response = await agent_client.retrieve( @@ -298,7 +299,12 @@ async def run_agentic_retrieval( results = [] if response and response.references: - references = sorted(response.references, key=lambda reference: int(reference.id)) + if results_merge_strategy == "interleaved": + # Use interleaved reference order + references = sorted(response.references, key=lambda reference: int(reference.id)) + else: + # Default to descending strategy + references = response.references for reference in references: if isinstance(reference, KnowledgeAgentAzureSearchDocReference) and reference.source_data: results.append( diff --git a/app/backend/approaches/chatreadretrieveread.py b/app/backend/approaches/chatreadretrieveread.py index 772529ec7d..fbdf01bdd2 100644 --- a/app/backend/approaches/chatreadretrieveread.py +++ b/app/backend/approaches/chatreadretrieveread.py @@ -235,6 +235,7 @@ async def run_agentic_retrieval_approach( search_index_filter = self.build_filter(overrides, auth_claims) top = overrides.get("top", 3) max_subqueries = overrides.get("max_subqueries", 10) + results_merge_strategy = overrides.get("results_merge_strategy", "interleaved") # 50 is the amount of documents that the reranker can process per query max_docs_for_reranker = max_subqueries * 50 @@ -246,6 +247,7 @@ async def run_agentic_retrieval_approach( filter_add_on=search_index_filter, minimum_reranker_score=minimum_reranker_score, max_docs_for_reranker=max_docs_for_reranker, + results_merge_strategy=results_merge_strategy, ) text_sources = self.get_sources_content(results, use_semantic_captions=False, use_image_citation=False) diff --git a/app/backend/approaches/retrievethenread.py b/app/backend/approaches/retrievethenread.py index 032fa1a90c..769027b232 100644 --- a/app/backend/approaches/retrievethenread.py +++ b/app/backend/approaches/retrievethenread.py @@ -186,6 +186,7 @@ async def run_agentic_retrieval_approach( search_index_filter = self.build_filter(overrides, auth_claims) top = overrides.get("top", 3) max_subqueries = overrides.get("max_subqueries", 10) + results_merge_strategy = overrides.get("results_merge_strategy", "interleaved") # 50 is the amount of documents that the reranker can process per query max_docs_for_reranker = max_subqueries * 50 @@ -197,6 +198,7 @@ async def run_agentic_retrieval_approach( filter_add_on=search_index_filter, minimum_reranker_score=minimum_reranker_score, max_docs_for_reranker=max_docs_for_reranker, + results_merge_strategy=results_merge_strategy, ) text_sources = self.get_sources_content(results, use_semantic_captions=False, use_image_citation=False) diff --git a/app/frontend/src/api/models.ts b/app/frontend/src/api/models.ts index d6014ba25f..63ff5c31f4 100644 --- a/app/frontend/src/api/models.ts +++ b/app/frontend/src/api/models.ts @@ -27,6 +27,7 @@ export type ChatAppRequestOverrides = { seed?: number; top?: number; max_subqueries?: number; + results_merge_strategy?: string; temperature?: number; minimum_search_score?: number; minimum_reranker_score?: number; diff --git a/app/frontend/src/components/Settings/Settings.tsx b/app/frontend/src/components/Settings/Settings.tsx index b1ce226b84..a1c4f46632 100644 --- a/app/frontend/src/components/Settings/Settings.tsx +++ b/app/frontend/src/components/Settings/Settings.tsx @@ -15,6 +15,7 @@ export interface SettingsProps { temperature: number; retrieveCount: number; maxSubqueryCount: number; + resultsMergeStrategy: string; seed: number | null; minimumSearchScore: number; minimumRerankerScore: number; @@ -55,6 +56,7 @@ export const Settings = ({ temperature, retrieveCount, maxSubqueryCount, + resultsMergeStrategy, seed, minimumSearchScore, minimumRerankerScore, @@ -108,6 +110,7 @@ export const Settings = ({ const retrieveCountFieldId = useId("retrieveCountField"); const maxSubqueryCountId = useId("maxSubqueryCount"); const maxSubqueryCountFieldId = useId("maxSubqueryCountField"); + const resultsMergeStrategyFieldId = useId("resultsMergeStrategy"); const includeCategoryId = useId("includeCategory"); const includeCategoryFieldId = useId("includeCategoryField"); const excludeCategoryId = useId("excludeCategory"); @@ -227,6 +230,24 @@ export const Settings = ({ /> )} + {showAgenticRetrievalOption && useAgenticRetrieval && ( + , option?: IDropdownOption) => + onChange("resultsMergeStrategy", option?.key) + } + aria-labelledby={includeCategoryId} + options={[ + { key: "interleaved", text: t("labels.resultsMergeStrategyOptions.interleaved") }, + { key: "descending", text: t("labels.resultsMergeStrategyOptions.descending") } + ]} + onRenderLabel={props => renderLabel(props, includeCategoryId, includeCategoryFieldId, t("helpTexts.resultsMergeStrategy"))} + /> + )} + (RetrievalMode.Hybrid); const [retrieveCount, setRetrieveCount] = useState(3); const [maxSubqueryCount, setMaxSubqueryCount] = useState(10); + const [resultsMergeStrategy, setResultsMergeStrategy] = useState("interleaved"); const [useSemanticRanker, setUseSemanticRanker] = useState(true); const [useSemanticCaptions, setUseSemanticCaptions] = useState(false); const [useQueryRewriting, setUseQueryRewriting] = useState(false); @@ -139,6 +140,7 @@ export function Component(): JSX.Element { exclude_category: excludeCategory.length === 0 ? undefined : excludeCategory, top: retrieveCount, max_subqueries: maxSubqueryCount, + results_merge_strategy: resultsMergeStrategy, temperature: temperature, minimum_reranker_score: minimumRerankerScore, minimum_search_score: minimumSearchScore, @@ -199,6 +201,9 @@ export function Component(): JSX.Element { case "maxSubqueryCount": setMaxSubqueryCount(value); break; + case "resultsMergeStrategy": + setResultsMergeStrategy(value); + break; case "useSemanticRanker": setUseSemanticRanker(value); break; @@ -350,6 +355,7 @@ export function Component(): JSX.Element { temperature={temperature} retrieveCount={retrieveCount} maxSubqueryCount={maxSubqueryCount} + resultsMergeStrategy={resultsMergeStrategy} seed={seed} minimumSearchScore={minimumSearchScore} minimumRerankerScore={minimumRerankerScore} diff --git a/app/frontend/src/pages/chat/Chat.tsx b/app/frontend/src/pages/chat/Chat.tsx index df4c70414c..579ad05fea 100644 --- a/app/frontend/src/pages/chat/Chat.tsx +++ b/app/frontend/src/pages/chat/Chat.tsx @@ -47,6 +47,7 @@ const Chat = () => { const [minimumSearchScore, setMinimumSearchScore] = useState(0); const [retrieveCount, setRetrieveCount] = useState(3); const [maxSubqueryCount, setMaxSubqueryCount] = useState(10); + const [resultsMergeStrategy, setResultsMergeStrategy] = useState("interleaved"); const [retrievalMode, setRetrievalMode] = useState(RetrievalMode.Hybrid); const [useSemanticRanker, setUseSemanticRanker] = useState(true); const [useQueryRewriting, setUseQueryRewriting] = useState(false); @@ -219,6 +220,7 @@ const Chat = () => { exclude_category: excludeCategory.length === 0 ? undefined : excludeCategory, top: retrieveCount, max_subqueries: maxSubqueryCount, + results_merge_strategy: resultsMergeStrategy, temperature: temperature, minimum_reranker_score: minimumRerankerScore, minimum_search_score: minimumSearchScore, @@ -316,6 +318,9 @@ const Chat = () => { case "maxSubqueryCount": setMaxSubqueryCount(value); break; + case "resultsMergeStrategy": + setResultsMergeStrategy(value); + break; case "useSemanticRanker": setUseSemanticRanker(value); break; @@ -538,6 +543,7 @@ const Chat = () => { temperature={temperature} retrieveCount={retrieveCount} maxSubqueryCount={maxSubqueryCount} + resultsMergeStrategy={resultsMergeStrategy} seed={seed} minimumSearchScore={minimumSearchScore} minimumRerankerScore={minimumRerankerScore} From 9f04690cbea591c366e4b2b93e596040c5763df1 Mon Sep 17 00:00:00 2001 From: Matt Gotteiner Date: Tue, 20 May 2025 22:34:03 -0700 Subject: [PATCH 11/12] Add results merge strategy to thought process --- app/backend/approaches/chatreadretrieveread.py | 1 + app/backend/approaches/retrievethenread.py | 1 + 2 files changed, 2 insertions(+) diff --git a/app/backend/approaches/chatreadretrieveread.py b/app/backend/approaches/chatreadretrieveread.py index fbdf01bdd2..ed87976e3b 100644 --- a/app/backend/approaches/chatreadretrieveread.py +++ b/app/backend/approaches/chatreadretrieveread.py @@ -261,6 +261,7 @@ async def run_agentic_retrieval_approach( { "reranker_threshold": minimum_reranker_score, "max_docs_for_reranker": max_docs_for_reranker, + "results_merge_strategy": results_merge_strategy, "filter": search_index_filter, }, ), diff --git a/app/backend/approaches/retrievethenread.py b/app/backend/approaches/retrievethenread.py index 769027b232..d59f903b0e 100644 --- a/app/backend/approaches/retrievethenread.py +++ b/app/backend/approaches/retrievethenread.py @@ -212,6 +212,7 @@ async def run_agentic_retrieval_approach( { "reranker_threshold": minimum_reranker_score, "max_docs_for_reranker": max_docs_for_reranker, + "results_merge_strategy": results_merge_strategy, "filter": search_index_filter, }, ), From 8426a21b4b20f14dc3bc15f1a3407744b00e7c28 Mon Sep 17 00:00:00 2001 From: Matt Gotteiner Date: Wed, 21 May 2025 08:33:22 -0700 Subject: [PATCH 12/12] update snapshots --- .../test_app/test_ask_rtr_text_agent/agent_client0/result.json | 3 ++- .../agent_auth_client0/result.json | 3 ++- .../test_app/test_chat_text_agent/agent_client0/result.json | 3 ++- .../test_chat_text_filter_agent/agent_auth_client0/result.json | 3 ++- 4 files changed, 8 insertions(+), 4 deletions(-) diff --git a/tests/snapshots/test_app/test_ask_rtr_text_agent/agent_client0/result.json b/tests/snapshots/test_app/test_ask_rtr_text_agent/agent_client0/result.json index 827d9ace6d..ec9bbf3360 100644 --- a/tests/snapshots/test_app/test_ask_rtr_text_agent/agent_client0/result.json +++ b/tests/snapshots/test_app/test_ask_rtr_text_agent/agent_client0/result.json @@ -18,7 +18,8 @@ "props": { "filter": null, "max_docs_for_reranker": 500, - "reranker_threshold": 0 + "reranker_threshold": 0, + "results_merge_strategy": "interleaved" }, "title": "Use agentic retrieval" }, diff --git a/tests/snapshots/test_app/test_ask_rtr_text_agent_filter/agent_auth_client0/result.json b/tests/snapshots/test_app/test_ask_rtr_text_agent_filter/agent_auth_client0/result.json index 909fbe1fda..029348cb23 100644 --- a/tests/snapshots/test_app/test_ask_rtr_text_agent_filter/agent_auth_client0/result.json +++ b/tests/snapshots/test_app/test_ask_rtr_text_agent_filter/agent_auth_client0/result.json @@ -18,7 +18,8 @@ "props": { "filter": "category ne 'excluded' and (oids/any(g:search.in(g, 'OID_X')) or groups/any(g:search.in(g, 'GROUP_Y, GROUP_Z')))", "max_docs_for_reranker": 500, - "reranker_threshold": 0 + "reranker_threshold": 0, + "results_merge_strategy": "interleaved" }, "title": "Use agentic retrieval" }, diff --git a/tests/snapshots/test_app/test_chat_text_agent/agent_client0/result.json b/tests/snapshots/test_app/test_chat_text_agent/agent_client0/result.json index 9e618d61b1..5f813bd45d 100644 --- a/tests/snapshots/test_app/test_chat_text_agent/agent_client0/result.json +++ b/tests/snapshots/test_app/test_chat_text_agent/agent_client0/result.json @@ -18,7 +18,8 @@ "props": { "filter": null, "max_docs_for_reranker": 500, - "reranker_threshold": 0 + "reranker_threshold": 0, + "results_merge_strategy": "interleaved" }, "title": "Use agentic retrieval" }, diff --git a/tests/snapshots/test_app/test_chat_text_filter_agent/agent_auth_client0/result.json b/tests/snapshots/test_app/test_chat_text_filter_agent/agent_auth_client0/result.json index 40e7000667..1069d6870e 100644 --- a/tests/snapshots/test_app/test_chat_text_filter_agent/agent_auth_client0/result.json +++ b/tests/snapshots/test_app/test_chat_text_filter_agent/agent_auth_client0/result.json @@ -18,7 +18,8 @@ "props": { "filter": "category ne 'excluded' and (oids/any(g:search.in(g, 'OID_X')) or groups/any(g:search.in(g, 'GROUP_Y, GROUP_Z')))", "max_docs_for_reranker": 500, - "reranker_threshold": 0 + "reranker_threshold": 0, + "results_merge_strategy": "interleaved" }, "title": "Use agentic retrieval" },