Docs and cli support for filter in deep QA, Research

This commit is contained in:
Yiorgis Gozadinos 2025-12-11 15:23:50 +02:00
parent 9fd33a2d83
commit ecba8cfd38
No known key found for this signature in database
4 changed files with 59 additions and 5 deletions

View file

@ -229,6 +229,20 @@ async with HaikuRAG(path_to_db) as client:
print(report.executive_summary) print(report.executive_summary)
``` ```
### Filtering Documents
Both Research and Deep QA graphs support restricting searches to specific documents via the `search_filter` parameter. Set it to a SQL WHERE clause before running:
```python
state = ResearchState.from_config(context=context, config=Config)
# Only search documents with these IDs
state.search_filter = "id IN ('doc-123', 'doc-456')"
result = await graph.run(state=state, deps=deps)
```
The filter applies to all search operations in the graph (context gathering and sub-question searches). See [Filtering Search Results](python.md#filtering-search-results) for available filter columns and syntax.
Alternative usage with custom config: Alternative usage with custom config:
```python ```python

View file

@ -149,8 +149,19 @@ Show verbose output with deep QA:
haiku-rag ask "What are the main features and architecture of haiku.rag?" --deep --verbose haiku-rag ask "What are the main features and architecture of haiku.rag?" --deep --verbose
``` ```
The QA agent will search your documents for relevant information and provide a comprehensive answer. With `--cite`, responses include citations showing which documents were used. With `--deep`, the question is decomposed into sub-questions that are answered in parallel before synthesizing a final answer. With `--verbose` (only with `--deep`), you'll see the planning, searching, evaluation, and synthesis steps as they happen. Filter to specific documents with deep QA:
When available, citations use the document title; otherwise they fall back to the URI. ```bash
haiku-rag ask "What are the main findings?" --deep --filter "uri LIKE '%paper%'"
```
The QA agent searches your documents for relevant information and provides a comprehensive answer. When available, citations use the document title; otherwise they fall back to the URI.
Flags:
- `--cite`: Include citations showing which documents were used
- `--deep`: Decompose the question into sub-questions answered in parallel before synthesizing a final answer
- `--verbose`: Show planning, searching, evaluation, and synthesis steps (only with `--deep`)
- `--filter`: Restrict searches to documents matching the filter (only with `--deep`)
## Research ## Research
@ -166,8 +177,16 @@ With verbose output to see progress:
haiku-rag research "How does haiku.rag organize and query documents?" --verbose haiku-rag research "How does haiku.rag organize and query documents?" --verbose
``` ```
Filter to specific documents:
```bash
haiku-rag research "What are the key findings?" --filter "uri LIKE '%paper%'"
```
Flags: Flags:
- `--verbose`: Show planning, searching previews, evaluation summary, and stop reason - `--verbose`: Show planning, searching previews, evaluation summary, and stop reason
- `--filter`: SQL WHERE clause to filter documents (see [Filtering Search Results](python.md#filtering-search-results))
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`, `confidence_threshold`, and `max_concurrency` are configured in your [configuration file](configuration/index.md) under the `research` section.

View file

@ -314,6 +314,7 @@ class HaikuRAGApp:
cite: bool = False, cite: bool = False,
deep: bool = False, deep: bool = False,
verbose: bool = False, verbose: bool = False,
filter: str | None = None,
): ):
"""Ask a question using the RAG system. """Ask a question using the RAG system.
@ -322,6 +323,7 @@ class HaikuRAGApp:
cite: Include citations in the answer cite: Include citations in the answer
deep: Use deep QA mode (multi-step reasoning) deep: Use deep QA mode (multi-step reasoning)
verbose: Show verbose output verbose: Show verbose output
filter: SQL WHERE clause to filter documents
""" """
async with HaikuRAG(db_path=self.db_path, config=self.config) as self.client: async with HaikuRAG(db_path=self.db_path, config=self.config) as self.client:
try: try:
@ -334,6 +336,7 @@ class HaikuRAGApp:
graph = build_deep_qa_graph(config=self.config) graph = build_deep_qa_graph(config=self.config)
context = DeepQAContext(original_question=question) context = DeepQAContext(original_question=question)
state = DeepQAState.from_config(context=context, config=self.config) state = DeepQAState.from_config(context=context, config=self.config)
state.search_filter = filter
deps = DeepQADeps(client=self.client) deps = DeepQADeps(client=self.client)
if verbose: if verbose:
@ -371,12 +374,15 @@ class HaikuRAGApp:
except Exception as e: except Exception as e:
self.console.print(f"[red]Error: {e}[/red]") self.console.print(f"[red]Error: {e}[/red]")
async def research(self, question: str, verbose: bool = False): async def research(
self, question: str, verbose: bool = False, filter: str | None = None
):
"""Run research via the pydantic-graph pipeline. """Run research via the pydantic-graph pipeline.
Args: Args:
question: The research question question: The research question
verbose: Show AG-UI event stream during execution verbose: Show AG-UI event stream during execution
filter: SQL WHERE clause to filter documents
""" """
async with HaikuRAG(db_path=self.db_path, config=self.config) as client: async with HaikuRAG(db_path=self.db_path, config=self.config) as client:
try: try:
@ -387,6 +393,7 @@ class HaikuRAGApp:
graph = build_research_graph(config=self.config) graph = build_research_graph(config=self.config)
context = ResearchContext(original_question=question) context = ResearchContext(original_question=question)
state = ResearchState.from_config(context=context, config=self.config) state = ResearchState.from_config(context=context, config=self.config)
state.search_filter = filter
deps = ResearchDeps(client=client) deps = ResearchDeps(client=client)
if verbose: if verbose:

View file

@ -305,9 +305,17 @@ def ask(
"--verbose", "--verbose",
help="Show verbose progress output (only with --deep)", help="Show verbose progress output (only with --deep)",
), ),
filter: str | None = typer.Option(
None,
"--filter",
"-f",
help="SQL WHERE clause to filter documents (only with --deep)",
),
): ):
app = create_app(db) app = create_app(db)
asyncio.run(app.ask(question=question, cite=cite, deep=deep, verbose=verbose)) asyncio.run(
app.ask(question=question, cite=cite, deep=deep, verbose=verbose, filter=filter)
)
@cli.command("research", help="Run multi-agent research and output a concise report") @cli.command("research", help="Run multi-agent research and output a concise report")
@ -325,9 +333,15 @@ def research(
"--verbose", "--verbose",
help="Show planning, searching previews, evaluation summary, and stop reason", help="Show planning, searching previews, evaluation summary, and stop reason",
), ),
filter: str | None = typer.Option(
None,
"--filter",
"-f",
help="SQL WHERE clause to filter documents (e.g., \"uri LIKE '%arxiv%'\")",
),
): ):
app = create_app(db) app = create_app(db)
asyncio.run(app.research(question=question, verbose=verbose)) asyncio.run(app.research(question=question, verbose=verbose, filter=filter))
@cli.command("settings", help="Display current configuration settings") @cli.command("settings", help="Display current configuration settings")