Coverage for src/local_deep_research/advanced_search_system/questions/flexible_browsecomp_question.py: 98%
27 statements
« prev ^ index » next coverage.py v7.16.0, created at 2026-09-06 15:42 +0000
« prev ^ index » next coverage.py v7.16.0, created at 2026-09-06 15:42 +0000
1"""
2Flexible BrowseComp question generator with less prescriptive instructions.
4Inherits from BrowseComp but gives the LLM more freedom in search strategy.
5"""
7from typing import Dict, List
9from ...utilities.json_utils import get_llm_response_text
10from .browsecomp_question import BrowseCompQuestionGenerator
13class FlexibleBrowseCompQuestionGenerator(BrowseCompQuestionGenerator):
14 """
15 BrowseComp variant with simplified, less prescriptive prompts.
17 Gives the LLM more freedom to explore different search strategies
18 instead of strict entity-combination rules.
19 """
21 def _generate_progressive_searches(
22 self,
23 query: str,
24 current_knowledge: str,
25 entities: Dict[str, List[str]],
26 questions_by_iteration: dict,
27 results_by_iteration: dict,
28 num_questions: int,
29 iteration: int,
30 ) -> List[str]:
31 """Generate searches with more freedom and less rigid instructions."""
33 # Check if recent searches are failing
34 recent_iterations = list(range(max(1, iteration - 5), iteration))
35 zero_count = sum(
36 1 for i in recent_iterations if results_by_iteration.get(i, 1) == 0
37 )
38 searches_failing = zero_count >= 3
40 # Simpler strategy hint
41 if searches_failing:
42 hint = "Recent searches returned 0 results. Try broader, simpler queries."
43 else:
44 hint = "Continue exploring to answer the query."
46 # Much simpler prompt - less prescriptive
47 prompt = f"""Generate {num_questions} new search queries for: {query}
49{hint}
51Available terms: {", ".join(entities["names"] + entities["temporal"] + entities["descriptors"])}
53Previous searches with results:
54{self._format_previous_searches(questions_by_iteration, results_by_iteration)}
56Current findings:
57{current_knowledge[: self.knowledge_truncate_length] if self.knowledge_truncate_length else current_knowledge}
59Create {num_questions} diverse search queries. Avoid exact duplicates. One per line.
60"""
62 response = self.model.invoke(prompt)
63 content = get_llm_response_text(response)
65 # Extract searches
66 searches = []
67 for line in content.strip().split("\n"):
68 line = line.strip()
69 if line and not line.endswith(":") and len(line) > 5:
70 for prefix in [
71 "Q:",
72 "Search:",
73 "-",
74 "*",
75 "•",
76 "1.",
77 "2.",
78 "3.",
79 "4.",
80 "5.",
81 ]:
82 if line.startswith(prefix):
83 line = line[len(prefix) :].strip()
84 if line: 84 ↛ 67line 84 didn't jump to line 67 because the condition on line 84 was always true
85 searches.append(line)
87 # If not enough, fall back to parent's logic
88 if len(searches) < num_questions:
89 parent_searches = super()._generate_progressive_searches(
90 query,
91 current_knowledge,
92 entities,
93 questions_by_iteration,
94 results_by_iteration,
95 num_questions - len(searches),
96 iteration,
97 )
98 searches.extend(parent_searches)
100 return searches[:num_questions]