Remove dead code from iterative research planning refactor
This commit is contained in:
parent
42f2d0fd0e
commit
ac76ecee86
14 changed files with 20 additions and 76 deletions
|
|
@ -9,6 +9,13 @@
|
|||
- Simpler flow: `plan_next` → `search_one` → loop back until complete → `synthesize`
|
||||
- Consolidated `build_conversational_graph()` into `build_research_graph(output_mode="conversational")`
|
||||
|
||||
### Removed
|
||||
|
||||
- **Dead config options**: Removed vestigial fields from iterative planning refactor
|
||||
- `confidence_threshold` from `ResearchConfig` and `ResearchState` (LLM decides completion via `is_complete`)
|
||||
- `max_sub_questions` from `QAConfig` (iterative flow uses one question at a time)
|
||||
- `sub_questions` field from `ResearchContext` (no longer populated)
|
||||
|
||||
## [0.27.2] - 2026-01-29
|
||||
|
||||
### Added
|
||||
|
|
|
|||
|
|
@ -244,7 +244,6 @@ custom_config = AppConfig(
|
|||
provider="openai",
|
||||
model="gpt-4o-mini",
|
||||
max_iterations=5,
|
||||
confidence_threshold=0.85,
|
||||
max_concurrency=3,
|
||||
)
|
||||
)
|
||||
|
|
|
|||
|
|
@ -255,7 +255,7 @@ Flags:
|
|||
- `--context`: Background context for the research
|
||||
- `--context-file`: Path to a file containing background context
|
||||
|
||||
Research parameters like `max_iterations`, `confidence_threshold`, and `max_concurrency` are configured in your [configuration file](configuration/index.md) under the `research` section.
|
||||
Research parameters like `max_iterations` and `max_concurrency` are configured in your [configuration file](configuration/index.md) under the `research` section.
|
||||
|
||||
## Server
|
||||
|
||||
|
|
|
|||
|
|
@ -85,7 +85,6 @@ qa:
|
|||
provider: ollama
|
||||
name: gpt-oss
|
||||
enable_thinking: false
|
||||
max_sub_questions: 3
|
||||
max_iterations: 2
|
||||
max_concurrency: 1
|
||||
|
||||
|
|
@ -95,7 +94,6 @@ research:
|
|||
name: ""
|
||||
enable_thinking: false
|
||||
max_iterations: 3
|
||||
confidence_threshold: 0.8
|
||||
max_concurrency: 1
|
||||
|
||||
search:
|
||||
|
|
|
|||
|
|
@ -32,17 +32,15 @@ qa:
|
|||
provider: ollama
|
||||
name: gpt-oss
|
||||
enable_thinking: false
|
||||
max_sub_questions: 3 # Maximum sub-questions for deep QA
|
||||
max_iterations: 2 # Maximum search iterations per sub-question
|
||||
max_concurrency: 1 # Sub-questions processed in parallel
|
||||
max_iterations: 2 # Maximum search iterations
|
||||
max_concurrency: 1 # Concurrent search operations
|
||||
```
|
||||
|
||||
- **model**: LLM configuration (see [Providers](providers.md#model-settings))
|
||||
- **max_sub_questions**: For deep QA mode, maximum number of sub-questions to generate (default: 3)
|
||||
- **max_iterations**: Maximum search/evaluate cycles per sub-question (default: 2)
|
||||
- **max_concurrency**: Number of sub-questions to process in parallel (default: 1)
|
||||
- **max_iterations**: Maximum search iterations (default: 2)
|
||||
- **max_concurrency**: Number of concurrent search operations (default: 1)
|
||||
|
||||
Deep QA mode (`haiku-rag ask --deep`) decomposes complex questions into sub-questions, processes them in parallel batches, and synthesizes the results.
|
||||
Deep QA mode (`haiku-rag ask --deep`) uses the research graph with a single iteration for quick, focused answers.
|
||||
|
||||
## Research Configuration
|
||||
|
||||
|
|
@ -55,13 +53,11 @@ research:
|
|||
name: "" # Empty to use qa model
|
||||
enable_thinking: false
|
||||
max_iterations: 3
|
||||
confidence_threshold: 0.8
|
||||
max_concurrency: 1
|
||||
```
|
||||
|
||||
- **model**: LLM configuration. Leave provider/model empty to inherit from `qa` (see [Providers](providers.md#model-settings))
|
||||
- **max_iterations**: Maximum search/evaluate cycles (default: 3)
|
||||
- **confidence_threshold**: Stop when confidence score meets/exceeds this (default: 0.8)
|
||||
- **max_concurrency**: Sub-questions searched in parallel per iteration (default: 1)
|
||||
- **max_iterations**: Maximum planning/search iterations (default: 3)
|
||||
- **max_concurrency**: Concurrent search operations (default: 1)
|
||||
|
||||
The research workflow plans sub-questions, searches in parallel batches, evaluates findings, and iterates until reaching the confidence threshold or max iterations.
|
||||
The research workflow uses an iterative feedback loop: the planner proposes one question at a time, sees the answer, then decides whether to continue or synthesize. This continues until the planner marks research as complete or `max_iterations` is reached.
|
||||
|
|
|
|||
|
|
@ -249,7 +249,6 @@ def create_chat_agent(config: AppConfig) -> Agent[ChatDeps, str]:
|
|||
state = ResearchState(
|
||||
context=context,
|
||||
max_iterations=1,
|
||||
confidence_threshold=0.0,
|
||||
search_filter=doc_filter,
|
||||
max_concurrency=ctx.deps.config.research.max_concurrency,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -13,9 +13,6 @@ class ResearchContext(BaseModel):
|
|||
"""Context shared across research agents."""
|
||||
|
||||
original_question: str = Field(description="The original research question")
|
||||
sub_questions: list[str] = Field(
|
||||
default_factory=list, description="Decomposed sub-questions"
|
||||
)
|
||||
qa_responses: list[Any] = Field(
|
||||
default_factory=list, description="Structured QA pairs used during research"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -27,17 +27,8 @@ from haiku.rag.config.models import AppConfig
|
|||
from haiku.rag.utils import build_prompt, get_model
|
||||
|
||||
|
||||
def format_context_for_prompt(
|
||||
context: ResearchContext,
|
||||
include_pending_questions: bool = True,
|
||||
) -> str:
|
||||
"""Format the research context as XML for prompts.
|
||||
|
||||
Args:
|
||||
context: The research context to format.
|
||||
include_pending_questions: Whether to include pending sub-questions.
|
||||
Set to False for synthesis prompts where pending questions aren't relevant.
|
||||
"""
|
||||
def format_context_for_prompt(context: ResearchContext) -> str:
|
||||
"""Format the research context as XML for prompts."""
|
||||
context_data: dict[str, object] = {}
|
||||
|
||||
if context.session_context:
|
||||
|
|
@ -45,9 +36,6 @@ def format_context_for_prompt(
|
|||
|
||||
context_data["question"] = context.original_question
|
||||
|
||||
if include_pending_questions and context.sub_questions:
|
||||
context_data["pending_questions"] = context.sub_questions
|
||||
|
||||
if context.qa_responses:
|
||||
context_data["prior_answers"] = [
|
||||
{
|
||||
|
|
@ -267,9 +255,7 @@ def build_research_graph(
|
|||
deps_type=ResearchDependencies,
|
||||
)
|
||||
|
||||
context_xml = format_context_for_prompt(
|
||||
state.context, include_pending_questions=False
|
||||
)
|
||||
context_xml = format_context_for_prompt(state.context)
|
||||
prompt = (
|
||||
"Generate a comprehensive research report based on all gathered information.\n\n"
|
||||
f"{context_xml}\n\n"
|
||||
|
|
@ -301,9 +287,7 @@ def build_research_graph(
|
|||
deps_type=ResearchDependencies,
|
||||
)
|
||||
|
||||
context_xml = format_context_for_prompt(
|
||||
state.context, include_pending_questions=False
|
||||
)
|
||||
context_xml = format_context_for_prompt(state.context)
|
||||
prompt = (
|
||||
f"Answer the question based on the gathered evidence.\n\n{context_xml}"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -29,9 +29,6 @@ class ResearchState(BaseModel):
|
|||
)
|
||||
iterations: int = Field(default=0, description="Current iteration number")
|
||||
max_iterations: int = Field(default=3, description="Maximum allowed iterations")
|
||||
confidence_threshold: float = Field(
|
||||
default=0.8, description="Confidence threshold for completion", ge=0.0, le=1.0
|
||||
)
|
||||
max_concurrency: int = Field(
|
||||
default=1, description="Maximum concurrent search operations", ge=1
|
||||
)
|
||||
|
|
@ -45,7 +42,6 @@ class ResearchState(BaseModel):
|
|||
context: ResearchContext,
|
||||
config: "AppConfig",
|
||||
max_iterations: int | None = None,
|
||||
confidence_threshold: float | None = None,
|
||||
) -> "ResearchState":
|
||||
"""Create a ResearchState from an AppConfig.
|
||||
|
||||
|
|
@ -53,15 +49,11 @@ class ResearchState(BaseModel):
|
|||
context: The ResearchContext containing the question
|
||||
config: The AppConfig object
|
||||
max_iterations: Override max iterations (None uses config default)
|
||||
confidence_threshold: Override threshold (None uses config, 0.0 disables check)
|
||||
"""
|
||||
return cls(
|
||||
context=context,
|
||||
max_iterations=max_iterations
|
||||
if max_iterations is not None
|
||||
else config.research.max_iterations,
|
||||
confidence_threshold=confidence_threshold
|
||||
if confidence_threshold is not None
|
||||
else config.research.confidence_threshold,
|
||||
max_concurrency=config.research.max_concurrency,
|
||||
)
|
||||
|
|
|
|||
|
|
@ -399,7 +399,6 @@ class HaikuRAGApp:
|
|||
context=context,
|
||||
config=self.config,
|
||||
max_iterations=1,
|
||||
confidence_threshold=0.0,
|
||||
)
|
||||
state.search_filter = filter
|
||||
deps = ResearchDeps(client=self.client)
|
||||
|
|
|
|||
|
|
@ -78,7 +78,6 @@ class QAConfig(BaseModel):
|
|||
enable_thinking=False,
|
||||
)
|
||||
)
|
||||
max_sub_questions: int = 3
|
||||
max_iterations: int = 2
|
||||
max_concurrency: int = 1
|
||||
|
||||
|
|
@ -92,7 +91,6 @@ class ResearchConfig(BaseModel):
|
|||
)
|
||||
)
|
||||
max_iterations: int = 3
|
||||
confidence_threshold: float = 0.8
|
||||
max_concurrency: int = 1
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -199,7 +199,6 @@ def create_mcp_server(
|
|||
context=context,
|
||||
config=config,
|
||||
max_iterations=2,
|
||||
confidence_threshold=0.0,
|
||||
)
|
||||
deps = ResearchDeps(client=rag)
|
||||
|
||||
|
|
|
|||
|
|
@ -30,7 +30,6 @@ async def test_graph_end_to_end(allow_model_requests, temp_db_path, qa_corpus):
|
|||
state = ResearchState(
|
||||
context=ResearchContext(original_question=doc["question"]),
|
||||
max_iterations=1,
|
||||
confidence_threshold=0.5,
|
||||
max_concurrency=1,
|
||||
)
|
||||
|
||||
|
|
@ -155,27 +154,6 @@ def test_format_context_for_prompt_with_session_context():
|
|||
assert "What is Y?" in result
|
||||
|
||||
|
||||
def test_format_context_for_prompt_excludes_pending_questions():
|
||||
"""Test format_context_for_prompt can exclude pending questions."""
|
||||
from haiku.rag.agents.research.dependencies import ResearchContext
|
||||
from haiku.rag.agents.research.graph import format_context_for_prompt
|
||||
|
||||
context = ResearchContext(
|
||||
original_question="Main question?",
|
||||
sub_questions=["Sub Q1?", "Sub Q2?"],
|
||||
)
|
||||
|
||||
# With pending questions (default)
|
||||
with_pending = format_context_for_prompt(context, include_pending_questions=True)
|
||||
assert "Sub Q1?" in with_pending
|
||||
|
||||
# Without pending questions (for synthesis)
|
||||
without_pending = format_context_for_prompt(
|
||||
context, include_pending_questions=False
|
||||
)
|
||||
assert "Sub Q1?" not in without_pending
|
||||
|
||||
|
||||
def test_format_context_for_prompt_with_prior_answers():
|
||||
"""Test format_context_for_prompt includes prior_answers."""
|
||||
from haiku.rag.agents.research.dependencies import ResearchContext
|
||||
|
|
|
|||
|
|
@ -78,7 +78,6 @@ async def test_research_graph_uses_search_filter(
|
|||
state = ResearchState(
|
||||
context=ResearchContext(original_question="Tell me about animals"),
|
||||
max_iterations=1,
|
||||
confidence_threshold=0.5,
|
||||
search_filter=filter_clause,
|
||||
)
|
||||
|
||||
|
|
@ -116,7 +115,6 @@ async def test_search_filter_none_searches_all(allow_model_requests, client_with
|
|||
state = ResearchState(
|
||||
context=ResearchContext(original_question="Tell me about animals"),
|
||||
max_iterations=1,
|
||||
confidence_threshold=0.5,
|
||||
search_filter=None,
|
||||
)
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue