mirror of
https://github.com/infiniflow/ragflow.git
synced 2026-08-14 20:54:30 +08:00
## Summary This PR improves the RAGFlow agentic-search path in three areas: it stops the outer agent from re-looping over the same rag call, lets the medium thinking mode discover and follow new sub-claims mid-loop, and strengthens retrieval by having the LLM emit synonym-rich queries with time/date/number terms boosted. 1. Avoid the outer re-loop — keep all multi-hop cycles inside agentic RAG 2. Dynamic claims in medium mode — keep querying newly discovered sub-questions medium now enables allows_dynamic_claims. During orchestration, when claim analysis discovers a new required sub-question (discovered_claims), the loop spawns it as a new ClaimTarget and continues searching it in subsequent cycles (bounded by the dynamic-claim budget) instead of stopping. Also added: 3. Stronger query strategy — synonym-rich queries + time/date/number weighting LLM-generated synonyms: the claim-analysis prompt now instructs the model to write each next_queries entry as a retrieval-boosted query that actively folds in entity aliases, DATE/TIME synonyms (e.g. 1994 → 1994, 66th Academy Awards), and number/unit variants (e.g. 1.95 m → 6 ft 5 in). Time/date/number boosting: query.py boosts numeric/date tokens to a high weight (_NUM_DATE_TOKEN_RE).
113 lines
3.4 KiB
Python
113 lines
3.4 KiB
Python
"""Thinking mode configurations."""
|
|
|
|
from rag.advanced_rag.harness.types import ExecutionStrategy
|
|
|
|
THINKING_MODES: dict[str, ExecutionStrategy] = {
|
|
"low": ExecutionStrategy(
|
|
label="low",
|
|
execution_strategy="direct_search",
|
|
requires_decomposition=False,
|
|
requires_agent_loop=False,
|
|
requires_sufficiency_judge=False,
|
|
requires_selective_gen=False,
|
|
allows_dynamic_claims=False,
|
|
allows_replan=False,
|
|
max_orchestrator_cycles=1,
|
|
max_agent_cycles=0,
|
|
max_parallel_agents=1,
|
|
available_tools=["hybrid_search", "web_search", "bm25_search"],
|
|
sufficiency_threshold=0.85,
|
|
fallback_to_direct_llm=False,
|
|
),
|
|
"medium": ExecutionStrategy(
|
|
label="medium",
|
|
execution_strategy="decompose_and_search",
|
|
requires_decomposition=True,
|
|
requires_agent_loop=False,
|
|
requires_sufficiency_judge=True,
|
|
requires_selective_gen=True,
|
|
allows_dynamic_claims=True,
|
|
allows_replan=False,
|
|
max_orchestrator_cycles=3,
|
|
max_agent_cycles=0,
|
|
max_parallel_agents=1,
|
|
available_tools=["hybrid_search", "web_search", "bm25_search"],
|
|
sufficiency_threshold=0.75,
|
|
fallback_to_direct_llm=False,
|
|
c_high=0.75,
|
|
c_low=0.45,
|
|
llm_floor=0.55,
|
|
allows_reconcile=False,
|
|
),
|
|
"high": ExecutionStrategy(
|
|
label="high",
|
|
execution_strategy="agentic_research",
|
|
requires_decomposition=True,
|
|
requires_agent_loop=False,
|
|
requires_sufficiency_judge=True,
|
|
requires_selective_gen=True,
|
|
allows_dynamic_claims=False,
|
|
allows_replan=False,
|
|
max_orchestrator_cycles=3,
|
|
max_agent_cycles=2,
|
|
max_parallel_agents=2,
|
|
available_tools=[
|
|
"hybrid_search",
|
|
"web_search",
|
|
"bm25_search",
|
|
"ontology_navigate",
|
|
"dataset_navigation_by_tree",
|
|
"graph_explore",
|
|
"inspector_open_context",
|
|
"inspector_compare",
|
|
],
|
|
sufficiency_threshold=0.65,
|
|
fallback_to_direct_llm=False,
|
|
c_high=0.70,
|
|
c_low=0.40,
|
|
llm_floor=0.50,
|
|
allows_reconcile=True,
|
|
),
|
|
"ultra": ExecutionStrategy(
|
|
label="ultra",
|
|
execution_strategy="deep_research",
|
|
requires_decomposition=True,
|
|
requires_agent_loop=True,
|
|
requires_sufficiency_judge=True,
|
|
requires_selective_gen=True,
|
|
allows_dynamic_claims=True,
|
|
allows_replan=True,
|
|
max_orchestrator_cycles=4,
|
|
max_agent_cycles=2,
|
|
max_parallel_agents=3,
|
|
available_tools=[
|
|
"hybrid_search",
|
|
"bm25_search",
|
|
"web_search",
|
|
"structured_query",
|
|
"ontology_navigate",
|
|
"dataset_navigation_by_tree",
|
|
"mindmap_navigate",
|
|
"graph_explore",
|
|
"wiki_query",
|
|
"inspector_open_context",
|
|
"inspector_compare",
|
|
"inspector_grep_within",
|
|
"inspector_request_adjacent",
|
|
],
|
|
sufficiency_threshold=0.55,
|
|
fallback_to_direct_llm=True,
|
|
c_high=0.65,
|
|
c_low=0.35,
|
|
llm_floor=0.45,
|
|
allows_reconcile=True,
|
|
),
|
|
}
|
|
|
|
|
|
def get_mode(label: str) -> ExecutionStrategy:
|
|
mode = THINKING_MODES.get(label)
|
|
if not mode:
|
|
raise ValueError(f"Unknown thinking mode: {label}. Available: {list(THINKING_MODES.keys())}")
|
|
return mode
|