Update docs

This commit is contained in:
Yiorgis Gozadinos 2025-11-05 16:32:08 +02:00
parent 8c05b76056
commit fa93226a28
No known key found for this signature in database

View file

@ -26,18 +26,17 @@ Python usage:
from haiku.rag.client import HaikuRAG from haiku.rag.client import HaikuRAG
from haiku.rag.qa.agent import QuestionAnswerAgent from haiku.rag.qa.agent import QuestionAnswerAgent
client = HaikuRAG(path_to_db) async with HaikuRAG(path_to_db) as client:
# Choose a provider and model (see Configuration for env defaults)
agent = QuestionAnswerAgent(
client=client,
provider="openai", # or "ollama", "vllm", etc.
model="gpt-4o-mini",
use_citations=False, # set True to bias prompt towards citing sources
)
# Choose a provider and model (see Configuration for env defaults) answer = await agent.answer("What is climate change?")
agent = QuestionAnswerAgent( print(answer)
client=client,
provider="openai", # or "ollama", "vllm", etc.
model="gpt-4o-mini",
use_citations=False, # set True to bias prompt towards citing sources
)
answer = await agent.answer("What is climate change?")
print(answer)
``` ```
### Deep QA Agent ### Deep QA Agent
@ -49,19 +48,25 @@ Deep QA is a multi-agent system that decomposes complex questions into sub-quest
title: Deep QA graph title: Deep QA graph
--- ---
stateDiagram-v2 stateDiagram-v2
DeepQAPlanNode --> DeepQASearchDispatchNode [*] --> plan
DeepQASearchDispatchNode --> DeepQADecisionNode plan --> get_batch
DeepQADecisionNode --> DeepQASearchDispatchNode get_batch --> search_one: Has questions (map)
DeepQADecisionNode --> DeepQASynthesizeNode get_batch --> synthesize: No questions
DeepQASynthesizeNode --> [*] search_one --> collect_answers
collect_answers --> decide
decide --> get_batch: Continue QA
decide --> synthesize: Done with QA
synthesize --> [*]
``` ```
Key nodes: Key nodes:
- **Plan**: Decomposes the question into focused sub-questions - **plan**: Decomposes the question into focused sub-questions using a presearch tool
- **Search (parallel)**: Answers sub-questions in parallel (respects max_concurrency) - **get_batch**: Retrieves remaining sub-questions for the current iteration
- **Decision**: Evaluates if we have sufficient information or need another iteration - **search_one**: Answers a single sub-question using the knowledge base (mapped in parallel)
- **Synthesize**: Generates the final comprehensive answer - **collect_answers**: Aggregates search results from parallel executions
- **decide**: Evaluates if sufficient information has been gathered or if more iterations are needed
- **synthesize**: Generates the final comprehensive answer from all gathered information
Key differences from Research: Key differences from Research:
@ -71,6 +76,11 @@ Key differences from Research:
- **Supports citations**: Can include inline source citations like `[document.md]` - **Supports citations**: Can include inline source citations like `[document.md]`
- **Configurable iterations**: Control max_iterations (default: 2) and max_concurrency (default: 1) - **Configurable iterations**: Control max_iterations (default: 2) and max_concurrency (default: 1)
Note on parallel execution:
- The `search_one` node is mapped over all questions in a batch
- Parallelism is controlled via `max_concurrency` using asyncio.Semaphore
- All questions in an iteration are processed before evaluation
CLI usage: CLI usage:
```bash ```bash
@ -87,11 +97,13 @@ Python usage:
from haiku.rag.client import HaikuRAG from haiku.rag.client import HaikuRAG
from haiku.rag.qa.deep.dependencies import DeepQAContext from haiku.rag.qa.deep.dependencies import DeepQAContext
from haiku.rag.qa.deep.graph import build_deep_qa_graph from haiku.rag.qa.deep.graph import build_deep_qa_graph
from haiku.rag.qa.deep.nodes import DeepQAPlanNode
from haiku.rag.qa.deep.state import DeepQADeps, DeepQAState from haiku.rag.qa.deep.state import DeepQADeps, DeepQAState
async with HaikuRAG(path_to_db) as client: async with HaikuRAG(path_to_db) as client:
graph = build_deep_qa_graph() graph = build_deep_qa_graph(
provider="openai",
model="gpt-4o-mini"
)
context = DeepQAContext( context = DeepQAContext(
original_question="What are the main features of haiku.rag?", original_question="What are the main features of haiku.rag?",
use_citations=True use_citations=True
@ -105,13 +117,12 @@ async with HaikuRAG(path_to_db) as client:
deps = DeepQADeps(client=client) deps = DeepQADeps(client=client)
result = await graph.run( result = await graph.run(
start_node=DeepQAPlanNode(provider="openai", model="gpt-4o-mini"),
state=state, state=state,
deps=deps deps=deps
) )
print(result.output.answer) print(result.answer)
print(result.output.sources) print(result.sources)
``` ```
### Research Graph ### Research Graph
@ -123,21 +134,27 @@ The research workflow is implemented as a typed pydanticgraph. It plans, sear
title: Research graph title: Research graph
--- ---
stateDiagram-v2 stateDiagram-v2
PlanNode --> SearchDispatchNode [*] --> plan
SearchDispatchNode --> AnalyzeInsightsNode plan --> get_batch
AnalyzeInsightsNode --> DecisionNode get_batch --> search_one: Has questions (map)
DecisionNode --> SearchDispatchNode get_batch --> synthesize: No questions
DecisionNode --> SynthesizeNode search_one --> collect_answers
SynthesizeNode --> [*] collect_answers --> analyze_insights
analyze_insights --> decide
decide --> get_batch: Continue research
decide --> synthesize: Done researching
synthesize --> [*]
``` ```
Key nodes: Key nodes:
- Plan: builds up to 3 standalone subquestions (uses an internal presearch tool) - **plan**: Builds up to 3 standalone subquestions (uses an internal presearch tool)
- Search (batched): answers subquestions using the KB with minimal, verbatim context - **get_batch**: Retrieves remaining subquestions for the current iteration
- Analyze: aggregates fresh insights, updates gaps, and suggests new sub-questions - **search_one**: Answers a single subquestion using the KB with minimal, verbatim context (mapped in parallel)
- Decision: checks sufficiency/confidence thresholds and chooses whether to iterate - **collect_answers**: Aggregates search results from parallel executions
- Synthesize: generates a final structured report - **analyze_insights**: Synthesizes fresh insights, updates gaps, and suggests new sub-questions
- **decide**: Checks sufficiency/confidence thresholds and determines whether to continue research
- **synthesize**: Generates a final structured research report
Primary models: Primary models:
@ -147,6 +164,11 @@ Primary models:
- `EvaluationResult` — insights, new questions, sufficiency, confidence - `EvaluationResult` — insights, new questions, sufficiency, confidence
- `ResearchReport` — final report (title, executive summary, findings, conclusions, …) - `ResearchReport` — final report (title, executive summary, findings, conclusions, …)
Note on parallel execution:
- The `search_one` node is mapped over all questions in a batch
- Parallelism is controlled via `max_concurrency` using asyncio.Semaphore
- Analysis and decision nodes process results after each batch completes
CLI usage: CLI usage:
```bash ```bash
@ -161,16 +183,15 @@ Python usage (blocking result):
```python ```python
from haiku.rag.client import HaikuRAG from haiku.rag.client import HaikuRAG
from haiku.rag.research import ( from haiku.rag.research.dependencies import ResearchContext
PlanNode, from haiku.rag.research.graph import build_research_graph
ResearchContext, from haiku.rag.research.state import ResearchDeps, ResearchState
ResearchDeps,
ResearchState,
build_research_graph,
)
async with HaikuRAG(path_to_db) as client: async with HaikuRAG(path_to_db) as client:
graph = build_research_graph() graph = build_research_graph(
provider="openai",
model="gpt-4o-mini"
)
question = "What are the main drivers and trends of global temperature anomalies since 1990?" question = "What are the main drivers and trends of global temperature anomalies since 1990?"
state = ResearchState( state = ResearchState(
context=ResearchContext(original_question=question), context=ResearchContext(original_question=question),
@ -181,12 +202,11 @@ async with HaikuRAG(path_to_db) as client:
deps = ResearchDeps(client=client) deps = ResearchDeps(client=client)
result = await graph.run( result = await graph.run(
PlanNode(provider="openai", model="gpt-4o-mini"),
state=state, state=state,
deps=deps, deps=deps,
) )
report = result.output report = result
print(report.title) print(report.title)
print(report.executive_summary) print(report.executive_summary)
``` ```
@ -195,17 +215,16 @@ Python usage (streamed events):
```python ```python
from haiku.rag.client import HaikuRAG from haiku.rag.client import HaikuRAG
from haiku.rag.research import ( from haiku.rag.research.dependencies import ResearchContext
PlanNode, from haiku.rag.research.graph import build_research_graph
ResearchContext, from haiku.rag.research.state import ResearchDeps, ResearchState
ResearchDeps, from haiku.rag.research.stream import stream_research_graph
ResearchState,
build_research_graph,
stream_research_graph,
)
async with HaikuRAG(path_to_db) as client: async with HaikuRAG(path_to_db) as client:
graph = build_research_graph() graph = build_research_graph(
provider="openai",
model="gpt-4o-mini"
)
question = "What are the main drivers and trends of global temperature anomalies since 1990?" question = "What are the main drivers and trends of global temperature anomalies since 1990?"
state = ResearchState( state = ResearchState(
context=ResearchContext(original_question=question), context=ResearchContext(original_question=question),
@ -217,7 +236,6 @@ async with HaikuRAG(path_to_db) as client:
async for event in stream_research_graph( async for event in stream_research_graph(
graph, graph,
PlanNode(provider="openai", model="gpt-4o-mini"),
state, state,
deps, deps,
): ):